Android网络请求三方库OkHttp,Retrofit的使用,及其注解使用的简介

工作内容:

1.OkHttp的Post,Get请求

2.Retrofit的使用【更多详情可以参考

学习分享:[代码中使用了ButterKnife,参考ButterKnife使用]

1.OkHttp的使用步骤【注意同步加载最好放入子线程中:同步加载call.execute,异步加载call.enqueue】

使用OkHttp注意:

1.同步加载最好放入子线程中(网络请求很可能耗时过长导致出错)

2.一个onResponse方法中response.body().string()只能使用一次(可以定义1个String变量接受它的值,重复使用)

① 添加依赖

compile 'com.squareup.okhttp3:okhttp:3.4.1'

② 使用步骤如下:

1.定义规范接口

import okhttp3.Call;

/**
 * Created by Administrator on 2016/9/27.
 * 接口:用于规范OkHttp请求的方法
 */
public interface MyOkHttpCall {
    //获取历史上的今天的信息
    Call getHistoryTodayInfoOnPost(String string);
    //获取天气接口
    Call getWeatherOnGet();
}

2.定义OkHttp工具类

import okhttp3.Call;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.logging.HttpLoggingInterceptor;
import retrodemo.liu.com.retrofitdemo.interface_.MyOkHttpCall;

/**
 * Created by Administrator on 2016/9/27.
 * 使用单列模式写OkHttp的网络请求工具类
 * 实现接口
 */
public class RequestOnOKHttpUtil implements MyOkHttpCall {
    private final String urlHostory = "http://api.avatardata.cn/GuoNeiNews/Query";//接口(不含参数)
    private final String urlWeather = "http://api.avatardata.cn/Weather/Query?" +
            "key=615dcc76298a44329b8db1896852b0cb&cityname=成都";//天气接口(含参数)
    private OkHttpClient okHttpClient;
    private static RequestOnOKHttpUtil requestOnOKHttp = null;
    public static RequestOnOKHttpUtil getInstance(){
        if(requestOnOKHttp == null){
            requestOnOKHttp = new RequestOnOKHttpUtil();
        }
        return requestOnOKHttp;
    }
    private RequestOnOKHttpUtil(){
        HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
        interceptor.setLevel(HttpLoggingInterceptor.Level.BASIC);
        //添加拦截器(用于打印请求字段[包括请求头,请求体等信息])
        okHttpClient = new OkHttpClient.Builder()
                .addInterceptor(interceptor)
                .build();
    }

    /**
     * OkHttp--Post方式请求数据
     * Post请求时需要特别注意请求参数
     * @param Parms
     * @return
     */
    @Override
    public Call getHistoryTodayInfoOnPost(String Parms) {
        String requestParms = "key=1dc41caa4c454d48a00e5f970c9fdfcb&page=1&rows=10";
        RequestBody requestBody = RequestBody.create(null,requestParms);
        Request request = new Request.Builder()
                .url(urlHostory)
                .post(requestBody) //post方式请求数据,requestBody是请求体
                .build();
        Call call = okHttpClient.newCall(request);
        return call;
    }
    /**
     * OkHttp--Get方式获取天气数据
     * Get请求时url中填入完整的请求地址+请求参数
     */
    @Override
    public Call getWeatherOnGet() {
        Request request = new Request.Builder()
                .url(urlWeather)
                .get()  //get方式请求数据
                .build();
        Call call = okHttpClient.newCall(request);
        return call;
    }
}

OkHttp_Post请求方式的RequestBody获取方式(老版本)

RequestBody formBody = new FormEncodingBuilder()//老版本获取ResquestBody的方式
    .add("name", "Cuber")
    .add("age", "26")
    .build();

Request request = new Request.Builder()
      .url(url)
      .post(RequestBody)
      .build();</span>

OkHttp_Post请求方式的RequestBody获取方式(新版本)

//新版本的请求体获取方式
        FormBody body= new FormBody.Builder()
                .add("menu","土豆")
                .add("key","08b127d3d67bc05a617fe7aebf1d9670")
                .build();
        request = new Request.Builder()
                .post(body)
                .url(baseUrl)
                .build();
        return client.newCall(request);

3.Callback后台转前台执行

import android.os.Handler;
import android.os.Looper;
import java.io.IOException;
import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.Response;

/**
 * Created by Administrator on 2016/9/27.
 * Callback的onFailure,onPosnse方法都是在后台线程执行
 * 这里使用Handler将后台执行转成Ui主线程执行
 */
public abstract class MyOkHttpCallback implements Callback {
    //Looper.getMainLooper()表示放到主UI线程去处理,不添加表示在当前线程处理
    private Handler handler = new Handler(Looper.getMainLooper());
    @Override
    public void onFailure(final Call call, final IOException e) {
        handler.post(new Runnable() {
            @Override
            public void run() {
                uiThreadDoOnFailure(call,e);
            }
        });
    }

