alwaystest / Blog

24 stars 2 forks source link

第一行代码 网络编程实践 个人浅见 #4

Open alwaystest opened 8 years ago

alwaystest commented 8 years ago

第一行代码 网络编程实践 浅见

标签(空格分隔): 未分类


书上是这么写的:

在sendHttpRequest()方法中开启了一个线程来发起HTTP请求,服务器响应的数据是无法进行返回的。……。sendHttpRequest()方法会在服务器还没来得及响应的时候就执行结束。……。解决方法只需要使用Java的回调机制就可以了。

这里就把我弄糊涂了,添加了一个回调的函数也不会引起哪里阻塞,怎么会这么说呢? 写代码验证。

package com.software.eric.coolweather.util;

import android.util.Log;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;

/**
 * Created by Mzz on 2015/10/29.
 */
public class HttpUtil {
    public static void sendHttpRequest(final String address, final HttpCallbackListener listener){
        new Thread(new Runnable() {
            @Override
            public void run() {
                HttpURLConnection connection = null;
                try{
                    URL url = new URL(address);
                    connection = (HttpURLConnection) url.openConnection();
                    connection.setRequestMethod("GET");
                    connection.setConnectTimeout(8000);
                    connection.setReadTimeout(8000);
                    InputStream in = connection.getInputStream();
                    BufferedReader reader = new BufferedReader(new InputStreamReader(in));
                    StringBuilder response = new StringBuilder();
                    String line;
                    while((line = reader.readLine()) != null){
                        response.append(line);
                    }
                    Log.i("weather", response.toString());
                    if(listener != null){
                        listener.onFinish(response.toString());
                    }
                } catch (Exception e) {
                    if(listener != null)
                        listener.onError(e);
                } finally {
                    if(connection != null){
                        connection.disconnect();
                    }
                }
            }
        }).start();
    }
}

listener.onFinish中,继续Log.i("weather", response.toString());

而运行的结果中输出了两遍Log信息。

而将if(listener != null)代码段注释掉以后,依然可以有一遍Log输出,所以服务器响应是可以收到的。

我觉得作者想表达的意思是此处获得的数据不能返回到主线程中,从而不能直接利用服务器返回的数据。

而此处使用监听器的好处是不必将数据处理编码到util类中,使用起来更加灵活。

个人浅见,欢迎指教。

luffykou commented 8 years ago

这里就把我弄糊涂了,添加了一个回调的函数也不会引起哪里阻塞,怎么会这么说呢?

因为在sendHttpRequest中开启了子线程,添加的这个回调函数就在子线程中,自然不会阻塞。

ps.这里说的阻塞是指阻塞主线程(UI Thread)

alwaystest commented 8 years ago

@luffykou 不好意思,是我没有表达清楚。在这本书的406页,作者在这里使用sendHttpRequest()开启子线程来进行网络请求,想要通过回调的方式处理服务器的响应。 如果在主线程中直接调用HttpUtil.sengHttpRequest(),网络请求是在子线程中发生的,主线程在开启了子线程以后继续往下走,不会阻塞线程等待服务器响应,所以无法处理服务器的响应。 所以我这里说

我觉得作者想表达的意思是此处获得的数据不能返回到主线程中,从而不能(在主线程中)直接利用服务器返回的数据。

原文中是这么写的

sendHttpRequest()方法会在服务器还没来得及响应的时候就执行结束了。

我看书的时候理解为添加了回调函数,就会使sendHttpRequest()方法`等待服务器响应再继续执行。

现在知道回调机制是怎么一回事了。多谢帮助:-D