TShopping

 找回密碼
 註冊
搜索
查看: 2446|回復: 2
打印 上一主題 下一主題

[教學] Android 讀取SD卡SQLite文件

[複製鏈接]
跳轉到指定樓層
1#
發表於 2013-11-6 00:38:39 | 只看該作者 |只看大圖 回帖獎勵 |倒序瀏覽 |閱讀模式
 
Push to Facebook
      開始模擬的場景是這樣的==  連後台取大JSON串,解析-轉成相應對像-存入數據庫; 由於後台暫時沒有數據,所以只能自己模擬測試數據; 那麼我的策略是這樣的: 連續new出來目標數據的對象數放置到一個list中,然後再將這個list異步插入到數據庫中;看似沒有問題, 但是一直以來我都忽略了一個非常重要的問題,大數據! 萬一有300W條記錄呢? 你要new300W個對象嗎? 開玩笑······· 所以這幾天難為我的小米2了,一直認為它不給力, 不到100W就內存溢出·· 現在想起來, 其實已經很夠給力的了;這300W個對象的內存佔用可不是鬧著玩的··········· 所以我只能換種思路;
        1. 我不通過new對象的形式向數據庫中插入對象,反正我最終要的是模擬數據, 我直接用db.exel();循環向裡面插入數據不也是一樣的嗎? 這樣一來那300W個對象不就可以不用創建了嗎? 為什麼自己沒早些考慮這方面的問題、 經驗教訓吶
        2. 今天去咨詢了兄弟開發IOS那邊, 給了我幾個比較有參考性的意見:
            可以將每次提交的記錄數減少==少量多次, 將300W條記錄每1000條記錄提交一次; 那麼就可以緩解寫入的數據庫壓力;
            看看模擬的對象佔用的內存是否已經將棧空間填滿, 其實我考慮到運行時內存這個概念了,但是水平不夠,沒能往下思考;
            在線解析JSON大字符串這個策略是不科學的,一方面耗時,其二萬一中途網絡中斷,要考慮到斷點續傳?所以只能剩下其中2中方式可行:1,第一次安裝的時候就先帶一個數據庫文件放置SD卡上,用程序讀這個SD卡內容;或者在線下載一個壓縮包,本地解壓,然後在讀;2,當後續有增量數據產生時,如果數據量小,可以採用在線解析JSON然後添加到數據庫中; 如果數據量較大,考慮分批獲取數據=少量多次請求數據; 如果間隔時間的確較長,參考後台給的數據壓縮規則, 實在不行就重新獲取新數據包,覆蓋之前的數據;
        3. 考慮了下, 我還是要模擬下從程序中讀取sd卡中的數據庫文件比較靠譜;用可視化工具做了個簡單的數據庫文件, 然後copy到SD卡中,開始模擬讀取;
         按照慣例, 先爆幾張過程圖看看流程==通過SQLite Developer可視化工具生成DB文件:
   
   
數據庫文件已經拷貝到SD卡根目錄下===

運行效果== 此處我只是做了查詢處理,添加功能暫時未做,可根據上圖結構自行添加:
      
       說說以下測試程序的構成:
     1. 傻瓜式佈局;
     2.從外界獲取的數據庫文件存放至SD卡的根目錄;
     3.manifest文件添加讀寫權限;
     4.寫一個openHelper數據庫操作幫助類;
     5.按照數據庫表結構建立相應的實體類(entity  or   bean);
     6.activity的數據展現;