    @Override
    public void onResponse(final Call call,final Response response) throws IOException {
        handler.post(new Runnable() {
            @Override
            public void run() {
                uiThreadDoOnResponse(call,response);
            }
        });
    }
    public abstract void uiThreadDoOnFailure(Call call, IOException e);
    public abstract void uiThreadDoOnResponse(Call call, Response response);
}

3.调用工具类的方法(activity代码)

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.widget.Toast;
import com.google.gson.Gson;
import java.io.IOException;
import java.util.List;
import butterknife.ButterKnife;
import okhttp3.Call;
import okhttp3.Response;
import retrodemo.liu.com.retrofitdemo.interface_.MyOkHttpCallback;
import retrodemo.liu.com.retrofitdemo.requestutil.RequestOnOKHttpUtil;

public class OkHttpActivity extends AppCompatActivity {
    private int pages = 1;
    private Gson gson = new Gson();
    private List<NewsInfo.ShowapiResBodyBean.PagebeanBean.ContentlistBean> list;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_ok_http);
        ButterKnife.bind(this);
        requestOnPost();
        requestOnGet();
    }

    //天气数据Okhttp_get
    private void requestOnGet() {
        Call call = RequestOnOKHttpUtil.getInstance().getWeatherOnGet();
        /**
         * 异步加载
         * 请求加入调度
         * 同步加载方法:call.execute();会抛出IO异常
         */
        call.enqueue(new MyOkHttpCallback() {
            @Override
            public void uiThreadDoOnFailure(Call call, IOException e) {
                Log.e("___测试___Get_OnFailure", "Get_OnFailure");
            }

            @Override
            public void uiThreadDoOnResponse(Call call, Response response) {
                try {
                    Log.e("___测试___Get_onResponce", response.body().string());
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        });
    }

    //历史上的今天OkHttp-post
    private void requestOnPost() {
        String parms = "yue=8&ri=28&type=1&page=1&rows=10";
        Call call = RequestOnOKHttpUtil.getInstance().getHistoryTodayInfoOnPost(parms);
        /**
         * 异步加载
         * 请求加入调度
         */
        call.enqueue(new MyOkHttpCallback() {
            @Override
            public void uiThreadDoOnFailure(Call call, IOException e) {
                Toast.makeText(OkHttpActivity.this, "uiThreadDoOnFailure_Post", Toast.LENGTH_SHORT).show();
            }

            @Override
            public void uiThreadDoOnResponse(Call call, Response response) {
                try {
                    Log.e("___测试___Post", response.body().string());
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        });
    }
}

③ 结果演示


2.Retrofit的常规使用【附带上注解的使用简介】

① 导包:/添加依赖【编程工具Android studio】

compile 'com.squareup.retrofit2:retrofit:2.1.0'
compile 'com.squareup.retrofit2:converter-gson:2.1.0'

② 创建请求接口【配置请求参数】

import android.support.annotation.Nullable;
import okhttp3.ResponseBody;
import retrofit2.Call;
import retrofit2.http.GET;
import retrofit2.http.Headers;
import retrofit2.http.POST;
import retrofit2.http.Path;
import retrofit2.http.Query;

/**
 * Created by Administrator on 2016/9/28.
 */
public interface RetrofitCall {
    //retrofit-getFruit
    @GET("/cook/query?key=08b127d3d67bc05a617fe7aebf1d9670" +
            "&menu=土豆&rn=10&pn=3")
    Call<ResponseBody>
    getFruit();

    //retrofit-postFruit
    @POST("/cook/query.php")
//    @Headers("content-type:json") //添加头信息固态,放入参数中则变成动态添加
    Call<ResponseBody>
    postFruit(@Query("key") String key
            , @Query("menu") String menu
            , @Nullable @Query("rn") String rn
            , @Nullable @Query("pn") String pn);

    //okhttp-get
    okhttp3.Call getFruitOkHttp();
    //okhttp-post
    okhttp3.Call postFruitOkHttp();
}
/**
 * 注解说明(Retrofit请求)
 * @GET @POST是请求方式
 * @Header 添加头信息
 *
 * 参数部分使用下列注解
 * @Path 表示替换【必填】
     * 例:
     * @GET("book/{id}")
     * Call<BookResponse> getBook(@Path("id") String id);
 * @Query 表示可选部分【非必填】代码中有用到,这里就不举例了
 * @QueryMap map<String str> options 表示map形式传递可选参数
     * 例:
     * @GET("book/search")
     * Call<BookSearchResponse> getSearchBooks(@QueryMap Map<String, String> options);
 * @field表单方式提交
     *      * @FormUrlEncoded
     * @POST("book/reviews")
     * Call<String> addReviews(@Field("book") String bookId, @Field("title") String title,
     * @Field("content") String content, @Field("rating") String rating);
 * @FieldMap 与上面类似只是变成了map
     *例:
     * @FormUrlEncoded
     * @POST("book/reviews")
     * Call<String> addReviews(@FieldMap Map<String, String> fields);
 * @Body 请求参数有多个,那么统一封装到类中应该会更好,
     * ;
     * @FormUrlEncoded
     * @POST("book/reviews")
     * Call<String> addReviews(@Body Reviews reviews);
     * public class Reviews {
     * public String book;
     * public String title;
     * public String content;
     * public String rating;
     * }
 * 还有一个多部分(比较少用)
 */

③ 创建业务类【处理网络请求】

import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.ResponseBody;
import okhttp3.logging.HttpLoggingInterceptor;
import online.liu.com.onlinedemo.inter.RetrofitCall;
import online.liu.com.onlinedemo.obj.User;
import online.liu.com.onlinedemo.obj.UserResult;
import retrofit2.Call;
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;
import retrofit2.http.Body;
import retrofit2.http.Query;

/**
 * Created by Administrator on 2016/9/28.
 */
public class RequestUtil implements RetrofitCall{
    private static RequestUtil requestUtil = null;
    private OkHttpClient client = null;
    private RetrofitCall retrofitCall;
    private String Base_postUrl = "http://admin.syfeicuiedu.com";
    private String Base_fruitUrl = "http://apis.juhe.cn";
    private String Base_fruitUrl_okhttpGet = "http://apis.juhe.cn/cook/query?" +
            "key=08b127d3d67bc05a617fe7aebf1d9670" +
            "&menu=土豆&rn=10&pn=3";
    private String Base_fruitUrl_okhttpPost = "http://apis.juhe.cn/cook/query";
    //单例模式
    public static RequestUtil getInstance(){
        if(requestUtil == null){
            requestUtil = new RequestUtil();
        }
        return requestUtil;
    }
    //构造函数
    private RequestUtil(){
        final HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
        interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
        client = new OkHttpClient.Builder()
                .addInterceptor(interceptor)    //添加拦截器【Log.d方式打印请求信息】
                .build();
    }

    //retrofit-Get
    @Override
    public Call<ResponseBody> getFruitData() {
        Retrofit retrofit = new Retrofit.Builder()
                .client(client)
                .baseUrl(Base_fruitUrl)
                //添加Gson转换器,将返回Json字符串转换成实体类
                .addConverterFactory(GsonConverterFactory.create())
                .build();
        retrofitCall = retrofit.create(RetrofitCall.class);
        return retrofitCall.getFruitData();
    }
    //retrofit-Post-login
    @Override
    public Call<UserResult> postData(@Body User user) {
        Retrofit retrofit = new Retrofit.Builder()
                .client(client)
                .addConverterFactory(GsonConverterFactory.create())
                .baseUrl(Base_postUrl)
                .build();
        retrofitCall = retrofit.create(RetrofitCall.class);
        return retrofitCall.postData(user);
    }
    //retrofit-Post-fruit
    @Override
    public Call<ResponseBody> postFruit(@Query("key") String key, @Query("menu") String menu, @Query("rn") int rn, @Query("pn") int pn) {
        Retrofit retrofit = new Retrofit.Builder()
                .client(client)
                .addConverterFactory(GsonConverterFactory.create())
                .baseUrl(Base_fruitUrl)
                .build();
        retrofitCall = retrofit.create(RetrofitCall.class);
        return retrofitCall.postFruit(key,menu,rn,pn);
    }
    //okhttp-get-fruit
    @Override
    public okhttp3.Call getFruitOkHttp() {
        Request request = new Request.Builder()
                .url(Base_fruitUrl_okhttpGet)
                .get()
                .build();
        return client.newCall(request);
    }
    //okhttp-post-fruit
    @Override
    public okhttp3.Call postFruitOkHttp() {
        RequestBody requestBody = RequestBody.create(null,"key=08b127d3d67bc05a617fe7aebf1d9670&menu=土豆&rn=10&pn=3");
        Request request = new Request.Builder()
                .url(Base_fruitUrl_okhttpPost)
                .post(requestBody)
                .build();
        return client.newCall(request);
    }
}

④ Presender类【这里没有写这处理类,直接写在了Activity中】

mport android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Toast;
import com.google.gson.Gson;
import java.io.IOException;
import java.util.List;
import butterknife.ButterKnife;
import butterknife.OnClick;
import okhttp3.ResponseBody;
import online.liu.com.onlinedemo.R;
import online.liu.com.onlinedemo.conn.RequestUtil;
import online.liu.com.onlinedemo.obj.Friut;
import online.liu.com.onlinedemo.obj.User;
import online.liu.com.onlinedemo.obj.UserResult;
import online.liu.com.onlinedemo.tools.LogTool;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;

/**
 * Activity类
 * 任务:
 * 点击按钮,通过下列的方式去请求网络数据()
 * 1.OKHttp_get
 * 2.OKHttp_post
 * 3.Retrofit_get
 * 4.Retrofit_post
 */
public class FruitActivity extends AppCompatActivity {
    private Gson gson = new Gson();
    private RequestUtil requestUtil;
    private List<Friut.ResultBean.DataBean> list;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_fruit);
        ButterKnife.bind(this);
        requestUtil = RequestUtil.getInstance();
    }

    private void postFruitOnRetrofit() {
        requestUtil.postFruit("08b127d3d67bc05a617fe7aebf1d9670", "土豆", 10, 3).enqueue(new Callback<ResponseBody>() {
            @Override
            public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
                Toast.makeText(FruitActivity.this, "PostFruitOnRetrofit_onResponse应成功", Toast.LENGTH_SHORT).show();
                LogTool.e("PostFruitOnRetrofit_onResponse响应成功");
                try {
                    LogTool.e("postFruit_OnRetrofit_onResponse:" + response.body().string());
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

            @Override
            public void onFailure(Call<ResponseBody> call, Throwable t) {
                LogTool.e("postFruit_OnRetrofit_onFailure");
                Toast.makeText(FruitActivity.this, "postFruit_OnRetrofit_onFailure", Toast.LENGTH_SHORT).show();
            }
        });
    }

    private void getFruitOnRetrofit() {
        requestUtil.getFruitData().enqueue(new Callback<ResponseBody>() {
            @Override
            public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
                Toast.makeText(FruitActivity.this, "getDataOnRetrofit_onResponse", Toast.LENGTH_SHORT).show();
                LogTool.e("getDataOnRetrofit_onResponse响应成功");
                try {
                    LogTool.e("getDataOnRetrofit_onResponse:" + response.body().string());
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

            @Override
            public void onFailure(Call<ResponseBody> call, Throwable t) {
                LogTool.e("getDataOnRetrofit_onFailure");
                Toast.makeText(FruitActivity.this, "getDataOnRetrofit_onFailure", Toast.LENGTH_SHORT).show();
            }
        });
    }
    //常用于账号/密码验证
    private void postDataOnRetrofit() {
        requestUtil.postData(new User("zhang", "123")).enqueue(new Callback<UserResult>() {
            @Override
            public void onResponse(Call<UserResult> call, Response<UserResult> response) {
                LogTool.e("响应成功");
                UserResult userResult = response.body();
                LogTool.e("postDataOnRetrofit_onResponse:" + userResult.getErrmsg());
                Toast.makeText(FruitActivity.this, "postDataOnRetrofit_onResponse", Toast.LENGTH_SHORT).show();
            }

            @Override
            public void onFailure(Call<UserResult> call, Throwable t) {
                LogTool.e("postDataOnRetrofit_onFailure");
                Toast.makeText(FruitActivity.this, "postDataOnRetrofit_onFailure", Toast.LENGTH_SHORT).show();
            }
        });
    }

    private void getFruitOnOkHttp() {
        requestUtil.getFruitOkHttp().enqueue(new okhttp3.Callback() {
            @Override
            public void onFailure(okhttp3.Call call, IOException e) {
                LogTool.e("getFruitOnOkHttp_onFailure");
            }

            @Override
            public void onResponse(okhttp3.Call call, okhttp3.Response response) throws IOException {
                LogTool.e("getFruitOnOkHttp_onResponse" + response.body().string());
            }
        });
    }

    private void postFruitOnOkHttp() {
        requestUtil.postFruitOkHttp().enqueue(new okhttp3.Callback() {
            @Override
            public void onFailure(okhttp3.Call call, IOException e) {
                LogTool.e("postFruitOnOkHttp_onFailure");
            }

            @Override
            public void onResponse(okhttp3.Call call, okhttp3.Response response) throws IOException {
                LogTool.e("postFruitOnOkHttp_onResponse" + response.body().string());
            }
        });
    }

    @OnClick({R.id.Okhttp_get, R.id.Okhttp_post, R.id.retrofit_get, R.id.retrofit_post})
    public void onClick(View view) {
        switch (view.getId()) {
            case R.id.Okhttp_get:
                getFruitOnOkHttp();
                break;
            case R.id.Okhttp_post:
                postFruitOnOkHttp();
                break;
            case R.id.retrofit_get:
                getFruitOnRetrofit();
                break;
            case R.id.retrofit_post:
                postFruitOnRetrofit();
//                postDataOnRetrofit();
                break;
        }
    }
}

⑤  执行效果


  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值