日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > Android >内容正文

Android

Android—数据持久化、SP源码

發布時間:2023/12/18 Android 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Android—数据持久化、SP源码 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

3種數據持久化:

  • File:openFileInput(String fileName)、openFileOutput(String fileName, int mode)

不對存儲的內容進行任何的格式化處理,比較合適存儲一些簡單的文本數據或二進制數據

  • SharedPreferences

使用鍵值對的方式來存儲數據,保存數據更加方便。數據以明文的方式保存在文件中,需要加密,一般保存應用設置。

  • SQLite 繼承SqLiteOpenHelper類創建數據庫,

可以保存大量復雜的關系型數據?

賬號密碼自動登陸:

在項目中,我們一般使用SharePrefences實現自動登錄的功能,在登錄成功后,將數據(用戶名,密碼)保存在SharePrefences中,然后再次進入app時,判斷SharePrefences中有無數據,有的話就跳到主頁面,沒有的話就跳到登錄頁。

SharedPreferences 的源碼實現:

SharedPreferences 是線程安全的。

final class SharedPreferencesImpl implements SharedPreferences {// 1、使用注釋標記鎖的順序// Lock ordering rules:// - acquire SharedPreferencesImpl.mLock before EditorImpl.mLock// - acquire mWritingToDiskLock before EditorImpl.mLock// 2、通過注解標記持有的是哪把鎖@GuardedBy("mLock")private Map<String, Object> mMap;@GuardedBy("mWritingToDiskLock")private long mDiskStateGeneration;public final class EditorImpl implements Editor {@GuardedBy("mEditorLock")private final Map<String, Object> mModified = new HashMap<>();} }

SharedPreferences 是由 Context 返回的,獲取 SharedPreferences 的方法定義在抽象類 Context 中。

public abstract SharedPreferences getSharedPreferences(String name, int mode);public abstract SharedPreferences getSharedPreferences(File file, int mode);

第一個方法是我們常用的,只要傳入文件名,SP會自動尋找已有文件或創建,第二個是我們傳入的文件。

所以 SharedPreferences 的操作,本質上就是對文件的操作,使用SharedPreferences時,只有第一次讀取數據是有概率卡主線程幾十到幾百毫秒,而之后的讀取時間幾乎可以忽略不計。最后會落實到一個 xml 文件上。

@Overridepublic File getSharedPreferencesPath(String name) {return makeFilename(getPreferencesDir(), name + ".xml");}

標準路徑在 /data/data/應用包名/shared_prefs 文件夾中,且都是 xml 文件。

commit 和 apply 的對比

EditorImpl 內部有一個內存緩存,用來保存用戶修改后的操作:

private final Map<String, Object> mModified = Maps.newHashMap();

在執行 commit 或者 apply 前,比如editor.putString("Key","Value")會把修改存儲在 mModified 中。

public Editor putString(String key, @Nullable String value) {synchronized (this) {mModified.put(key, value);return this;}}}

commit(同步):構造一個MemoryCommitResult來進行結果投遞,在post任務以后會直接在當前線程進行wait。

apply(異步):構造一個MemoryCommitResult來調度IO(QueuedWork提供了singleThreadExecutor),apply()不會等待,而由QueuedWork的waitToFinish()方法的調用者(ActivityThread)來保證在某些時間點等待task的完成。

QueuedWork.singleThreadExecutor().execute(writeToDiskRunnable);

QueuedWork:一個內部工具類,用于跟蹤那些未完成的或尚未結束的全局任務。由?waitToFinish?方法保證執行,在?Activity onStop 以及 Service 處理 onStop,onStartCommand 時等待寫入操作,所有排隊的異步任務都在一個獨立、專用的線程上處理。平時使用的時候,盡量使用 apply 避免卡住主線程。

apply方法造成的ANR:

在apply()方法中,首先會創建一個等待鎖,最終更新文件的任務會交給QueuedWork.singleThreadExecutor()單個線程或者HandlerThread去執行,當文件更新完畢后會釋放鎖。 但當Activity.onStop()以及Service處理onStop等相關方法時,則會執行 QueuedWork.waitToFinish()等待所有的等待鎖釋放,因此如果SharedPreferences一直沒有完成更新任務,有可能會導致卡在主線程,最終超時導致ANR。

加載 xml 數據文件

?SharedPreferences 的加載流程,就是把文件的內容載入內存的過程。

private void loadFromDisk() {...str = new BufferedInputStream(new FileInputStream(mFile), 16*1024);map = XmlUtils.readMapXml(str);...}

本質上,就是讀取一個 xml 文件,被內容解析為 Map 對象。這個 map 包含了我們之前保存的所有鍵值對的數據。?

SharedPreferences 的讀取非常快,載入完成后,后面的讀操作都是針對 mMap 的,響應速度是內存級別的非常快。

SharedPreferences 不存放大量數據原因:

  • apply操作耗時過久會導致ANR
  • 如果數據量很大的話,返回的map對象會占很大一塊內存

總結

以上是生活随笔為你收集整理的Android—数据持久化、SP源码的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。