Retrofit使用案例、源码简析

Retrofit

(a type-safe HTTP client for Android and Java) HTTP网络请求工具

Retrofit使用步骤

1.定义一个接口(封装url地址和数据请求)
2.实例化Retrofit
3.调用Retrofit实例创建接口服务对象
4.接口服务对象调用接口中的方法获取Call对象
5.call对象执行请求(异步、同步请求)

封装url地址和数据请求的接口类

public interface INewsBiz {
    /*
    通过@GET注解标示为get请求 @GET中填写的value和baseUrl指定的地址组成完成的访问路径
    baseUrl构造retrofit对象时指定
    */
    @GET("api/GetFeeds?column=0&PageSize=20&pageIndex=1&val=100511D3BE5301280E0992C73A9DEC41")
    Call<ResponseBody> getResonsebody();

    @GET("api/GetFeeds?column=0&PageSize=20&pageIndex=1&val=100511D3BE5301280E0992C73A9DEC41")
    Call<String> getJsonString();

    @GET("category?app_id=161")
    Call<List<Tea>> getTeas();

    @GET("api/{type}?column=0&PageSize=20&pageIndex=1&val=100511D3BE5301280E0992C73A9DEC41")
    Call<NewsInfo> getNewsInfo(@Path("type") String type);//String type="GetFeeds"

    //http://42.120.4.67/api/app/business/category?app_id=161
    @GET("category")
    Call<List<Tea>> getTeaByNetWork(@Query("app_id") int id);//int id=161

    //api/GetFeeds?column=0&PageSize=20&pageIndex=1&val=100511D3BE5301280E0992C73A9DEC41
    @GET("api/GetFeeds")
    Call<NewsInfo> getInfo(@QueryMap Map<String,String> map);

//    @GET("api/{type}")
//    Call<NewsInfo> getInfo(@Path("type") String type,@QueryMap Map<String,String> map);

    //网络上下载文件
    @GET("download")
     Call<ResponseBody> downLoad();

    //post请求中通过@FormUrlEncoded和@POST注解 指明访问的地址  @Field("向服务器提交的key")
    @POST("LoginServlet")//采用post请求方式
    @FormUrlEncoded  //表单提交
    Call<String> login(@Field("username") String username,
                       @Field("password") String password);
}

activity中具体使用

