Fresco源码解析 - DataSource怎样存储数据

 

Fresco源码解析 - DataSource怎样存储数据 

datasource是一个独立的 package,与FB导入的guava包都在同一个工程内
fbcore

datasource的类关系比较简单,一张类图基本就可以描述清楚它们间的关系。



DataSource 是一个 interface
功能与JDK中的Future类似,但是相比于Future,它的先进之处则在于 不仅仅只生产一个单一的结果,而是能够提供系列结果。

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

最典型的用途就是渐进式加载图片时可以提供加载中的中间数据。



DataSubscriber 和 DataSource 构成了一个观察者模式。

Datasource 提供了注册方法。

<code class="hljs cs has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> subscribe(DataSubscriber<T> dataSubscriber, Executor executor);</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li></ul>

通过 subscribe 方法我们可以把 DataSubscriber 注册成为 DataSource 的观察者,然后当 DataSource 的数据发生变化时,在 Executor 中通知所有的观察者
DataSubscriber

DataSubscriber 会响应数据的四种变化。

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

使用Executor来通知观察者是比较高明的,这样做可以让回调方法的执行线程交由 DataSubscriber 来处理,增加了灵活性。



DataSource 只是一个接口,没有提供任何实现,AbstractDataSource 实现了 DataSource 后封装了一些基础的操作,例如 通知观察者,记录数据状态。

Datasource 的状态记录使用了一个枚举类型。

<code class="language-java hljs  has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">private</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">enum</span> DataSourceStatus {
  <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// data source has not finished yet</span>
  IN_PROGRESS,

  <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// data source has finished with success</span>
  SUCCESS,

  <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// data source has finished with failure</span>
  FAILURE,
}</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li></ul>

这三种状态保存在一个成员变量(mDataSourceStatus)中。

<code class="language-java hljs  has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-annotation" style="color: rgb(155, 133, 157); box-sizing: border-box;">@GuardedBy</span>(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"this"</span>)
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">private</span> DataSourceStatus mDataSourceStatus;</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li></ul>

AbstractDataSource 构造时,会把 mDataSourceStatus 设置为 IN_PROGRESS

<code class="language-java hljs  has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">protected</span> <span class="hljs-title" style="box-sizing: border-box;">AbstractDataSource</span>() {
  mIsClosed = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">false</span>;
  mDataSourceStatus = DataSourceStatus.IN_PROGRESS;
  mSubscribers = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> ConcurrentLinkedQueue<>();
}</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li></ul>

所有的观察者(订阅者)会被放在一个列表中 - mSubscribers

<code class="language-java hljs  has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">private</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">final</span> ConcurrentLinkedQueue<Pair<DataSubscriber<T>, Executor>> mSubscribers;</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li></ul>

如果当前的数据请求没有关闭并且满足mDataSourceStatus == DataSourceStatus.IN_PROGRESS时才能注册成功观察者,因为只有当数据发生变化的时候,观察者才有存在的意义。

<code class="language-java hljs  has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">  <span class="hljs-annotation" style="color: rgb(155, 133, 157); box-sizing: border-box;">@Override</span>
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">subscribe</span>(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">final</span> DataSubscriber<T> dataSubscriber, <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">final</span> Executor executor) {
  Preconditions.checkNotNull(dataSubscriber);
  Preconditions.checkNotNull(executor);
  <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">boolean</span> shouldNotify;

  <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">synchronized</span>(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">this</span>) {
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (mIsClosed) {
      <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span>;
    }

    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (mDataSourceStatus == DataSourceStatus.IN_PROGRESS) {
      mSubscribers.add(Pair.create(dataSubscriber, executor));
    }

    shouldNotify = hasResult() || isFinished() || wasCancelled();
  }

  <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (shouldNotify) {
    notifyDataSubscriber(dataSubscriber, executor, hasFailed(), wasCancelled());
  }
}</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li></ul>

如果 DataSource 有了新的数据或者请求已经结束掉或被取消掉,会通知观察者。

<code class="language-java hljs  has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">private</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">notifyDataSubscribers</span>() {
  <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">final</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">boolean</span> isFailure = hasFailed();
  <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">final</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">boolean</span> isCancellation = wasCancelled();
  <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">for</span> (Pair<DataSubscriber<T>, Executor> pair : mSubscribers) {
    notifyDataSubscriber(pair.first, pair.second, isFailure, isCancellation);
  }
}

