OKHTTP 学习总结

首先说下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来设置需要传递的键值对儿


阅读更多
个人分类: android开发
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

加入CSDN,享受更精准的内容推荐,与500万程序员共同成长!
关闭
关闭