ion学习

来源:互联网 发布:白苹果怎么备份数据 编辑:程序博客网 时间:2024/05/17 21:15

[转]http://blog.csdn.net/moonant/article/details/38101039

它所依赖的库

  • androidasync.jar
  • gson.jar
  • android-support-v4.jar

四种常见的 POST 提交数据方式

  • application/x-www-form-urlencoded
  • multipart/form-data
  • application/json
  • text/xml

特点


  • 自动回调UI线程
  • 灵活的api
  • 缓存
  • 管理activity 和service的生命周期
  • 所有操作返回Futures(可取消)

关于图片

  • 支持ListView回收,缓存
  • 继承自 UrlimageViewHelper

ion的几种网络请求


  1. 基本回调

    Ion.with(context).load("http://api.example.com")
  2. 参数

    1. json
      .setJsonObjectBody()
    2. url 编码

      .setBosyparameter("foo","bar")

    3. 上传文件
      .setMultipartParameter("goop","noop") .setMultipartParameter("filename.zip",new File("/sd/file"))
  3. 进度

    .uploadProgressBar(bar).progressBar(bar).progressDialog(progressDialog).progress(new callback())
  4. 头信息
    setHeader("foo","bar")
  5. img -> ImageView
    .withBitmap().placeholder(resId).error(resId).animateLoad(Animation).animateIn(Animation).intoImageView(imageview)
  6. 设置返回类型
    .asJsonObject().asString().write(new File("/"))
  7. future
    All operations return a custom Future that allows you to specify a callback that runs on completion.

    • 回调
      setCallBack(new FutureCallback<T>(){});
    • 阻塞调用
      get();
    • 取消
      .cancel();.cancelall(tag)
    • 返回头信息
      .withResponse()
  8. 阻塞
    JsonObject json = Ion.with(context).load("http://example.com/thing.json").asJsonObject().get();

    分包


  • src

    • bitmap
    • builder
    • conscrypt
    • cookie
    • future
    • gif
    • gson
    • loader

    AsserLoader
    BitmapCallback 图片回调类, 4个子类
    BitmapFetcher 图片处理?类()
    BitmapInfoToBitmap
    ContextReference
    DeferredLoadBitmap

加载图片

Load an image into an ImageView_

// This is the "long" way to do build an ImageView request... it allows you to set headers, etc.Ion.with(context).load("http://example.com/image.png").withBitmap().placeholder(R.drawable.placeholder_image).error(R.drawable.error_image).animateLoad(spinAnimation).animateIn(fadeInAnimation).intoImageView(imageView);// but for brevity, use the ImageView specific builder...Ion.with(imageView).placeholder(R.drawable.placeholder_image).error(R.drawable.error_image).animateLoad(spinAnimation).animateIn(fadeInAnimation).load("http://example.com/image.png");

The Ion Image load API has the following features: Disk and memory caching Bitmaps are held via weak references so memory is managed very effeciently ListView Adapter recycling support Bitmap transformations via the .transform(Transform) Animate loading and loaded ImageView states DeepZoom for extremely large images

流程

    • LoadBuilder<Builders.Any.B> Ion.with(Context)

      Get the default Ion object instance and begin building a request

    • Builders.Any.B load(java.lang.String uri) //*返回IonRequestBuilder实现*

      uri - Uri to load. This may be a http(s), file, or content uri.

    • Builders.Any.B load(java.lang.String method, java.lang.String url)

      method - HTTP method such as GET or POST.
      url - Url to load.

    • Builders.Any.B load(java.io.File file)

      file - File to load.

    • Builders.Any.BF<? extends Builders.Any.BF<?>> withBitmap() //继承自builder.FutureBuilder

      Use the request as a Bitmap which can then be modified and/or applied to an ImageView.

  1. Builders.IV.F<? extends Builders.IV.F<?>> Ion.with(ImageView) // 实现类IonImageViewRequestBuilder

    Create a ImageView bitmap request builder

    Builders.Any.BF<? extends Builders.Any.BF<?>>
    Builders.IV.F<? extends Builders.IV.F<?>>
    都是和image bitmap 相关的接口

  2. ImageViewBuilder<I extends ImageViewBuilder<?>> 对 imageView 进行设置
    .placeHolder() .error .animateLoad() .animateIn() 返回 I 可以重复调用

    • 设置ImageView
      ImageViewFuture .intoimageView() //ImageViewFutureBuilder 实现IonBitmapRequestBuilder, IonImageViewRequestBuilder, IonRequestBuilder
    • 设置 uri
      ImageViewFuture .load(url) //LoadImageViewFutureBuilder 实现IonImageViewRequestBuilder
  3. 得到ImageViewFuture(com.koushikdutta.async.future.Cancellable, java.util.concurrent.Future<ImageView>) 实现:IonDrawable.ImageViewFutureImpl

    限定符和类型 方法和说明
    com.koushikdutta.async.future.Future<ImageViewBitmapInfo> withBitmapInfo()
    从接口继承的方法 com.koushikdutta.async.future.Future
    setCallback, then
    从接口继承的方法 com.koushikdutta.async.future.Cancellable
    cancel, isCancelled, isDone
    从接口继承的方法 java.util.concurrent.Future
    cancel, get, get, isCancelled, isDone

