多多色-多人伦交性欧美在线观看-多人伦精品一区二区三区视频-多色视频-免费黄色视屏网站-免费黄色在线

國內最全IT社區平臺 聯系我們 | 收藏本站
阿里云優惠2
您當前位置:首頁 > php開源 > 綜合技術 > Fresco源碼解析 - DataSource怎樣存儲數據

Fresco源碼解析 - DataSource怎樣存儲數據

來源:程序員人生   發布時間:2015-05-26 08:32:42 閱讀次數:3587次

datasource是1個獨立的 package,與FB導入的guava包都在同1個工程內 - fbcore

fbcore的工程結構

datasource的類關系比較簡單,1張類圖基本就能夠描寫清楚它們間的關系。

datasource uml diagram


DataSource 是1個 interface, 功能與JDK中的Future類似,但是相比于Future,它的先進的地方則在于 不單單只生產1個單1的結果,而是能夠提供系列結果

Unlike Futures, DataSource can issue a series of results, rather than just one.

最典型的用處就是漸進式加載圖片時可以提供加載中的中間數據。


DataSubscriberDataSource 構成了1個視察者模式

Datasource 提供了注冊方法。

void subscribe(DataSubscriber<T> dataSubscriber, Executor executor);

通過 subscribe 方法我們可以把 DataSubscriber 注冊成為 DataSource 的視察者,然后當 DataSource 的數據產生變化時,在 Executor 中通知所有的視察者 - DataSubscriber

DataSubscriber 會響應數據的4種變化。

  1. onNewResult
  2. onFailure
  3. onCancellation
  4. onProgressUpdate

使用Executor來通知視察者是比較高明的,這樣做可讓回調方法的履行線程交由 DataSubscriber 來處理,增加了靈活性。


DataSource 只是1個接口,沒有提供任何實現,AbstractDataSource 實現了 DataSource 后封裝了1些基礎的操作,例如 通知視察者記錄數據狀態

Datasource 的狀態記錄使用了1個枚舉類型。