public class MainActivity extends AppCompatActivity {
    private TextView tv;
    private ImageView iv;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        tv= (TextView) findViewById(R.id.tv);
        iv= (ImageView) findViewById(R.id.iv);
//        initRetrofit01();
//        initRetrofit02();
//        initRetrofit03();
//        initRetrofit04();
//        initRetrofit05();
//        initRetrofit06();
//        initRetrofit07();
        initRetrofit08();
    }

    /**
     *  采用同步访问的方式 excute()
     */
    public void initRetrofit08(){
        Retrofit retrofit=new Retrofit
                .Builder()
                .baseUrl(Constant.BASE_URL)
                .build();
        final INewsBiz iNewsBiz=retrofit.create(INewsBiz.class);
        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    Call<ResponseBody> call=iNewsBiz.getResonsebody();
                    // 采用同步方式请求数据
                    Response<ResponseBody> response=call.execute();
                    final String str=response.body().string();
                    tv.post(new Runnable() {
                        @Override
                        public void run() {
                            tv.setText(str);
                        }
                    });
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }).start();
    }
    /**
     * 下载网络图片文件
     */
    public void initRetrofit07(){
         Retrofit retrofit=new Retrofit
                 .Builder()
                 .baseUrl(Constant.IMAGE_URL)
                 .build();
        INewsBiz iNewsBiz=retrofit.create(INewsBiz.class);
        Call<ResponseBody> call=iNewsBiz.downLoad();
        call.enqueue(new Callback<ResponseBody>() {
            @Override
            public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
                if(response.isSuccess()){
//                    String str=response.body().string();
//                    byte[] buff=response.body().bytes();
                    InputStream inputStream=response.body().byteStream();
                    Bitmap bm= BitmapFactory.decodeStream(inputStream);
                    iv.setImageBitmap(bm);
                }
            }

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

            }
        });
    }
    /**
     * get 请求通过@queryMap注解动态传递多个参数
     */
    public void initRetrofit06(){
        Retrofit retrofit=new Retrofit
                .Builder()
                .baseUrl(Constant.BASE_URL)
                .addConverterFactory(GsonConverterFactory.create())
                .build();
        INewsBiz iNewsBiz=retrofit.create(INewsBiz.class);
        //column=0&PageSize=20&pageIndex=1&val=100511D3BE5301280E0992C73A9DEC41
        //将参数根据key-value对的形式存储到map集合中
        Map<String,String> map=new HashMap<>();
        map.put("column",0+"");
        map.put("PageSize",20+"");
        map.put("pageIndex",1+"");
        map.put("val","100511D3BE5301280E0992C73A9DEC41");
        Call<NewsInfo> call=iNewsBiz.getInfo(map);
        //api/GetFeeds?column=0&PageSize=20&pageIndex=1&val=100511D3BE5301280E0992C73A9DEC41
//        Call<NewsInfo> call=iNewsBiz.getInfo("GetFeeds",map);
        call.enqueue(new Callback<NewsInfo>() {
            @Override
            public void onResponse(Call<NewsInfo> call, Response<NewsInfo> response) {
                if(response.isSuccess()){
                    List<NewsInfo.ParamzBean.FeedsBean> news=
                            response.body().getParamz().getFeeds();
                    StringBuilder sb=new StringBuilder();
                    for(NewsInfo.ParamzBean.FeedsBean feed:news){
                        sb.append(feed.getData().getSubject());
                    }
                    tv.setText(sb.toString());
                }
            }

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

            }
        });
    }

    /**
    get请求 通过@query注解动态传递参数的值
     */
    public void initRetrofit05(){
        Retrofit retrofit=new Retrofit
                .Builder()
                .baseUrl(Constant.TEABASE_URL)
                .addConverterFactory(GsonConverterFactory.create())
                .build();
        INewsBiz iNewsBiz=retrofit.create(INewsBiz.class);
        Call<List<Tea>> call=iNewsBiz.getTeaByNetWork(161);
        call.enqueue(new Callback<List<Tea>>() {
            @Override
            public void onResponse(Call<List<Tea>> call, Response<List<Tea>> response) {
                if(response.isSuccess()){
                    StringBuilder sb=new StringBuilder();
                    List<Tea> list=response.body();
                    for(Tea t:list){
                        sb.append(t.getProduct_cat_name());
                    }
                    tv.setText(sb.toString());
                }
            }

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

            }
        });
    }

    /**
     * get请求 通过占位符指定path路径
     */
    public void initRetrofit04(){
        Retrofit retrofit=new Retrofit
                .Builder()
                .baseUrl(Constant.BASE_URL)
                .addConverterFactory(GsonConverterFactory.create())
                .build();
        INewsBiz iNewsBiz=retrofit.create(INewsBiz.class);
        Call<NewsInfo> call=iNewsBiz.getNewsInfo("GetFeeds");
        call.enqueue(new Callback<NewsInfo>() {
            @Override
            public void onResponse(Call<NewsInfo> call, Response<NewsInfo> response) {
                if(response.isSuccess()){
                    List<NewsInfo.ParamzBean.FeedsBean> news=
                            response.body().getParamz().getFeeds();
                    StringBuilder sb=new StringBuilder();
                    for(NewsInfo.ParamzBean.FeedsBean feed:news){
                        sb.append(feed.getData().getSubject());
                    }
                    tv.setText(sb.toString());
                }
            }

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

            }
        });
    }
    /**
     * 普通的get请求 返回的数据为gson解析后的list集合
     */
    public void initRetrofit03(){
        Retrofit retrofit=new Retrofit
                .Builder()
                .baseUrl(Constant.TEABASE_URL)
                //如果服务器返回的时json格式数据 设置了GsonConverterFactory
                //实现对对象的转化
                // 自定义数据解析器 只要解析器继承Converter.Factory即可
                .addConverterFactory(GsonConverterFactory.create())
                .build();
        INewsBiz iNewsBiz=retrofit.create(INewsBiz.class);
        Call<List<Tea>> call=iNewsBiz.getTeas();
        call.enqueue(new Callback<List<Tea>>() {
            @Override
            public void onResponse(Call<List<Tea>> call, Response<List<Tea>> response) {
                if(response.isSuccess()){
                    List<Tea> list=response.body();//获取解析后的集合
                    StringBuilder sb=new StringBuilder();
                    for(Tea t:list){
                        sb.append(t.getProduct_cat_name());
                    }
                    tv.setText(sb.toString());
                }
            }

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

            }
        });

    }
    /**
     * 普通get请求 返回的数据为String类型
     */
    public void initRetrofit02(){
        Retrofit retrofit=new Retrofit
                .Builder()
                .baseUrl(Constant.BASE_URL)
                //设置回调时的适配器 get请求后可以返回String字符串类型的内容
                .addConverterFactory(ScalarsConverterFactory.create())
                .build();
         INewsBiz iNewsBiz=retrofit.create(INewsBiz.class);
         Call<String> call=iNewsBiz.getJsonString();
         call.enqueue(new Callback<String>() {
             @Override
             public void onResponse(Call<String> call, Response<String> response) {
                 if(response.isSuccess()){
                     tv.setText(response.body());
                 }
             }

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

             }
         });
    }
    /**
     * 普通get请求
     */
    public void initRetrofit01(){
        //构建Retrofit网络访问对象
        Retrofit retrofit=new Retrofit
                .Builder()
                .baseUrl(Constant.BASE_URL)//设置访问的跟路径
                .build();
        //根据接口的字节码文件对象获取接口的对象
        INewsBiz iNewsBiz=retrofit.create(INewsBiz.class);
        //调用接口中定义的函数
        Call<ResponseBody> call=iNewsBiz.getResonsebody();
        /*enqueue 采用异步访问数据   execute()采用同步访问数据*/
        call.enqueue(new Callback<ResponseBody>() {
            @Override
            public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
                if(response.isSuccess()){//成功的获取响应
                    try {
                        String result=response.body().string();//获取网络访问的字符串
                        tv.setText(result);
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }

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

            }
        });
    }
}

