SharePreference为什么不适合存储大容量数据

匿名 (未验证) 提交于 2019-12-03 00:29:01

操作简单,以键值对的方式存储在本地。

getSharedPreference在子线程进行读取操作,为啥还会阻塞线程呢? 因为get操作要等所有键值对都读取完毕之后,才能进行操作。

看源码:

val sp = getSharedPreferences("zhen", Context.MODE_PRIVATE) val editor = sp.edit() editor.putString("key", "value") editor.commit()  val value = sp.getString("key", "null")

SharedPreferenceImpl

SharedPreferencesImpl(File file, int mode) {     mFile = file;     mBackupFile = makeBackupFile(file);     mMode = mode;     mLoaded = false;     mMap = null;     startLoadFromDisk(); }

开启子线程进行文件读取

private void startLoadFromDisk() {     synchronized (mLock) {         mLoaded = false;     }     new Thread("SharedPreferencesImpl-load") {         public void run() {             loadFromDisk();         }     }.start(); }

private void loadFromDisk() {     synchronized (mLock) {         if (mLoaded) {             return;         }         if (mBackupFile.exists()) {             mFile.delete();             mBackupFile.renameTo(mFile);         }     }      // Debugging     if (mFile.exists() && !mFile.canRead()) {         Log.w(TAG, "Attempt to read preferences file " + mFile + " without permission");     }      Map map = null;     StructStat stat = null;     try {         stat = Os.stat(mFile.getPath());         if (mFile.canRead()) {             BufferedInputStream str = null;             try {                 str = new BufferedInputStream(                         new FileInputStream(mFile), 16*1024);                 map = XmlUtils.readMapXml(str);             } catch (Exception e) {                 Log.w(TAG, "Cannot read " + mFile.getAbsolutePath(), e);             } finally {                 IoUtils.closeQuietly(str);             }         }     } catch (ErrnoException e) {         /* ignore */     }      synchronized (mLock) {         mLoaded = true;         if (map != null) {             mMap = map;             mStatTimestamp = stat.st_mtim;             mStatSize = stat.st_size;         } else {             mMap = new HashMap<>();         }         mLock.notifyAll();     } }

那为啥在子线程操作,还会阻塞UI呢?

@Nullable public String getString(String key, @Nullable String defValue) {     synchronized (mLock) {         awaitLoadedLocked();         String v = (String)mMap.get(key);         return v != null ? v : defValue;     } }
//会等待所有的都读取完毕之后,才进行get操作

private void awaitLoadedLocked() {     if (!mLoaded) {         // Raise an explicit StrictMode onReadFromDisk for this         // thread, since the real read will be in a different         // thread and otherwise ignored by StrictMode.         BlockGuard.getThreadPolicy().onReadFromDisk();     }     while (!mLoaded) {         try {             mLock.wait();         } catch (InterruptedException unused) {         }     } }

//put操作会使用SharedPreference的内部类EditorImpl, 统一commit。

public Editor putString(String key, @Nullable String value) {     synchronized (mLock) {         mModified.put(key, value);         return this;     } }
public boolean commit() {     long startTime = 0;      if (DEBUG) {         startTime = System.currentTimeMillis();     }      MemoryCommitResult mcr = commitToMemory();      SharedPreferencesImpl.this.enqueueDiskWrite(         mcr, null /* sync write on this thread okay */);     try {         mcr.writtenToDiskLatch.await();     } catch (InterruptedException e) {         return false;     } finally {         if (DEBUG) {             Log.d(TAG, mFile.getName() + ":" + mcr.memoryStateGeneration                     + " committed after " + (System.currentTimeMillis() - startTime)                     + " ms");         }     }     notifyListeners(mcr);     return mcr.writeToDiskResult; }







易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!