Ion

public class Ion {    public static LoadBuilder<Builders.Any.B> with(Context context) {        return getDefault(context).build(context);    }    public static Ion getDefault(Context context) {        return getInstance(context, "ion");    }   public LoadBuilder<Builders.Any.B> build(Context context) {        return new IonRequestBuilder(ContextReference.fromContext(context), this);    }}

IonRequestBuilder

LoadBuilder<Builders.Any.B> Ion.with(Context)
LoadBuilder<Builders.Any.B>的唯一实现类IonRequestBuilder
Builders.Any.B .load(java.lang.String uri)
返回自己,Builders.Any.B的唯一实现类IonRequestBuilder
Builders.Any.BF<? extends Builders.Any.BF<?>> withBitmap()
返回IonImageViewRequestBuilder,Builders.Any.BF<? extends Builders.Any.BF<?>>两个实现类
IonBitmapRequestBuilder, IonImageViewRequestBuilder

class IonRequestBuilder implements Builders.Any.B LoadBuilder<Builders.Any.B> {     public IonRequestBuilder load(String url) {        return loadInternal(AsyncHttpGet.METHOD, url);    }     private IonRequestBuilder loadInternal(String method, String url) {        this.method = method;        if (!TextUtils.isEmpty(url) && url.startsWith("/"))            url = new File(url).toURI().toString();        this.uri = url;        return this;    }     public IonImageViewRequestBuilder withBitmap() {        return new IonImageViewRequestBuilder(this);    }}

IonImageViewRequestBuilder

