Android基础篇 Android 数据存储与性能
文章目錄
- 前言
- 有關Android存儲
- SharedPreferences 共享首選項
- 靜態變量存儲方式
- 到底使用哪一種存儲方式?
- 文件存儲方式(實戰工具類)
- 數據庫存儲方式(實戰工具類)
前言
最近到了一家公司,跟一個同事做項目,比如常規的一些操作用SharedPreferences就很好搞定,他跟我說SharedPreferences 會影響性能說了一堆… 難道別的存儲方式就不耗費性能嗎?不消耗內存嗎?
有關Android存儲
Android中的數據存儲方案主要有:共享首選項(SharedPreferences)、內部存儲(Internal Storage)、外部存儲(External Storage)、SQLite數據庫、 網絡存儲 靜態變量等
SharedPreferences 共享首選項
先說一下SharedPreferences 簡稱SP , SharedPreferences類提供了一個通用框架,使開發者能夠以鍵值對的方式,永久性的保存一些原始數據類型的數據,包括:布爾值,浮點值,整型值,長整型和字符串,被保存的數據可以跨多個用戶會話永久保留(即使應用已經終止)。
為什么使用 SP 它的優點是什么? 使用SP 為Android開發者提供了更為便利的存儲方式,但是相對的他也是有一些缺點的。
當我們首次創建 SharedPreferences 對象時,會根據文件名將文件下內容一次性加載到 mMap(SharedPreferencesImpl 成員) 容器中,每當我們 edit 都會創建一個新的 EditorImpl 對象,當修改或者添加數據時會將數據添加到 mModifiled (EditorImpl 成員)容器中,然后 commit 或 apply 操作比較 mMap 與 mModifiled 數據修正 mMap 中最后一次提交數據,然后寫入到文件中。而 get 直接從 mMap 中讀取。試想如果此時你存儲了一些大型 key 或 value 它們會一直存儲在內存中得不到釋放。
(1) 不要存放大的 key 和 value 在 SharedPreferences 中,否則會一直存儲在內存中得不到釋放,內存使用過高會頻發引發GC,導致界面丟幀甚至ANR (2) 不相關的配置選項最好不要放在一起,單個文件越大讀取速度則越慢。 (3) 讀取頻繁的 key 和不頻繁的 key 盡量不要放在一起(如果整個文件本身就較小則忽略,為了這點性能添加維護得不償失)。 (4) 盡量不要存放 JSON 和 HTML,這種可以直接文件緩存。Json/HTML 文件較小忽略不計! (5) 不要指望這貨能夠跨進程通信 Context.PROCESS
靜態變量存儲方式
因為這種方式我與我一個同事有了一些意見不一的地方,他喜歡使用靜態變量。現在的開發是針對于設備開發,而并非手機app的開發,如果app開發他的那種搞法非得出現問題不可。 因為Activity初始化的靜態變量也會被置空,因此它的生命周期是不穩定的。也就是說,在Android中靜態變量可能隨時被系統置空,變為null,其它地方在使用的時候就會產生空指針現象
在Android開發中不提倡過多使用static類型的變量(除了 static final)因為靜態變量生命周期較長,而且不易被系統回收,因此如果不能合理地使用靜態變量,就會適得其反,造成大量的內存浪費,所謂過猶不及。 經過我的多方查證 建議在具備下列全部條件的情況下,盡量使用靜態變量: (1) 變量所包含的對象體積較大,占用內存較多。 (2) 變量所包含的對象生命周期較長。 (3) 變量所包含的對象數據穩定。 (4) 該類的對象實例有對該變量所包含的對象的共享需求。 如果變量不具備上述特點建議你不要輕易地使用靜態變量,以免弄巧成拙。 對于全局變量使用Android提供了 Application 其生命周期與應用程序共存亡。所以對于全局變量可以寫在 Application。
到底使用哪一種存儲方式?
(1) 如果是簡單的數據結構,首選 SharedPreferences (2) 如果是數據量大處理復雜的話,首選是sql數據庫 對于結構化的數據,一定要使用數據庫,雖然會顯得比較麻煩,但是后續的使用中會獲益無窮 (3) 普通文件就是指文本文件,二進制文件,多媒體文件,還有頻繁的讀取要是用二進制文件。 (4) 使用網絡存儲時要避免傳輸大數據量數據,應注意對網絡傳輸方式的優化(減少請求次數等)。
文件存儲方式(實戰工具類)
文件存儲方式工具類
數據庫存儲方式(實戰工具類)
數據庫最近學會的是一個DAO 簡直愛死這個了,處理數據庫數據是真的輕松。
示例:
public class DbController {/*** Helper*/private DaoMaster.DevOpenHelper mHelper;/*** 數據庫*/private SQLiteDatabase db;/*** DaoMaster*/private DaoMaster mDaoMaster;/*** DaoSession*/private DaoSession mDaoSession;/*** 上下文*/private Context context;private static DbController mDbController;/*** dao*/private StudentsDao studentsDao;/*** 獲取單例*/public static DbController getInstance(Context context) {if (mDbController == null) {synchronized (DbController.class) {if (mDbController == null) {mDbController = new DbController(context);}}}return mDbController;}/*** 初始化** @param context*/public DbController(Context context) {this.context = context;mHelper = new DaoMaster.DevOpenHelper(context, "person.db", null);mDaoMaster = new DaoMaster(getWritableDatabase());mDaoSession = mDaoMaster.newSession();studentsDao = mDaoSession.getStudentsDao();// diningRoomDao = mDaoSession.getDiningRoomDao();}/*** 獲取可寫數據庫** @return*/private SQLiteDatabase getWritableDatabase() {if (mHelper == null) {mHelper = new DaoMaster.DevOpenHelper(context, "person.db", null);}SQLiteDatabase db = mHelper.getWritableDatabase();return db;}public boolean execSQL(String sql) {if (db == null) {db = getWritableDatabase();}try {db.execSQL(sql);return true;} catch (SQLException s) {Log.e("SQLException", s.getMessage());return false;}}/*** 插入學生數據** @param*/public void insertStudents(Students studentsData) {studentsDao.insertOrReplace(studentsData);}/*** 批量插入學生數據*/public void saveStudentLists(final List<StudentBean> list) {if (list == null || list.isEmpty()) {return;}studentsDao.getSession().runInTx(new Runnable() {@Overridepublic void run() {for (int i = 0; i < list.size(); i++) {Students studentsData = new Students();studentsData.setLast_change_id(list.get(i).getLast_change_id());studentsData.setClass_name(list.get(i).getClass_name());studentsDao.insertOrReplace(studentsData);}}});}/*** 修改學生信息** @param studentsData 學生信息*/public void upDateStudents(Students studentsData) {studentsDao.update(studentsData);}/*** 查詢所有學生數據*/public List<Students> searchAllStudents() {List<Students> list = studentsDao.queryBuilder().list();return list;}/*** 按條件查詢數據學生信息*/public Students searchStudentsByID(int user_id) {Students studentsData = studentsDao.queryBuilder().where(StudentsDao.Properties.Id.eq(user_id)).build().unique();return studentsData;}/*** 按條件查詢卡號*/public Students searchStudentsByCard(String card) {Students studentsData = studentsDao.queryBuilder().where(StudentsDao.Properties.Real_number.eq(card)).build().unique();return studentsData;}/*** 刪除學生數據*/public void delete(String userId) {studentsDao.queryBuilder().where(StudentsDao.Properties.Id.eq(userId)).buildDelete().executeDeleteWithoutDetachingEntities();}/*** 清理所有學生數據*/public void deleteStudentData() {studentsDao.deleteAll();}}每天進步一點點。。。
總結
以上是生活随笔為你收集整理的Android基础篇 Android 数据存储与性能的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【10】python 读写word文档
- 下一篇: android sina oauth2.