開始模擬的場景是這樣的== 連後台取大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的數據展現; 【佈局】
- <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:tools="http://schemas.android.com/tools"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:orientation="vertical">
- <EditText android:id="@+id/input"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:hint="请输入要插入的数据"/>
- <EditText android:id="@+id/input_detail"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:hint="输入数据的详细信息"/>
- <Button android:id="@+id/addBtn"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:text="点击添加"/>
- <EditText android:id="@+id/showContext"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:hint="显示查询数据"/>
- <Button android:id="@+id/searchBtn"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:text="点击查询"/>
- <TextView
- android:id="@+id/show_textview"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:text="TextView" />
- </LinearLayout>
復制代碼 【權限】
- <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission>
復制代碼
【openHelper幫助類】
- package com.example.test_sqlite;
- import java.io.File;
- import java.util.ArrayList;
- import java.util.List;
- import com.example.test_sqlite.entity.MainData;
- import android.content.Context;
- import android.database.Cursor;
- import android.database.sqlite.SQLiteDatabase;
- import android.database.sqlite.SQLiteOpenHelper;
- public class MyDBHelper extends SQLiteOpenHelper{
- //数据库文件在SD卡中,此时必须用全限定名!! 默认路径在/data/data/databases/testDBinSD.sqlite, 但私密数据外界看不到-除非root。
- private static final String SQL_NAME = "/sdcard/testDBinSD.sqlite";//数据库名称。//Environment.getExternalStorageDirectory().getPath() + "testDBinSD.sqlite";//
- private static final String MAIN_DATA_TABLE_NAME = "maindata";//表名。
- private static final String MAIN_DATA_ID = "id";//表的4个字段
- private static final String MAIN_DATA_NAME = "name";
- private static final String MAIN_DATA_SEX = "sex";
- private static final String MAIN_DATA_GRADE = "grade";
- //构造方法
- public MyDBHelper(Context context) {
- super(context, SQL_NAME, null, 1);
- }
- @Override
- public void onCreate(SQLiteDatabase db) {
- //建表
- String mainDataSQL = "create table if not exists " + MAIN_DATA_TABLE_NAME + "("
- + MAIN_DATA_ID + " varchar(20), "
- + MAIN_DATA_NAME + " varchar(20), "
- + MAIN_DATA_SEX + " varchar(20), "
- + MAIN_DATA_GRADE + " varchar(20));";
- db.execSQL(mainDataSQL);
- }
- //读文件获取记录。
- public List<MainData> getMainData() {
- String mainDataSQL = "select * from "+MAIN_DATA_TABLE_NAME+"";
- File name = new File(SQL_NAME);
- SQLiteDatabase db = SQLiteDatabase.openOrCreateDatabase(name, null);//读SD卡数据库必须如此--用静态方法打开数据库。
- Cursor cursor = db.rawQuery(mainDataSQL, null);
- List<MainData> dataList = new ArrayList<MainData>();
- if (cursor != null) {
- while (cursor.moveToNext()) {//直到返回false说明表中到了数据末尾
- MainData data = new MainData();
- data.setId(cursor.getString(0));
- data.setName(cursor.getString(1));
- data.setSex(cursor.getString(2));
- data.setGrade(cursor.getString(3));
- dataList.add(data);
- }
- }
- cursor.close();
- db.close();
- return dataList;
- }
- @Override
- public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
- }
- }
復制代碼
【實體類】
- package com.example.test_sqlite.entity;
- public class MainData {
- private String id;
- private String name;
- private String sex;
- private String grade;
- public String getId() {
- return id;
- }
- public void setId(String id) {
- this.id = id;
- }
- public String getName() {
- return name;
- }
- public void setName(String name) {
- this.name = name;
- }
- public String getSex() {
- return sex;
- }
- public void setSex(String sex) {
- this.sex = sex;
- }
- public String getGrade() {
- return grade;
- }
- public void setGrade(String grade) {
- this.grade = grade;
- }
- }
復制代碼
【activity數據查詢-展現】
- package com.example.test_sqlite;
- import java.util.List;
- import com.example.test_sqlite.entity.MainData;
- import android.os.Bundle;
- import android.view.View;
- import android.view.View.OnClickListener;
- import android.widget.Button;
- import android.widget.EditText;
- import android.widget.TextView;
- import android.app.Activity;
- public class MainActivity extends Activity implements OnClickListener {
- private MyDBHelper dbHelper;//SQLite帮助类
- private EditText input;
- private EditText inputDetail;
- private Button addBtn;
- private EditText showContent;
- //最主要功能是下面的俩=== 点击查询--数据呈现。
- private Button searchBtn;
- private TextView showText;
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
- dbHelper = new MyDBHelper(this);
- input = (EditText) findViewById(R.id.input);
- inputDetail = (EditText) findViewById(R.id.input_detail);
- addBtn = (Button) findViewById(R.id.addBtn);
- showContent = (EditText) findViewById(R.id.showContext);
- searchBtn = (Button) findViewById(R.id.searchBtn);
- showText = (TextView) findViewById(R.id.show_textview);
- addBtn.setOnClickListener(this);
- searchBtn.setOnClickListener(this);
- }
- @Override
- public void onClick(View v) {
- if(v.getId() == R.id.addBtn) {
- // handleInsertDB();
- } else if(v.getId() == R.id.searchBtn) {
- handleSearchDB();
- }
- }
- private void handleSearchDB() {
- //查询sql。返回记录集合。
- List<MainData> dataList = dbHelper.getMainData();
- StringBuilder sb = new StringBuilder();
- for(MainData data : dataList) {
- sb.append(data.getId()).append("-").//循环将记录拼接起来方便显示。
- append(data.getName()).append("-").append(data.getSex()).
- append("-").append(data.getGrade()).append("-\n").toString();
- }
- showText.setText(sb);//显示结果。
- }
- private void handleInsertDB() {
- }
- }
復制代碼
說明從SD卡中讀取SQLite文件是可以實現的============
|