【佈局】
  1. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  2. xmlns:tools="http://schemas.android.com/tools"
  3. android:layout_width="match_parent"
  4. android:layout_height="match_parent"
  5. android:orientation="vertical">

  6. <EditText android:id="@+id/input"
  7. android:layout_width="match_parent"
  8. android:layout_height="wrap_content"
  9. android:hint="请输入要插入的数据"/>
  10. <EditText android:id="@+id/input_detail"
  11. android:layout_width="match_parent"
  12. android:layout_height="wrap_content"
  13. android:hint="输入数据的详细信息"/>

  14. <Button android:id="@+id/addBtn"
  15. android:layout_width="match_parent"
  16. android:layout_height="wrap_content"
  17. android:text="点击添加"/>

  18. <EditText android:id="@+id/showContext"
  19. android:layout_width="match_parent"
  20. android:layout_height="wrap_content"
  21. android:hint="显示查询数据"/>
  22. <Button android:id="@+id/searchBtn"
  23. android:layout_width="match_parent"
  24. android:layout_height="wrap_content"
  25. android:text="点击查询"/>

  26. <TextView
  27. android:id="@+id/show_textview"
  28. android:layout_width="match_parent"
  29. android:layout_height="wrap_content"
  30. android:text="TextView" />

  31. </LinearLayout>
複製代碼

【權限】


  1. <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission>
複製代碼


【openHelper幫助類】
  1. package com.example.test_sqlite;

  2. import java.io.File;
  3. import java.util.ArrayList;
  4. import java.util.List;
  5. import com.example.test_sqlite.entity.MainData;
  6. import android.content.Context;
  7. import android.database.Cursor;
  8. import android.database.sqlite.SQLiteDatabase;
  9. import android.database.sqlite.SQLiteOpenHelper;

  10. public class MyDBHelper extends SQLiteOpenHelper{
  11. //数据库文件在SD卡中,此时必须用全限定名!! 默认路径在/data/data/databases/testDBinSD.sqlite, 但私密数据外界看不到-除非root。
  12. private static final String SQL_NAME = "/sdcard/testDBinSD.sqlite";//数据库名称。//Environment.getExternalStorageDirectory().getPath() + "testDBinSD.sqlite";//
  13. private static final String MAIN_DATA_TABLE_NAME = "maindata";//表名。
  14. private static final String MAIN_DATA_ID = "id";//表的4个字段
  15. private static final String MAIN_DATA_NAME = "name";
  16. private static final String MAIN_DATA_SEX = "sex";
  17. private static final String MAIN_DATA_GRADE = "grade";

  18. //构造方法
  19. public MyDBHelper(Context context) {
  20. super(context, SQL_NAME, null, 1);
  21. }

  22. @Override
  23. public void onCreate(SQLiteDatabase db) {
  24. //建表
  25. String mainDataSQL = "create table if not exists " + MAIN_DATA_TABLE_NAME + "("
  26. + MAIN_DATA_ID + " varchar(20), "
  27. + MAIN_DATA_NAME + " varchar(20), "
  28. + MAIN_DATA_SEX + " varchar(20), "
  29. + MAIN_DATA_GRADE + " varchar(20));";
  30. db.execSQL(mainDataSQL);
  31. }

  32. //读文件获取记录。
  33. public List<MainData> getMainData() {
  34. String mainDataSQL = "select * from "+MAIN_DATA_TABLE_NAME+"";
  35. File name = new File(SQL_NAME);
  36. SQLiteDatabase db = SQLiteDatabase.openOrCreateDatabase(name, null);//读SD卡数据库必须如此--用静态方法打开数据库。
  37. Cursor cursor = db.rawQuery(mainDataSQL, null);
  38. List<MainData> dataList = new ArrayList<MainData>();
  39. if (cursor != null) {
  40. while (cursor.moveToNext()) {//直到返回false说明表中到了数据末尾
  41. MainData data = new MainData();
  42. data.setId(cursor.getString(0));
  43. data.setName(cursor.getString(1));
  44. data.setSex(cursor.getString(2));
  45. data.setGrade(cursor.getString(3));
  46. dataList.add(data);
  47. }
  48. }
  49. cursor.close();
  50. db.close();

  51. return dataList;
  52. }

  53. @Override
  54. public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {

  55. }

  56. }
複製代碼