retrofit底层源码

底层使用注解反射 动态代理 okhttp访问网络

Retrofit 底层使用注解反射 动态代理

  1. Retrofit retrofit=new Retrofit.Builder().baseUrl(url).build();

源码:

public static final class Builder {
    private List<Converter.Factory> converterFactories = new ArrayList<>();
    private okhttp3.Call.Factory callFactory;
    .....
     public Builder() {
         ...
          converterFactories.add(new BuiltInConverters());
     }

     public Builder baseUrl(String baseUrl) {
           checkNotNull(baseUrl, "baseUrl == null"); //检查传递的baseUrl不能为null
           //将根路径封装成HttpUrl对象
           HttpUrl httpUrl = HttpUrl.parse(baseUrl);
           if (httpUrl == null) {
             throw new IllegalArgumentException("Illegal URL: " + baseUrl);
           }
           return baseUrl(httpUrl);
      }

      ....
      public Builder baseUrl(final HttpUrl baseUrl) {
            checkNotNull(baseUrl, "baseUrl == null");
            //检查根路径是否以/结尾
            List<String> pathSegments = baseUrl.pathSegments();
            if (!"".equals(pathSegments.get(pathSegments.size() - 1))) {
              throw new IllegalArgumentException("baseUrl must end in /: " + baseUrl);
            }
            return baseUrl(new BaseUrl() {
              @Override public HttpUrl url() {
                return baseUrl;
              }
            });
          }
     .....
       public Builder baseUrl(BaseUrl baseUrl) {
                this.baseUrl = checkNotNull(baseUrl, "baseUrl == null");
                return this;
       }

       .....

       public Retrofit build() {
            //判断根路径必须存在
             if (baseUrl == null) {
               throw new IllegalStateException("Base URL required.");
             }

             //retrofit底层采用okhttp访问网络
             okhttp3.Call.Factory callFactory = this.callFactory;
             if (callFactory == null) {
               callFactory = new OkHttpClient();
             }

             //CallAdapter.Factory 主要用于对call进行转化
             List<CallAdapter.Factory> adapterFactories = new ArrayList<>(this.adapterFactories);
             adapterFactories.add(Platform.get().defaultCallAdapterFactory(callbackExecutor));

             //Converter.Factory 主要用于转化数据
             List<Converter.Factory> converterFactories = new ArrayList<>(this.converterFactories);

                //构建retrofit对象
             return new Retrofit(callFactory, baseUrl, converterFactories, adapterFactories,
                 callbackExecutor, validateEagerly);
           }
         }
  }
///////////////////////////////////////////////////////////////////////////////////////////
2.INewsBiz iNewsBiz=retrofit.create(INewsBiz.class);


public <T> T create(final Class<T> service) {
    .....
    return (T) Proxy.newProxyInstance(service.getClassLoader(), new Class<?>[] { service },
        new InvocationHandler() {
          private final Platform platform = Platform.get();

          @Override public Object invoke(Object proxy, Method method, Object... args)
              throws Throwable {
            // If the method is a method from Object then defer to normal invocation.
            if (method.getDeclaringClass() == Object.class) {
              return method.invoke(this, args);
            }
            if (platform.isDefaultMethod(method)) {
              return platform.invokeDefaultMethod(method, service, proxy, args);
            }
            return loadMethodHandler(method).invoke(args);
          }
        });
  }

CallBack
retrofit请求数据返回的接口 onResponse() onFailure()

Call
接口主要用用就是发送Http请求 默认实现的okHttpCall

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值