Android性能优化方案之数据库缓存

143 阅读2分钟

可以考虑在用户首次安装app的时候,进行数据库文件的加载。这样可以减少网络请求的时间。

1.定义自己的SQLiteOpenHelper:

public class MyDataBaseHelper extends SQLiteOpenHelper {


    public MyDataBaseHelper(@Nullable Context context, @Nullable String name, @Nullable SQLiteDatabase.CursorFactory factory, int version) {
        super(context, name, factory, version);
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        String createStudentTableSql = "create table student(_id integer primary key,name varchar(255),age integer)";
        db.execSQL(createStudentTableSql);
    }

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

    }
}

2.定义自己的DBManger,用来加载数据库文件:

public class DBManager {
    private static final String TAG = "DBManager";

    private final int BUFFER_SIZE = 400000;
    public static final String DB_NAME = "test.db";//保存的数据库文件名
    public static final String PACKAGE_NAME = "com.mobile.db";
    public static final String DB_PATH = "/data/data/"
            + PACKAGE_NAME + "/"
            + "databases"; //在手机里存放数据库的位置

    private SQLiteDatabase database;
    private Context context;

    public DBManager(Context context) {
        this.context = context;
    }

    public SQLiteDatabase getDatabase() {
        return database;
    }

    public void openDatabase() {
        this.database = this.openDatabase(DB_PATH + "/" + DB_NAME);
    }

    private SQLiteDatabase openDatabase(String dbfile) {
        try {

            File originalFile = context.getDatabasePath(DB_NAME);
            Log.d(TAG, "openDatabase path: "+originalFile.getAbsolutePath());
            if (!originalFile.exists()) {
                Log.d(TAG, "openDatabase,进入了: ");
                //判断数据库文件是否存在,若不存在则执行导入,否则直接打开数据库
                InputStream is = this.context.getResources().getAssets().open("test.db");
                FileOutputStream fos = null;
                try {
                    fos = new FileOutputStream(dbfile);
                    Log.d(TAG, "openDatabase,dbfile: "+dbfile);
                } catch (FileNotFoundException e) {
                    e.printStackTrace();
                    Log.d(TAG, "openDatabase: FileNotFoundException");
                }
                byte[] buffer = new byte[BUFFER_SIZE];
                int count = 0;
                while ((count = is.read(buffer)) > 0) {
                    fos.write(buffer, 0, count);
                }
                fos.close();
                is.close();
            }
            SQLiteDatabase db = SQLiteDatabase.openOrCreateDatabase(dbfile, null);
            return db;
        } catch (Exception e) {
            Log.e("Database", "File not found");
            e.printStackTrace();
        }
        return null;
    }
}

3.也可以打包数据库中的某个表为cvs文件或者json文件,加载文件,插入到数据库中。

private static final String TABLE_NAME = "student";
private static final String FIRST_COLUMN = "name";
private static final String SECOND_COLUMN = "age";
button.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        startAccessJsonData();
        Cursor cursor = null;
        String sql = "SELECT * FROM " + TABLE_NAME;
        cursor = database.rawQuery(sql,null);
        while (cursor.moveToNext()) {
            String name = cursor.getString(cursor.getColumnIndex("name"));
            int age = cursor.getInt(cursor.getColumnIndex("age"));
            Log.d(TAG, "onClick: name:"+name + " age:"+age);
        }
    }
});


