zoukankan      html  css  js  c++  java
  • 自定义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)

    这里有个坑 addConverterFactory 顺序很重要 假设ScalarsConverterFactory(在上面的代码中第一个add的) 也可以处理Bitmap的话那么 第二个BitMapCoverterFactory 并不会调用,除非ScalarsConverterFactory 返回null

    我们要做的就是写一个BitMapCoverterFactory

    教程

    1. 我们先来导入Retrofit的依赖

          compile 'com.squareup.retrofit2:retrofit:2.1.0'
    2. 创建一个类并且继承Converter.Factory 类
      我们来看一下这个类

      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;
            }
        }

    最终代码: //注解大家可以不用看懂 如果想了解的话注解的使用和自己写一个框架

    //用注解完成布局填充
    @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();
        }
  • 相关阅读:
    Java知识回顾 (2) Java 修饰符
    SpringMVC和Springboot的区别
    VS Supercharger插件的破解
    Spring3.1新属性管理API:PropertySource、Environment、Profile
    如何进行接口测试
    commons-lang3中DateUtils类方法介绍
    springCloud com.sun.jersey.api.client.ClientHandlerException: java.net.ConnectException: Connection refused: connect
    rabbitmq 连接报错 An unexpected connection driver error occured
    rabbitmq的安装与使用
    mysql5.7 mysql库下面的user表没有password字段无法修改密码
  • 原文地址:https://www.cnblogs.com/muyuge/p/6152096.html
Copyright © 2011-2022 走看看