自定義Retrofit轉化器Converter

咱們來看一下Retrofit的使用

interface TestConn {       
    //這裏的Bitmap就是要處理的類型   @GET("https://ss0.baidu.com/73F1bjeh1BF3odCf/it/u=2537069448,2929136489&fm=85&s=85B8ED321DD844CA4EED10DE000070B1")
        Call<Bitmap> getString();
    }
Retrofit  retrofit = new Retrofit.Builder()
                .baseUrl("https://www.baidu.com/")              .addConverterFactory(ScalarsConverterFactory.create())               .addConverterFactory(BitMapCoverterFactory.create())
                .build();

ScalarsConverterFactory 就是一個轉化器 支持轉爲字符串 也就是說處理類型爲String
BitMapCoverterFactory 這是我自定義的一個轉化器 能夠轉換爲Bitmap對象(處理類型爲Bitmap)php

這裏有個坑 addConverterFactory 順序很重要 假設ScalarsConverterFactory(在上面的代碼中第一個add的) 也能夠處理Bitmap的話那麼 第二個BitMapCoverterFactory 並不會調用,除非ScalarsConverterFactory 返回nulljava

咱們要作的就是寫一個BitMapCoverterFactory ruby

教程

  1. 咱們先來導入Retrofit的依賴bash

    compile 'com.squareup.retrofit2:retrofit:2.1.0'
  2. 建立一個類而且繼承Converter.Factory 類
    咱們來看一下這個類markdown

    abstract class Factory {
            //從名字就能夠看到這個是請求後調用
        public Converter<ResponseBody, ?> responseBodyConverter(Type type, Annotation[] annotations,
            Retrofit retrofit) {
          return null;
        }
    
        //從名字就能夠看到這個是請求前調用
        public Converter<?, RequestBody> requestBodyConverter(Type type,
            Annotation[] parameterAnnotations, Annotation[] methodAnnotations, Retrofit retrofit) {
          return null;
        }
    
            //因爲不經常使用因此這裏介紹
        public Converter<?, String> stringConverter(Type type, Annotation[] annotations,
            Retrofit retrofit) {
          return null;
        }
      }

    來看看咱們代碼網絡

    static class BitMapCoverterFactory extends Converter.Factory {
            @Override
            //方法爲網絡調用後 使用
            public Converter<ResponseBody, ?> responseBodyConverter(Type type, Annotation[] annotations, Retrofit retrofit) {
                //若是出類型爲Bitmap 那麼就處理用UserResponseConverter 類處理
                // 咱們稍後再看這個類
                //若是不爲這個處理類那麼返回空交給另外一個轉化器處理
                if (type == Bitmap.class)
                    return new UserResponseConverter(type);
                return null;
            }
    
            private static BitMapCoverterFactory bitMapCoverterFactory;
    
            static BitMapCoverterFactory create() {
    
                if (bitMapCoverterFactory == null) {
                    bitMapCoverterFactory = new BitMapCoverterFactory();
                }
                return bitMapCoverterFactory;
            }
    
            private BitMapCoverterFactory() {
    
            }
        }
  3. 編寫處理邏輯類 這個類必須實現Converter
//返回處理結果
@Override
        public T convert(ResponseBody responseBody) throws IOException {
            return null ;
        }

來結合上面的代碼看下框架

public static class UserResponseConverter<T> implements Converter<ResponseBody, T> {
        private Type type;

        public UserResponseConverter(Type type) {
            this.type = type;
        }

        @Override
        public T convert(ResponseBody responseBody) throws IOException {
            byte[] bytes = responseBody.bytes();
            Bitmap bitmap = BitmapFactory.decodeByteArray(bytes, 0, bytes.length);
            return (T) bitmap;
        }
    }

最終代碼: //註解你們能夠不用看懂 若是想了解的話註解的使用和本身寫一個框架ide

//用註解完成佈局填充
@FmyContentView(R.layout.activity_main)
public class MainActivity extends AppCompatActivity {
    //用註解 完成實例化
    @FmyViewView(R.id.iv)
    ImageView iv;

    public static class UserResponseConverter<T> implements Converter<ResponseBody, T> {
        private Type type;

        public UserResponseConverter(Type type) {
            this.type = type;
        }

        @Override
        public T convert(ResponseBody responseBody) throws IOException {
            byte[] bytes = responseBody.bytes();
            Bitmap bitmap = BitmapFactory.decodeByteArray(bytes, 0, bytes.length);
            return (T) bitmap;
        }
    }


    static class BitMapCoverterFactory extends Converter.Factory {
        @Override
        //方法爲網絡調用後 使用
        public Converter<ResponseBody, ?> responseBodyConverter(Type type, Annotation[] annotations, Retrofit retrofit) {
            //若是出類型爲Bitmap 那麼就處理用UserResponseConverter 類處理
            // 咱們稍後再看這個類
            //若是不爲這個處理類那麼返回空交給另外一個轉化器處理
            if (type == Bitmap.class)
                return new UserResponseConverter(type);
            return null;
        }

        private static BitMapCoverterFactory bitMapCoverterFactory;

        static BitMapCoverterFactory create() {

            if (bitMapCoverterFactory == null) {
                bitMapCoverterFactory = new BitMapCoverterFactory();
            }
            return bitMapCoverterFactory;
        }

        private BitMapCoverterFactory() {

        }
    }

    private Retrofit retrofit;
    private TestConn testConn;
    private static final String TAG = "MainActivity";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //初始化註解
         FmyViewInject.inject(this);

        Retrofit  retrofit = new Retrofit.Builder()
                .baseUrl("https://www.baidu.com/")
                .addConverterFactory(ScalarsConverterFactory.create())
                .addConverterFactory(BitMapCoverterFactory.create())
                .build();
        testConn = retrofit.create(TestConn.class);
        testConn.getString().enqueue(new Callback<Bitmap>() {
            @Override
            public void onResponse(Call<Bitmap> call, Response<Bitmap> response) {
                   iv.setImageBitmap(response.body());
            }

            @Override
            public void onFailure(Call<Bitmap> call, Throwable t) {

            }
        });

    }

    interface TestConn {

        @GET("https://ss0.baidu.com/73F1bjeh1BF3odCf/it/u=2537069448,2929136489&fm=85&s=85B8ED321DD844CA4EED10DE000070B1")
        Call<Bitmap> getString();
    }
}

心得

其實若是你不是用轉化器也能夠的
處理類型爲ResponseBody也是能夠的 當網絡訪問結束後自行處理便可佈局

interface TestConn {      @GET("https://ss0.baidu.com/73F1bjeh1BF3odCf/it/u=2537069448,2929136489&fm=85&s=85B8ED321DD844CA4EED10DE000070B1")
        Call<ResponseBody> getString();
    }
相關文章
相關標籤/搜索