private enum DataSourceStatus { // data source has not finished yet IN_PROGRESS, // data source has finished with success SUCCESS, // data source has finished with failure FAILURE, }

這3種狀態保存在1個成員變量(mDataSourceStatus)中。

@GuardedBy("this") private DataSourceStatus mDataSourceStatus;

AbstractDataSource 構造時,會把 mDataSourceStatus 設置為 IN_PROGRESS

protected AbstractDataSource() { mIsClosed = false; mDataSourceStatus = DataSourceStatus.IN_PROGRESS; mSubscribers = new ConcurrentLinkedQueue<>(); }

所有的視察者(定閱者)會被放在1個列表中 - mSubscribers

private final ConcurrentLinkedQueue<Pair<DataSubscriber<T>, Executor>> mSubscribers;

如果當前的數據要求沒有關閉并且滿足mDataSourceStatus == DataSourceStatus.IN_PROGRESS時才能注冊成功視察者,由于只有當數據產生變化的時候,視察者才有存在的意義。

@Override public void subscribe(final DataSubscriber<T> dataSubscriber, final Executor executor) { Preconditions.checkNotNull(dataSubscriber); Preconditions.checkNotNull(executor); boolean shouldNotify; synchronized(this) { if (mIsClosed) { return; } if (mDataSourceStatus == DataSourceStatus.IN_PROGRESS) { mSubscribers.add(Pair.create(dataSubscriber, executor)); } shouldNotify = hasResult() || isFinished() || wasCancelled(); } if (shouldNotify) { notifyDataSubscriber(dataSubscriber, executor, hasFailed(), wasCancelled()); } }

如果 DataSource 有了新的數據或要求已結束掉或被取消掉,會通知視察者。

private void notifyDataSubscribers() { final boolean isFailure = hasFailed(); final boolean isCancellation = wasCancelled(); for (Pair<DataSubscriber<T>, Executor> pair : mSubscribers) { notifyDataSubscriber(pair.first, pair.second, isFailure, isCancellation); } } private void notifyDataSubscriber( final DataSubscriber<T> dataSubscriber, final Executor executor, final boolean isFailure, final boolean isCancellation) { executor.execute( new Runnable() { @Override public void run() { if (isFailure) { dataSubscriber.onFailure(AbstractDataSource.this); } else if (isCancellation) { dataSubscriber.onCancellation(AbstractDataSource.this); } else { dataSubscriber.onNewResult(AbstractDataSource.this); } } }); }

使用 DataSource 很重要的1點:不要產生內存泄漏,也就是說,用過的資源1定要釋放掉。
使用 DataSubscriber 注冊成了視察者后,回調方法都會帶回1個 DataSource 的實例,如果要求已結束后者失敗了,拿到數據后1定要把 DataSourceclose 掉,否則很容易造成 OOM。

BaseDataSubscriber 就是為了避免OOM,它本身的設計也很奇妙。

在毀掉方法 onNewResultonFailure 中加了1個 try - catch, 在 try 的 block 中調用子類必須重載的 onNewResultImpl 方法,然后在 finally 的 block 中 close DataSource

DataSourceSubscriber.java

public abstract class BaseDataSubscriber<T> implements DataSubscriber<T> { @Override public void onNewResult(DataSource<T> dataSource) { try { onNewResultImpl(dataSource); } finally { if (dataSource.isFinished()) { dataSource.close(); } } } @Override public void onFailure(DataSource<T> dataSource) { try { onFailureImpl(dataSource); } finally { dataSource.close(); } } @Override public void onCancellation(DataSource<T> dataSource) { } @Override public void onProgressUpdate(DataSource<T> dataSource) { } protected abstract void onNewResultImpl(DataSource<T> dataSource); protected abstract void onFailureImpl(DataSource<T> dataSource); }

IncreasingQualityDataSourceSupplierFirstAvailableDataSourceSupplierDataSource 的兩種不同的數據存儲情勢,等后面用到了再做分析。


Supplier 是1個設計比較奇妙的借口,用處非常廣泛。

A class that can supply objects of a single type. Semantically, this could be a factory, generator, builder, closure, or something else entirely. No guarantees are implied by this interface.


SettableDataSourceset 方法中使用 GuavaPreconditions 來做數據合法性檢驗,它與 DataSource 的區分也是僅此而已。

Preconditions

  • checkArgument
  • checkState
  • checkNotNull
  • checkElementIndex
  • checkPositionIndex
  • checkPositionIndexes

如果 check 結果為 false, 則拋出異常。Fresco 的毛病處理基本上是用異常做的。

生活不易,碼農辛苦
如果您覺得本網站對您的學習有所幫助,可以手機掃描二維碼進行捐贈
程序員人生
------分隔線----------------------------
分享到:
------分隔線----------------------------
關閉
程序員人生
主站蜘蛛池模板: www.狠狠操.com | 久久久久久久岛国免费播放 | 最近最新中文字幕大全高清6 | 五月天伊人 | 中文精品久久久久中文 | 羞羞动漫视频在线观看 | 在线看片777av免费观看 | 欧美日韩一区二区三区久久 | 中文字幕第一页国产 | 欧美日韩乱 | 国产精品亚洲第五区在线 | 亚洲精品久久99久久一区 | 最近中文字幕免费6 | 日本护士handjob | 中国一级淫片aaa毛片毛片 | 日本www高清 | 亚洲 欧美 小说 国产 图片 | 黄网站在线播放视频免费观看 | 国产在线h视频 | 免费国产在线观看老王影院 | jizz18欧美18 | 成人国内精品久久久久影 | 成人毛片一区二区三区 | 欧美最新的精品videoss | 亚洲精品一区二区三区在 | 爽爽在线 | 亚洲国产欧美一区 | 老司机午夜精品视频播放 | 亚洲成人av| 欧美日韩亚洲精品一区二区 | 亚洲精品永久一区 | 国产成人精品免费视频网页大全 | 91久久亚洲精品国产一区二区 | 成人污片 | 18欧美同性视频 | 亚洲一区日本 | 日本高清专区一区二无线 | 国产欧美日韩综合二区三区 | 亚洲图片另类小说 | 国产高清在线精品一区二区三区 | 欧美一级毛片美99毛片 |