class IonImageViewRequestBuilder extends IonBitmapRequestBuilder implements Builders.Any.BF<? extends Builders.Any.BF<?>>{     public IonImageViewRequestBuilder(IonRequestBuilder builder) {        super(builder);    }        @Override    public ImageViewFuture intoImageView(ImageView imageView) {        assert Thread.currentThread() == Looper.getMainLooper().getThread();        if (imageView == null)            throw new NullPointerException("imageView");        // no uri? just set a placeholder and bail        if (builder.uri == null) {            setIonDrawable(imageView, null, 0).cancel();            return FUTURE_IMAGEVIEW_NULL_URI;        }        // executeCache the request, see if we get a bitmap from cache.        BitmapFetcher bitmapFetcher = executeCache();//         if (bitmapFetcher.info != null) {            doAnimation(imageView, null, 0);            IonDrawable drawable = setIonDrawable(imageView, bitmapFetcher.info, Loader.LoaderEmitter.LOADED_FROM_MEMORY);            drawable.cancel();            IonDrawable.ImageViewFutureImpl imageViewFuture = drawable.getFuture();            imageViewFuture.reset();            imageViewFuture.setComplete(bitmapFetcher.info.exception, imageView);            return imageViewFuture;        }        IonDrawable drawable = setIonDrawable(imageView, null, 0);        doAnimation(imageView, loadAnimation, loadAnimationResource);        IonDrawable.ImageViewFutureImpl imageViewFuture = drawable.getFuture();        imageViewFuture.reset();        drawable.register(ion, bitmapFetcher.bitmapKey);        // nothing from cache, check to see if there's too many imageview loads        // already in progress        if (BitmapFetcher.shouldDeferImageView(ion)) {            bitmapFetcher.defer();        }        else {            bitmapFetcher.execute();        }        return imageViewFuture;    }    private IonDrawable setIonDrawable(ImageView imageView, BitmapInfo info, int loadedFrom) {        IonDrawable ret = IonDrawable.getOrCreateIonDrawable(imageView)        .ion(ion)        .setBitmap(info, loadedFrom)        .setSize(resizeWidth, resizeHeight)        .setError(errorResource, errorDrawable)        .setPlaceholder(placeholderResource, placeholderDrawable)        .setInAnimation(inAnimation, inAnimationResource)        .setDisableFadeIn(disableFadeIn);        imageView.setImageDrawable(ret);        return ret;    }}

IonDrawable

class IonDrawble extends Drawable {        static IonDrawable getOrCreateIonDrawable(ImageView imageView) {        Drawable current = imageView.getDrawable();        IonDrawable ret;        if (current == null || !(current instanceof IonDrawable))            ret = new IonDrawable(imageView.getResources(), imageView);        else            ret = (IonDrawable)current;        // invalidate self doesn't seem to trigger the dimension check to be called by imageview.        // are drawable dimensions supposed to be immutable?        imageView.setImageDrawable(null);        return ret;    }    public IonDrawable(Resources resources, ImageView imageView) {        this.resources = resources;        paint = new Paint(DEFAULT_PAINT_FLAGS);        callback = new IonDrawableCallback(this, imageView);    }    public void register(Ion ion, String bitmapKey) {        String previousKey = callback.bitmapKey;        if (TextUtils.equals(previousKey, bitmapKey))            return;        callback.bitmapKey = bitmapKey;        ion.bitmapsPending.add(bitmapKey, callback);        unregister(ion, previousKey, callback);    }}
// create an internal static class that can act as a callback.    // dont let it hold strong references to anything.    static class IonDrawableCallback implements FutureCallback<BitmapInfo> {        private WeakReference<IonDrawable> ionDrawableRef;        private ContextReference.ImageViewContextReference imageViewRef;        private String bitmapKey;        private ImageViewFutureImpl imageViewFuture = new ImageViewFutureImpl();        private Animation inAnimation;        private int inAnimationResource;        public IonDrawableCallback(IonDrawable drawable, ImageView imageView) {            ionDrawableRef = new WeakReference<IonDrawable>(drawable);            imageViewRef = new ContextReference.ImageViewContextReference(imageView);        }        @Override        public void onCompleted(Exception e, BitmapInfo result) {            assert Thread.currentThread() == Looper.getMainLooper().getThread();            assert result != null;            // see if the imageview is still alive and cares about this result            ImageView imageView = imageViewRef.get();            if (imageView == null)                return;            IonDrawable drawable = ionDrawableRef.get();            if (drawable == null)                return;            if (imageView.getDrawable() != drawable)                return;            imageView.setImageDrawable(null);            drawable.setBitmap(result, result.loadedFrom);            imageView.setImageDrawable(drawable);            IonBitmapRequestBuilder.doAnimation(imageView, inAnimation, inAnimationResource);            if (null != imageViewRef.isAlive()) {                imageViewFuture.cancelSilently();                return;            }            imageViewFuture.setComplete(e, imageView);        }    }

IonBitmapRequestBuilder

class IonBitmapRequestBuilder {    BitmapFetcher executeCache() {        final String downloadKey = computeDownloadKey();        String bitmapKey = computeBitmapKey(downloadKey);        // TODO: eliminate this allocation?        BitmapFetcher ret = new BitmapFetcher();        ret.downloadKey = downloadKey;        ret.bitmapKey = bitmapKey;        ret.hasTransforms = hasTransforms();        ret.resizeWidth = resizeWidth;        ret.resizeHeight = resizeHeight;        ret.builder = builder;        ret.transforms = transforms;        ret.animateGif = animateGif;        ret.deepZoom = deepZoom;        ret.postProcess = postProcess;        // see if this request can be fulfilled from the cache        if (!builder.noCache) {            BitmapInfo bitmap = builder.ion.bitmapCache.get(bitmapKey);            if (bitmap != null) {                ret.info = bitmap;                return ret;            }        }        return ret;    }}

BitmapFetcher

class BitmapFetcher implements IonRequestBuilder.LoadRequestCallback{    public static boolean shouldDeferImageView(Ion ion) {        if (ion.bitmapsPending.keySet().size() <= MAX_IMAGEVIEW_LOAD)            return false;        int loadCount = 0;        for (String key: ion.bitmapsPending.keySet()) {            Object owner = ion.bitmapsPending.tag(key);            if (owner instanceof LoadBitmapBase) {                loadCount++;                if (loadCount > MAX_IMAGEVIEW_LOAD)                    return true;            }        }        return false;    }    public DeferredLoadBitmap defer() {        DeferredLoadBitmap ret = new DeferredLoadBitmap(builder.ion, downloadKey, this);        executeTransforms(builder.ion);        return ret;    }    public void execute() {        final Ion ion = builder.ion;        // bitmaps that were transformed are put into the FileCache to prevent        // subsequent retransformation. See if we can retrieve the bitmap from the disk cache.        // See TransformBitmap for where the cache is populated.        FileCache fileCache = ion.responseCache.getFileCache();        if (!builder.noCache && hasTransforms && fileCache.exists(bitmapKey) && !deepZoom) {            TransformBitmap.getBitmapSnapshot(ion, bitmapKey, postProcess);            return;        }        // Perform a download as necessary.        if (ion.bitmapsPending.tag(downloadKey) == null && !fastLoad(builder.uri)) {            builder.setHandler(null);            builder.loadRequestCallback = this;            if (!deepZoom) {                IonRequestBuilder.EmitterTransform<ByteBufferList> emitterTransform = builder.execute(new ByteBufferListParser(), new Runnable() {                    @Override                    public void run() {                        AsyncServer.post(Ion.mainHandler, new Runnable() {                            @Override                            public void run() {                                ion.bitmapsPending.remove(downloadKey);                            }                        });                    }                });                emitterTransform.setCallback(new LoadBitmap(ion, downloadKey, !hasTransforms, resizeWidth, resizeHeight, animateGif, emitterTransform));            }            else {//                System.out.println("downloading file for deepZoom");                File file = fileCache.getTempFile();                IonRequestBuilder.EmitterTransform<File> emitterTransform = builder.write(file);                LoadDeepZoom loadDeepZoom = new LoadDeepZoom(ion, downloadKey, animateGif, emitterTransform, fileCache) {                    @Override                    public void onCompleted(Exception e, File file) {                        super.onCompleted(e, file);                    }                };                emitterTransform.setCallback(loadDeepZoom);            }        }        executeTransforms(ion);    }}
0 0
原创粉丝点击