美文网首页
Native API 之 ImageLoader

Native API 之 ImageLoader

作者: 卑鄙的鹿尤菌 | 来源:发表于2017-06-04 17:25 被阅读134次

    在Android端,React Native采用了Fresco图片库来进行图片相关的操作,因此RN所有的图片管理策略都基于Fresco。
    ImageLoaderModule利用Fresco向JS端提供了图片加载相关的能力,该module主要API方法如下:

    • getSize 获取网络图片的宽高
    • prefetchImage 预加载图片到磁盘缓存
    • abortRequest 取消请求任务
    • queryCache 根据uri查询该图片的缓存位置(memory 或者 disk)

    具体实现分析如下。


    getSize

    • input: 图片的URI
    • output:图片尺寸对象
    {
        “width”:400,
        "height":300
    }
    

    getSize 异步获取网络图片的宽高:

      public void getSize(
          final String uriString,
          final Promise promise) {
        if (uriString == null || uriString.isEmpty()) {
          promise.reject(ERROR_INVALID_URI, "Cannot get the size of an image for an empty URI");
          return;
        }
    
        Uri uri = Uri.parse(uriString);
        // 根据URI 创建图片请求对象
        ImageRequest request = ImageRequestBuilder.newBuilderWithSource(uri).build();
        // 下载图片并decode
        DataSource<CloseableReference<CloseableImage>> dataSource =
          Fresco.getImagePipeline().fetchDecodedImage(request, mCallerContext);
    
        DataSubscriber<CloseableReference<CloseableImage>> dataSubscriber =
          new BaseDataSubscriber<CloseableReference<CloseableImage>>() {
            @Override
            protected void onNewResultImpl(
                DataSource<CloseableReference<CloseableImage>> dataSource) {
              if (!dataSource.isFinished()) {
                return;
              }
              CloseableReference<CloseableImage> ref = dataSource.getResult();
              if (ref != null) {
                try {
                  CloseableImage image = ref.get();
    
                  WritableMap sizes = Arguments.createMap();
                  sizes.putInt("width", image.getWidth());
                  sizes.putInt("height", image.getHeight());
    
                  promise.resolve(sizes);
                } catch (Exception e) {
                  promise.reject(ERROR_GET_SIZE_FAILURE, e);
                } finally {
                  CloseableReference.closeSafely(ref);
                }
              } else {
                promise.reject(ERROR_GET_SIZE_FAILURE);
              }
            }
    
            @Override
            protected void onFailureImpl(DataSource<CloseableReference<CloseableImage>> dataSource) {
              promise.reject(ERROR_GET_SIZE_FAILURE, dataSource.getFailureCause());
            }
          };
        dataSource.subscribe(dataSubscriber, CallerThreadExecutor.getInstance());
      }
    

    prefetchImage

    • input:图片的URI,标识请求的ID
    • output:图片是否预加载成功

    prefetchImage 将图片下载到磁盘缓存中

      public void prefetchImage(
        final String uriString,
        final int requestId,
        final Promise promise)
      {
        if (uriString == null || uriString.isEmpty()) {
          promise.reject(ERROR_INVALID_URI, "Cannot prefetch an image for an empty URI");
          return;
        }
    
        Uri uri = Uri.parse(uriString);
        ImageRequest request = ImageRequestBuilder.newBuilderWithSource(uri).build();
        //下载图片到磁盘
        DataSource<Void> prefetchSource =
          Fresco.getImagePipeline().prefetchToDiskCache(request, mCallerContext);
        DataSubscriber<Void> prefetchSubscriber = new BaseDataSubscriber<Void>() {
          @Override
          protected void onNewResultImpl(DataSource<Void> dataSource) {
            if (!dataSource.isFinished()) {
              return;
            }
            try {
              removeRequest(requestId);
              promise.resolve(true);
            } finally {
              dataSource.close();
            }
          }
    
          @Override
          protected void onFailureImpl(DataSource<Void> dataSource) {
            try {
              removeRequest(requestId);
              promise.reject(ERROR_PREFETCH_FAILURE, dataSource.getFailureCause());
            } finally {
              dataSource.close();
            }
          }
        };
        registerRequest(requestId, prefetchSource);
        prefetchSource.subscribe(prefetchSubscriber, CallerThreadExecutor.getInstance());
      }
    

    queryCache
    input: 待查询的uri 数组
    output: 图片位于缓存的位置对象

    { 
        "https://s.geilicdn.com/CPC/common/201705/header/images/logo-5f5aeedef4.png": "disk", 
        "https://s.geilicdn.com/CPC/loginNew/201706/login/images/topic-bb6756e79d.png": "memory"
    }
    

    根据uri查询异步图片所在缓存类型:

    public void queryCache(final ReadableArray uris, final Promise promise) {
        // perform cache interrogation in async task as disk cache checks are expensive
        new GuardedAsyncTask<Void, Void>(getReactApplicationContext()) {
          @Override
          protected void doInBackgroundGuarded(Void... params) {
            WritableMap result = Arguments.createMap();
            ImagePipeline imagePipeline = Fresco.getImagePipeline();
            for (int i = 0; i < uris.size(); i++) {
              String uriString = uris.getString(i);
              final Uri uri = Uri.parse(uriString);
              if (imagePipeline.isInBitmapMemoryCache(uri)) {
                result.putString(uriString, "memory");
              } else if (imagePipeline.isInDiskCacheSync(uri)) {
                result.putString(uriString, "disk");
              }
            }
            promise.resolve(result);
          }
        }.executeOnExecutor(GuardedAsyncTask.THREAD_POOL_EXECUTOR);
      }
    

    相关文章

      网友评论

          本文标题:Native API 之 ImageLoader

          本文链接:https://www.haomeiwen.com/subject/hxwvfxtx.html