【實體類】
  1. package com.example.test_sqlite.entity;

  2. public class MainData {

  3. private String id;
  4. private String name;
  5. private String sex;
  6. private String grade;
  7. public String getId() {
  8. return id;
  9. }
  10. public void setId(String id) {
  11. this.id = id;
  12. }
  13. public String getName() {
  14. return name;
  15. }
  16. public void setName(String name) {
  17. this.name = name;
  18. }
  19. public String getSex() {
  20. return sex;
  21. }
  22. public void setSex(String sex) {
  23. this.sex = sex;
  24. }
  25. public String getGrade() {
  26. return grade;
  27. }
  28. public void setGrade(String grade) {
  29. this.grade = grade;
  30. }
  31. }
複製代碼




【activity數據查詢-展現】
  1. package com.example.test_sqlite;

  2. import java.util.List;
  3. import com.example.test_sqlite.entity.MainData;
  4. import android.os.Bundle;
  5. import android.view.View;
  6. import android.view.View.OnClickListener;
  7. import android.widget.Button;
  8. import android.widget.EditText;
  9. import android.widget.TextView;
  10. import android.app.Activity;

  11. public class MainActivity extends Activity implements OnClickListener {

  12. private MyDBHelper dbHelper;//SQLite帮助类

  13. private EditText input;
  14. private EditText inputDetail;
  15. private Button addBtn;
  16. private EditText showContent;
  17. //最主要功能是下面的俩=== 点击查询--数据呈现。
  18. private Button searchBtn;
  19. private TextView showText;

  20. @Override
  21. protected void onCreate(Bundle savedInstanceState) {
  22. super.onCreate(savedInstanceState);
  23. setContentView(R.layout.activity_main);
  24. dbHelper = new MyDBHelper(this);
  25. dbHelper.getWritableDatabase();  //第一次執行要建MAINDATA TABLE

  26. input = (EditText) findViewById(R.id.input);
  27. inputDetail = (EditText) findViewById(R.id.input_detail);
  28. addBtn = (Button) findViewById(R.id.addBtn);
  29. showContent = (EditText) findViewById(R.id.showContext);
  30. searchBtn = (Button) findViewById(R.id.searchBtn);
  31. showText = (TextView) findViewById(R.id.show_textview);

  32. addBtn.setOnClickListener(this);
  33. searchBtn.setOnClickListener(this);
  34. }

  35. @Override
  36. public void onClick(View v) {
  37. if(v.getId() == R.id.addBtn) {
  38. // handleInsertDB();
  39. } else if(v.getId() == R.id.searchBtn) {
  40. handleSearchDB();
  41. }
  42. }

  43. private void handleSearchDB() {
  44. //查询sql。返回记录集合。
  45. List<MainData> dataList = dbHelper.getMainData();
  46. StringBuilder sb = new StringBuilder();
  47. for(MainData data : dataList) {
  48. sb.append(data.getId()).append("-").//循环将记录拼接起来方便显示。
  49. append(data.getName()).append("-").append(data.getSex()).
  50. append("-").append(data.getGrade()).append("-\n").toString();
  51. }
  52. showText.setText(sb);//显示结果。
  53. }

  54. private void handleInsertDB() {

  55. }
  56. }
複製代碼




       說明從SD卡中讀取SQLite文件是可以實現的============

 

臉書網友討論
2#
發表於 2013-11-6 00:44:21 | 只看該作者
牛X海海!!!

版主招募中

3#
發表於 2013-11-6 14:53:30 | 只看該作者
感謝大大分享~~雖然有點複雜~看不懂


*滑块验证:
您需要登錄後才可以回帖 登錄 | 註冊 |

本版積分規則



Archiver|手機版|小黑屋|免責聲明|TShopping

GMT+8, 2024-4-27 09:01 , Processed in 0.059474 second(s), 25 queries .

本論壇言論純屬發表者個人意見,與 TShopping綜合論壇 立場無關 如有意見侵犯了您的權益 請寫信聯絡我們。

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回復 返回頂部 返回列表