OKHTTP 学习总结

来源:互联网 发布:ammo.js 编辑:程序博客网 时间:2024/06/06 02:25

首先说下OkHttp3是Java和Android都能用,Android还有一个著名网络库叫Volley,那个只有Android能用。

导入库支持

gradle方式:会自动下载两个库OkHttp和Okio库

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

同步和异步

支持同步和异步的方式,总结同步方式call.execute(); 异步方式 call.enqueue

从android4以后规定了所有的网络请求不能在主线程执行,因此,以下方式的操作直接会crash,提示在主线程进行了操作

private void sendRequestWithOkHttp() {    try {        //create okhttpclient instance        OkHttpClient client = new OkHttpClient();        //create request object for send request        Request request = new Request.Builder()                .url("https://www.baidu.com")                .build();        //create call object and send request and finally get response        Response response = client.newCall(request).execute();        String responseData = response.body().string();        showResponse(responseData);    } catch (Exception e) {        Toast.makeText(this, e.toString(), Toast.LENGTH_SHORT).show();        e.printStackTrace();    }}

post是一样的,同样会报错,如何解决这一问题呢?创建新的线程,在子线程中执行对应的代码

private void sendSynThreadRequestWithOkHttp() {    new Thread(new Runnable() {        @Override        public void run() {            try {                //create okhttpclient instance                OkHttpClient client = new OkHttpClient();                //create request object for send request                Request request = new Request.Builder()                        .url("https://www.baidu.com")                        .build();                //create call object and send request and finally get response                Response response = client.newCall(request).execute();                String responseData = response.body().string();                showResponse(responseData);            } catch (Exception e) {                e.printStackTrace();            }        }    }    ).start();}


private void sendSynPostThreadRequest() {    new Thread(new Runnable() {        @Override        public void run() {            try {                OkHttpClient okHttpClient = new OkHttpClient();                RequestBody body = new FormBody.Builder()                        .add("key", "value")                        .add("key", "value")                        .build();                Request request = new Request.Builder()                        .url("https://www.baidu.com")                        .post(body)                        .build();                Call call = okHttpClient.newCall(request);                try {                    Response response = call.execute();                    String responseData = response.body().string();                    showResponse(responseData);                } catch (Exception e) {                    e.printStackTrace();                }            } catch (Exception e) {                e.printStackTrace();            }        }    }).start();}


异步的请求如下:get

private void sendAsynGetRequestWithOkHttp() {    OkHttpClient client = new OkHttpClient();    Request request = new Request.Builder()            .url("https://www.baidu.com")            .build();    Call call = client.newCall(request);    call.enqueue(new Callback() {        @Override        public void onFailure(Call call, IOException e) {            if (Looper.getMainLooper().getThread() == Thread.currentThread()) {                Log.d("MainActivity", "Main Thread");            } else {                Log.d("MainActivity", "Not Main Thread");            }        }        @Override        public void onResponse(Call call, final Response response) throws IOException {            string = response.body().string(); //注意            if (Looper.getMainLooper().getThread() == Thread.currentThread()) {                Log.d("MainActivity", "Main Thread");            } else {                Log.d("MainActivity", "Not Main Thread");                MainActivity.this.runOnUiThread(new Runnable() { //注意                    @Override                    public void run() {                        try {                            showResponse(string);                        } catch (Exception e) {                            e.printStackTrace();                        }                    }                });            }        }    });}

注意:异步请求处理中,会发现回调方法并不是在主线程中执行的,如果想刷新页面,就需要切换到主线程来执行。这里采用了MainActivity.this.runOnUiThread的方式。

但是与此同时,会发现运行报错,提示在主线程中执行了操作,为什么呢?因为原来的 String string = response.body().string();写在了showResponse一起,其他这是获取网络数据的,被认为网络操作在主线程进行了操作,依然不对。因此,就需要在主线程外执行。继续报错,不是final变量,于是这里将string声明成了成员变量,private String string;

private void showResponse(final String response) {    runOnUiThread(new Runnable() {        @Override        public void run() {            responstText.setText(response);        }    });}

Get 和 Post

post主要最大的区别是添加了RequestBody来设置需要传递的键值对儿