private void startAccessJsonData() {
    new Thread() {
        @Override
        public void run() {
            long startTime = SystemClock.uptimeMillis();
            Log.d(TAG, "run start time: " + startTime);
            SQLiteDatabase db = getDatabase();
            InputStream open = null;
            InputStreamReader inputStreamReader = null;
            BufferedReader bufferedReader = null;
            StudentBean studentBean = null;
            //开启一个子线程进行assets目录下的json文件的读取,然后插入数据库,然后刷新页面
            try {
                open = getInputStreamFromAssets("department_eapp.json");
                inputStreamReader = new InputStreamReader(open);
                bufferedReader = new BufferedReader(inputStreamReader);
                StringBuilder stringBuilder = new StringBuilder();
                String lineString;
                ArrayList<String> lists = new ArrayList<>();
                while ((lineString = bufferedReader.readLine()) != null) {
                    stringBuilder.append(lineString).append("\n");
                    Log.d(TAG, "run: " + lineString + "\n");
                }
                Gson gson = new Gson();
                String jsonString = stringBuilder.toString();
                studentBean = gson.fromJson(jsonString, StudentBean.class);
                Log.d(TAG, "run: stringBuilder.length:" + studentBean.record.size());
                bufferedReader.close();
                long endTime = SystemClock.uptimeMillis();
                long dTime = endTime - startTime;
                Log.d(TAG, "run time: " + dTime);
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                try {
                    if (bufferedReader != null && inputStreamReader != null && open != null)
                        bufferedReader.close();
                    inputStreamReader.close();
                    open.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            Log.d(TAG, "run: 开始入库");
            long insertStartTime = SystemClock.uptimeMillis();
            //进行数据入库操作
            String sql = "INSERT INTO " + TABLE_NAME + "(" + FIRST_COLUMN + "," + SECOND_COLUMN + ")values(?,?)";
            SQLiteStatement sqLiteStatement = db.compileStatement(sql);
            db.beginTransaction();
            for (int i = 0; i < studentBean.record.size(); i++) {
                //SQL语句的方式
                Log.d(TAG, "run: 执行" + i + "次了");
                String dept_name = studentBean.record.get(i).dept_name;
                int dept_count_emp = studentBean.record.get(i).dept_count_emp;
                sqLiteStatement.bindString(1, dept_name);
                sqLiteStatement.bindLong(2, dept_count_emp);
                sqLiteStatement.executeInsert();
            }
            db.setTransactionSuccessful();
            db.endTransaction();
            long insertEndTime = SystemClock.uptimeMillis();
            long time = insertEndTime - insertStartTime;
            Log.d(TAG, "run: 入库完成:" + time);
        }
    }.start();
    Log.d(TAG, "startAccessJsonData: ");
}


private void startAccessCVSData() {
    new Thread() {
        @Override
        public void run() {
            long startTime = SystemClock.uptimeMillis();
            Log.d(TAG, "run start time: " + startTime);
            SQLiteDatabase db = getDatabase();
            InputStream open = null;
            InputStreamReader inputStreamReader = null;
            BufferedReader bufferedReader = null;
            //开启一个子线程进行assets目录下的cvs文件的读取,然后插入数据库,然后刷新页面
            try {
                open = getInputStreamFromAssets("department_eapp.csv");
                inputStreamReader = new InputStreamReader(open);
                bufferedReader = new BufferedReader(inputStreamReader);
                StringBuilder stringBuilder = new StringBuilder();
                String lineString;
                ArrayList<String> lists = new ArrayList<>();
                while ((lineString = bufferedReader.readLine()) != null) {
                    stringBuilder.append(lineString).append("\n");
                    Log.d(TAG, "run: " + lineString + "\n");
                    //读出一行数据,按照"|"进行字段的拆分
                    StringTokenizer st = new StringTokenizer(lineString, "|");
                    while (st.hasMoreTokens()) {
                        String str = st.nextToken();
                        Log.d(TAG, "run: 字段值:" + str);
                        lists.add(str);
                    }
                }
                Log.d(TAG, "run: stringBuilder.length:" + stringBuilder.length());
                bufferedReader.close();
                long endTime = SystemClock.uptimeMillis();
                long dTime = endTime - startTime;
                Log.d(TAG, "run time: " + dTime);
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                try {
                    if (bufferedReader != null && inputStreamReader != null && open != null)
                        bufferedReader.close();
                    inputStreamReader.close();
                    open.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }

            }
        }
    }.start();
    Log.d(TAG, "startAccessCVSData: ");


}

private InputStream getInputStreamFromAssets(String fileName) throws IOException {
    InputStream open = getResources().getAssets().open(fileName);
    return open;
}

上面的核心逻辑,已验证。