<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">private</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">notifyDataSubscriber</span>(
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">final</span> DataSubscriber<T> dataSubscriber,
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">final</span> Executor executor,
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">final</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">boolean</span> isFailure,
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">final</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">boolean</span> isCancellation) {
  executor.execute(
      <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> Runnable() {
        <span class="hljs-annotation" style="color: rgb(155, 133, 157); box-sizing: border-box;">@Override</span>
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">run</span>() {
          <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (isFailure) {
            dataSubscriber.onFailure(AbstractDataSource.<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">this</span>);
          } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">else</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (isCancellation) {
            dataSubscriber.onCancellation(AbstractDataSource.<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">this</span>);
          } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">else</span> {
            dataSubscriber.onNewResult(AbstractDataSource.<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">this</span>);
          }
        }
      });
}</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li><li style="box-sizing: border-box; padding: 0px 5px;">26</li><li style="box-sizing: border-box; padding: 0px 5px;">27</li></ul>


使用 DataSource 很重要的一点:不要产生内存泄露,也就是说,用过的资源一定要释放掉。 
使用 DataSubscriber 注册成为了观察者后,回调方法都会带回一个 DataSource 的实例,如果请求已经结束后者失败了,拿到数据后一定要把 DataSource 给 close 掉,否则很容易造成
OOM。

BaseDataSubscriber 就是为了防止OOM,它本身的设计也很巧妙。

在毁掉方法 onNewResult 和 onFailure 中加了一个 try
- catch
, 在 try 的 block 中调用子类必须重载的onNewResultImpl 方法,然后在 finally 的
block 中 close DataSource

DataSourceSubscriber.java

<code class="language-java hljs  has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">abstract</span> <span class="hljs-class" style="box-sizing: border-box;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">class</span> <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">BaseDataSubscriber</span><<span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">T</span>> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">implements</span> <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">DataSubscriber</span><<span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">T</span>> {</span>

  <span class="hljs-annotation" style="color: rgb(155, 133, 157); box-sizing: border-box;">@Override</span>
  <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">onNewResult</span>(DataSource<T> dataSource) {
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">try</span> {
      onNewResultImpl(dataSource);
    } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">finally</span> {
      <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (dataSource.isFinished()) {
        dataSource.close();
      }
    }
  }

  <span class="hljs-annotation" style="color: rgb(155, 133, 157); box-sizing: border-box;">@Override</span>
  <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">onFailure</span>(DataSource<T> dataSource) {
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">try</span> {
      onFailureImpl(dataSource);
    } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">finally</span> {
      dataSource.close();
    }
  }

  <span class="hljs-annotation" style="color: rgb(155, 133, 157); box-sizing: border-box;">@Override</span>
  <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">onCancellation</span>(DataSource<T> dataSource) {
  }

  <span class="hljs-annotation" style="color: rgb(155, 133, 157); box-sizing: border-box;">@Override</span>
  <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">onProgressUpdate</span>(DataSource<T> dataSource) {
  }

  <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">protected</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">abstract</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">onNewResultImpl</span>(DataSource<T> dataSource);

  <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">protected</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">abstract</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">onFailureImpl</span>(DataSource<T> dataSource);
}</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li><li style="box-sizing: border-box; padding: 0px 5px;">26</li><li style="box-sizing: border-box; padding: 0px 5px;">27</li><li style="box-sizing: border-box; padding: 0px 5px;">28</li><li style="box-sizing: border-box; padding: 0px 5px;">29</li><li style="box-sizing: border-box; padding: 0px 5px;">30</li><li style="box-sizing: border-box; padding: 0px 5px;">31</li><li style="box-sizing: border-box; padding: 0px 5px;">32</li><li style="box-sizing: border-box; padding: 0px 5px;">33</li><li style="box-sizing: border-box; padding: 0px 5px;">34</li></ul>


IncreasingQualityDataSourceSupplier 和 FirstAvailableDataSourceSupplier 是 DataSource 的两种不同的数据存储形式,等后面用到了再做分析。



Supplier 是一个设计比较巧妙的借口,用途非常广泛。

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.



SettableDataSource 在 set 方法中使用 Guava 的 Preconditions 来做数据合法性检验,它与 DataSource 的区别也是仅此而已。

Preconditions

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

如果 check 结果为 false, 则抛出异常。Fresco 的错误处理基本上是用异常做的。

时间: 2024-08-02 09:24:51

Fresco源码解析 - DataSource怎样存储数据的相关文章

Fresco源码解析 - 创建一个ImagePipeline(一)

在Fresco源码解析 - 初始化过程分析章节中, 我们分析了Fresco的初始化过程,两个initialize方法中都用到了 ImagePipelineFactory类.   ImagePipelineFactory.initialize(context); 会创建一个所有参数都使用默认值的ImagePipelineConfig来初始化ImagePipeline.   ImagePipelineFactory.initialize(imagePipelineConfig)会首先用 imageP

Java集合学习(十三) WeakHashMap详细介绍(源码解析)和使用示例

这一章,我们对WeakHashMap进行学习. 我们先对WeakHashMap有个整体认识,然后再学习它的源码,最后再通过实例来学会使用WeakHashMap. 第1部分 WeakHashMap介绍 WeakHashMap简介    WeakHashMap 继承于AbstractMap,实现了Map接口.    和HashMap一样,WeakHashMap 也是一个散列表,它存储的内容也是键值对(key-value)映射,而且键和值都可以是null.   不过WeakHashMap的键是"弱键&

Java集合学习(十一) Hashtable详细介绍(源码解析)和使用示例

这一章,我们对Hashtable进行学习. 我们先对Hashtable有个整体认识,然后再学习它的源码,最后再通过实例来学会使用Hashtable. 第1部分 Hashtable介绍 Hashtable 简介 和HashMap一样,Hashtable 也是一个散列表,它存储的内容是键值对(key-value)映射. Hashtable 继承于Dictionary,实现了Map.Cloneable.java.io.Serializable接口. Hashtable 的函数都是同步的,这意味着它是线

Java集合学习(十) HashMap详细介绍(源码解析)和使用示例

这一章,我们对HashMap进行学习. 我们先对HashMap有个整体认识,然后再学习它的源码,最后再通过实例来学会使用HashMap. 第1部分 HashMap介绍 HashMap简介 HashMap 是一个散列表,它存储的内容是键值对(key-value)映射. HashMap 继承于AbstractMap,实现了Map.Cloneable.java.io.Serializable接口. HashMap 的实现不是同步的,这意味着它不是线程安全的.它的key.value都可以为null.此外

EventBus用法及源码解析

EventBus用法及源码解析 目录介绍 1.EventBus简介 1.1 EventBus的三要素 1.2 EventBus的四种ThreadMode(线程模型) 1.3 EventBus怎么调用 2.EventBus使用 2.1 最简单的使用 3.EventBus注册源码解析 3.1 EventBus.getDefault()获取对象 3.2 register(this)注册源码解析 3.2.1 首先看register(this)源码 3.2.2 接下来看findSubscriberMeth

EventBus源码解析

前面一篇文章讲解了EventBus的使用,但是作为开发人员,不能只停留在仅仅会用的层面上,我们还需要弄清楚它的内部实现原理.所以本篇博文将分析EventBus的源码,看看究竟它是如何实现"发布/订阅"功能的. 相关文章EventBus使用详解EventBus源码解析 事件注册 根据前一讲EventBus使用详解我们已经知道EventBus使用首先是需要注册的,注册事件的代码如下: EventBus.getDefault().register(this); EventBus对外提供了一个

从源码解析Android中View的容器ViewGroup_Android

 这回我们是深入到ViewGroup内部\,了解ViewGroup的工作,同时会阐述更多有关于View的相关知识.以便为以后能灵活的使用自定义空间打更近一步的基础.希望有志同道合的朋友一起来探讨,深入Android内部,深入理解Android. 一.ViewGroup是什么?       一个ViewGroup是一个可以包含子View的容器,是布局文件和View容器的基类.在这个类里定义了ViewGroup.LayoutParams类,这个类是布局参数的子类.        其实ViewGrou

Java 集合系列10之 HashMap详细介绍(源码解析)和使用示例

概要 这一章,我们对HashMap进行学习.我们先对HashMap有个整体认识,然后再学习它的源码,最后再通过实例来学会使用HashMap.内容包括:第1部分 HashMap介绍第2部分 HashMap数据结构第3部分 HashMap源码解析(基于JDK1.6.0_45)    第3.1部分 HashMap的"拉链法"相关内容    第3.2部分 HashMap的构造函数    第3.3部分 HashMap的主要对外接口    第3.4部分 HashMap实现的Cloneable接口 

Java 集合系列11之 Hashtable详细介绍(源码解析)和使用示例

概要 前一章,我们学习了HashMap.这一章,我们对Hashtable进行学习.我们先对Hashtable有个整体认识,然后再学习它的源码,最后再通过实例来学会使用Hashtable.第1部分 Hashtable介绍第2部分 Hashtable数据结构第3部分 Hashtable源码解析(基于JDK1.6.0_45)第4部分 Hashtable遍历方式第5部分 Hashtable示例 转载请注明出处:http://www.cnblogs.com/skywang12345/p/3310887.h