第10章 网络编程

本系列学习笔记第10章

前言

打算把android基本知识点写一个系列,旨在把android基础书,例如《Android 第一行代码 第2版》、《爱上android》、《疯狂android讲义》等书的一些知识点记录一下,会持续更新内容,为了方便自己复习,也希望可以帮助到大家!

1、HTTP协议

1.1 URL简介

URL的全称是统一资源定位符,通过一个URL能找到互联网上唯一 的一个资源,URL就是资源的地址、位置。

URL的基本格式 = 协议://主机地址/路径
协议:不同的协议,代表不同资源的查找方式、资源传输方式
主机地址:存放资源的主机IP地址或者域名
路径:资源在主机中的具体位置

URL中常见的协议如下:
HTTP:超文本传输协议,访问的是远程网络资源,格式是http://
file:访问的是本机的文件资源,格式是file://
mailto:访问的是电子邮件地址,格式是mailto:
FTP:访问的是共享主机的文件资源,格式是ftp://

1.2 HTTP简介

image.png
image.png
image.png

1.3 GET与POST对比

image.png
image.png

2、WebView的用法

2.1 加载网络页面的用法

public class MainActivity extends AppCompatActivity {

    private WebView webView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        webView = (WebView) findViewById(R.id.web_view);

        WebSettings settings = webView.getSettings();

        //支持JavaScript脚本
        settings.setJavaScriptEnabled(true);

        webView.setWebViewClient(new WebViewClient());
        webView.loadUrl("http://www.baidu.com");

    }
}

2.2 加载本地静态页面的用法

首先先把html等文件放在如下的文件夹中


image.png
 webView.loadUrl("file:///android_asset/apply_notice.html");

2.3 WebView的设置用法

        //支持获取手势焦点,输入用户名、密码或其他
        webView.requestFocusFromTouch();

        //支持js,这样有潜在的安全隐患,无需要,建议关闭
        webSettings.setJavaScriptEnabled(true);

        //提高渲染的优先级,高版本废弃了。
        webSettings.setRenderPriority(WebSettings.RenderPriority.HIGH);

        //  设置自适应屏幕,两者合用
        webSettings.setUseWideViewPort(true);  //将图片调整到适合webview的大小
        webSettings.setLoadWithOverviewMode(true); // 缩放至屏幕的大小

        webSettings.setSupportZoom(true);  //支持缩放,默认为true。是下面那个的前提。
        //若下面是false,则该WebView不可缩放,这个不管设置什么都不能缩放。
        webSettings.setBuiltInZoomControls(true); //设置内置的缩放控件。


        webSettings.setDisplayZoomControls(false); //隐藏原生的缩放控件

        webSettings.setLayoutAlgorithm(WebSettings.LayoutAlgorithm.SINGLE_COLUMN); //支持内容重新布局
        webSettings.supportMultipleWindows();  //支持多窗口
        webSettings.setCacheMode(WebSettings.LOAD_CACHE_ELSE_NETWORK);  //关闭webview中缓存
        webSettings.setAllowFileAccess(true);  //设置可以访问文件
        webSettings.setNeedInitialFocus(true); //当webview调用requestFocus时为webview设置节点
        webSettings.setJavaScriptCanOpenWindowsAutomatically(true); //支持通过JS打开新窗口
        webSettings.setLoadsImagesAutomatically(true);  //支持自动加载图片
        webSettings.setDefaultTextEncodingName("utf-8");//设置编码格式


        //----缓存
        //根据网页中cache-control决定是否从网络上取数据。
        webSettings.setCacheMode(WebSettings.LOAD_DEFAULT);

        webSettings.setCacheMode(WebSettings.LOAD_CACHE_ELSE_NETWORK);//没网,则从本地获取,即离线加载


        webSettings.setDomStorageEnabled(true); // 开启 DOM storage API 功能
        webSettings.setDatabaseEnabled(true);   //开启 database storage API 功能
        webSettings.setAppCacheEnabled(true);//开启 Application Caches 功能

        String cacheDirPath = getCacheDir().getAbsolutePath();
        //设置  Application Caches 缓存目录
        //每个 Application 只调用一次 WebSettings.setAppCachePath()
        webSettings.setAppCachePath(cacheDirPath);

        //Android 5.0上 Webview 默认不允许加载 Http 与 Https 混合内容,加下下面的配置就解决了.
        webSettings.setMixedContentMode(WebSettings.MIXED_CONTENT_ALWAYS_ALLOW);

2.4 WebViewClient的介绍

WebViewClient就是帮助WebView 处理各种通知,请求事件的。

   WebViewClient mWebViewClient = new WebViewClient() {
        //在网页上的所有加载都经过这个方法,这个函数我们可以做很多操作。
        //比如获取url,查看url.contains(“add”),进行添加操作
        public boolean shouldOverrideUrlLoading(WebView view, String url) {
            view.loadUrl(url);
            return true;
        }

        // 21版本引入 同上
        @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
        @Override
        public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) {
            view.loadUrl(request.getUrl().toString());
            return true;
        }

        //这个事件就是开始载入页面调用的,我们可以设定一个loading的页面,告诉用户程序在等待网络响应。
        @Override
        public void onPageStarted(WebView view, String url, Bitmap favicon) {
            super.onPageStarted(view, url, favicon);
        }

        //在页面加载结束时调用。同样道理,我们可以关闭loading 条,切换程序动作。
        @Override
        public void onPageFinished(WebView view, String url) {
            super.onPageFinished(view, url);
        }

        // 在加载页面资源时会调用,每一个资源(比如图片)的加载都会调用一次。
        @Override
        public void onLoadResource(WebView view, String url) {
            super.onLoadResource(view, url);
        }

        // 拦截替换网络请求数据,  API 11开始引入,API 21弃用
        @Override
        public WebResourceResponse shouldInterceptRequest(WebView view, String url) {
            return super.shouldInterceptRequest(view, url);
        }

        // 拦截替换网络请求数据,  从API 21开始引入
        @Override
        public WebResourceResponse shouldInterceptRequest(WebView view, WebResourceRequest request) {
            return super.shouldInterceptRequest(view, request);
        }

        //报告错误信息 API 21 废弃
        @Override
        public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) {
            super.onReceivedError(view, errorCode, description, failingUrl);
        }

        //报告错误信息 API 21 引用
        @Override
        public void onReceivedError(WebView view, WebResourceRequest request, WebResourceError error) {
            super.onReceivedError(view, request, error);
        }

        //接收http 错误信息
        @Override
        public void onReceivedHttpError(WebView view, WebResourceRequest request, WebResourceResponse errorResponse) {
            super.onReceivedHttpError(view, request, errorResponse);
        }

        //应用程序重新请求网页数据
        @Override
        public void onFormResubmission(WebView view, Message dontResend, Message resend) {
            super.onFormResubmission(view, dontResend, resend);
        }

        //更新历史记录
        @Override
        public void doUpdateVisitedHistory(WebView view, String url, boolean isReload) {
            super.doUpdateVisitedHistory(view, url, isReload);
        }

        //重写此方法可以让webview处理https请求。
        @Override
        public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) {
            super.onReceivedSslError(view, handler, error);
        }


        //获取返回信息授权请求
        @Override
        public void onReceivedHttpAuthRequest(WebView view, HttpAuthHandler handler, String host, String realm) {
            super.onReceivedHttpAuthRequest(view, handler, host, realm);
        }

        @Override
        public boolean shouldOverrideKeyEvent(WebView view, KeyEvent event) {
            return super.shouldOverrideKeyEvent(view, event);
        }

        //Key事件未被加载时调用
        @Override
        public void onUnhandledKeyEvent(WebView view, KeyEvent event) {
            super.onUnhandledKeyEvent(view, event);
        }

        // WebView发生改变时调用
        @Override
        public void onScaleChanged(WebView view, float oldScale, float newScale) {
            super.onScaleChanged(view, oldScale, newScale);
        }

    };
        webView.setWebViewClient(mWebViewClient);

2.5 WebChromeClient 的介绍

WebChromeClient 是辅助WebView处理JavaScript对话框、网站图标、网站标题、加载进度等,下面方法中的代码都是android端自己处理。

   WebChromeClient mWebChromeClient = new WebChromeClient() {

        //获得网页的加载进度
        @Override
        public void onProgressChanged(WebView view, int newProgress) {

        }

        //获取Web页中的title用来设置自己界面中的title
        //当加载出错的时候,比如无网络,这时onReceiveTitle中获取的标题为 找不到该网页,
        //因此建议当触发onReceiveError时,不要使用获取到的title
        @Override
        public void onReceivedTitle(WebView view, String title) {

        }

        //获取Web页icon
        @Override
        public void onReceivedIcon(WebView view, Bitmap icon) {
            //
        }

        //创建窗口
        @Override
        public boolean onCreateWindow(WebView view, boolean isDialog, boolean isUserGesture, Message resultMsg) {
            //
            return true;
        }

        //关闭窗口
        @Override
        public void onCloseWindow(WebView window) {
        }

        //处理alert弹出框,html 弹框的一种方式
        @Override
        public boolean onJsAlert(WebView view, String url, String message, JsResult result) {
            //
            return true;
        }

        //处理confirm弹出框
        @Override
        public boolean onJsPrompt(WebView view, String url, String message, String defaultValue, JsPromptResult
                result) {
            //
            return true;
        }

        //处理prompt弹出框
        @Override
        public boolean onJsConfirm(WebView view, String url, String message, JsResult result) {
            //
            return true;
        }
    };
mWebView.setWebChromeClient (mWebChromeClient );

2.6 WebView常用的方法

2.6.1 前进、后退
        webView.goBack();//后退
        webView.goForward();//前进

        //以当前的index为起始点前进或者后退到历史记录中指定的steps, 如果steps为负数则为后退,正数则为前进
        // webView.goBackOrForward(intsteps);


        webView.canGoForward();//判断是否可以前进
        webView.canGoBack(); //判断是否可以后退
    //按键事件
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        //当点击的返回键 && webView可以回退
        if ((keyCode == KeyEvent.KEYCODE_BACK) && webView.canGoBack()) {
            webView.goBack();  //回退界面
            return true;
        }
        //没有点击返回键或者webView不能回退就处理默认的事件
        return super.onKeyDown(keyCode, event);
    }
2.6.2 清除缓存数据
webView.clearCache(true);//清除网页访问留下的缓存,由于内核缓存是全局的因此这个方法不仅仅针对webview而是针对整个应用程序.
        webView.clearHistory();//清除当前webview访问的历史记录,只会webview访问历史记录里的所有记录除了当前访问记录.
        webView.clearFormData();//这个api仅仅清除自动完成填充的表单数据,并不会清除WebView存储到本地的数据。
2.6.3 WebView的状态
        webView.onResume(); //激活WebView为活跃状态,能正常执行网页的响应
        webView.onPause();//当页面被失去焦点被切换到后台不可见状态,需要执行onPause动过, onPause动作通知内核暂停所有的动作,比如DOM的解析、plugin的执行、JavaScript执行。

        webView.pauseTimers();//当应用程序被切换到后台我们使用了webview, 这个方法不仅仅针对当前的webview而是全局的全应用程序的webview,它会暂停所有webview的layout,parsing,javascripttimer。降低CPU功耗。
        webView.resumeTimers();//恢复pauseTimers时的动作。

        webView.destroy();//销毁,关闭了Activity时,音乐或视频,还在播放。就必须销毁

注意点,当destroy调用destroy方法时,destroy仍然绑定在Activity上,这是因为构建自定义的webview时传入了该Activity的Context对象,因此需要从父容器中移除webview,再对webview进行destroy销毁。

3、使用HTTP协议访问网络

3.1 使用HttpURLConnection

3.1.1 GET请求

    /**
     * Get 请求
     * @param mUrl
     */
    private void sendRequestWithHttpURLConnection(final String mUrl){
        new Thread(new Runnable() {

            @Override
            public void run() {
                HttpURLConnection connection = null;
                BufferedReader reader = null;
                try {
                    URL url = new URL(mUrl);
                    connection = (HttpURLConnection) url.openConnection();
                    connection.setRequestMethod("GET");
                    connection.setConnectTimeout(8000);
                    connection.setReadTimeout(8000);
                    connection.setDoInput(true);
                    connection.setDoOutput(true);
                    InputStream in = connection.getInputStream();
                    reader = new BufferedReader(new InputStreamReader(in));
                    StringBuilder respond = new StringBuilder();
                    String line;
                    while ((line = reader.readLine()) != null){
                        respond.append(line);
                    }
                    
                    //将接口返回的数据处理
                } catch (IOException e) {
                    e.printStackTrace();
                    
                }finally {
                    if (reader != null){
                        try {
                            reader.close();
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                    if (connection != null){
                        connection.disconnect();
                    }
                }
            }
        }).start();
    }
3.1.2 POST请求

    /**
     * post 请求
     * @param mUrl
     */
    private void sendRequestWithHttpURLConnection_post(final String mUrl){
        new Thread(new Runnable() {

            @Override
            public void run() {
                HttpURLConnection connection = null;
                BufferedReader reader = null;
                try {
                    URL url = new URL(mUrl);
                    connection = (HttpURLConnection) url.openConnection();
                    connection.setRequestMethod("POST");
                    connection.setConnectTimeout(8000);
                    connection.setReadTimeout(8000);
                    connection.setDoInput(true);
                    connection.setDoOutput(true);
                    DataOutputStream out = new DataOutputStream(connection.getOutputStream());
                    out.writeBytes("username=admin&password=123456");
                    InputStream in = connection.getInputStream();
                    reader = new BufferedReader(new InputStreamReader(in));
                    StringBuilder respond = new StringBuilder();
                    String line;
                    while ((line = reader.readLine()) != null){
                        respond.append(line);
                    }

                    //将接口返回的数据处理
                } catch (IOException e) {
                    e.printStackTrace();

                }finally {
                    if (reader != null){
                        try {
                            reader.close();
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                    if (connection != null){
                        connection.disconnect();
                    }
                }
            }
        }).start();
    }
3.1.3 HttpURLConnection基本封装工具类
/**HttpURLConnection工具类*/
public class NetUtils {
    /**post请求*/
    public static String post(String url, String content) {
        HttpURLConnection conn = null;
        try {
            // 创建一个URL对象
            URL mURL = new URL(url);
            // 调用URL的openConnection()方法,获取HttpURLConnection对象
            conn = (HttpURLConnection) mURL.openConnection();

            conn.setRequestMethod("POST");// 设置请求方法为post
            conn.setReadTimeout(5000);// 设置读取超时为5秒
            conn.setConnectTimeout(10000);// 设置连接网络超时为10秒
            conn.setDoOutput(true);// 设置此方法,允许向服务器输出内容

            // post请求的参数
            String data = content;
            // 获得一个输出流,向服务器写数据,默认情况下,系统不允许向服务器输出内容
            OutputStream out = conn.getOutputStream();// 获得一个输出流,向服务器写数据
            out.write(data.getBytes());
            out.flush();
            out.close();

            //获取服务器返回码 调用此方法就不必再使用conn.connect()方法
            int responseCode = conn.getResponseCode();
            if (responseCode == 200) {   //200代表请求成功
                InputStream is = conn.getInputStream();
                String response = getStringFromInputStream(is);
                return response;
            } else {
                throw new NetworkErrorException("response status is "+responseCode);
            }

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (conn != null) {
                conn.disconnect();// 关闭连接
            }
        }

        return null;
    }
    /**get请求*/
    public static String get(String url) {
        HttpURLConnection conn = null;
        try {
            // 利用string url构建URL对象
            URL mURL = new URL(url);
            conn = (HttpURLConnection) mURL.openConnection();

            conn.setRequestMethod("GET");
            conn.setReadTimeout(5000);
            conn.setConnectTimeout(10000);

            int responseCode = conn.getResponseCode();
            if (responseCode == 200) {
                InputStream is = conn.getInputStream();
                String response = getStringFromInputStream(is);
                return response;
            } else {
                throw new NetworkErrorException("response status is "+responseCode);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (conn != null) {
                conn.disconnect();
            }
        }

        return null;
    }
    // 把InputStream转换成String
    private static String getStringFromInputStream(InputStream is)
            throws IOException {
        ByteArrayOutputStream os = new ByteArrayOutputStream();
        // 模板代码 必须熟练
        byte[] buffer = new byte[1024];
        int len = -1;
        while ((len = is.read(buffer)) != -1) {
            os.write(buffer, 0, len);
        }
        is.close();
        // 把流中的数据转换成字符串,采用的编码是utf-8(模拟器默认编码)
        String state = os.toString();
        os.close();
        return state;
    }
}

3.2 使用OkHttp

image.png
3.2.1 GET请求
        try {
            OkHttpClient client = new OkHttpClient();
            Request request = new Request.Builder()
                    .url("http://www.baidu.com")
                    .build();
            Response response = client.newCall(request).execute();
            String string = response.body().string();
        } catch (IOException e) {
            e.printStackTrace();
        }
3.2.2 POST请求
        try {
            OkHttpClient client = new OkHttpClient();
            RequestBody requestBody = new FormBody.Builder()
                    .add("username", "admin")
                    .add("password", "123456")
                    .build();
            Request request = new Request.Builder()
                    .url("http://www.baidu.com")
                    .post(requestBody)
                    .build();
            Response response = client.newCall(request).execute();
            String string = response.body().string();
        } catch (IOException e) {
            e.printStackTrace();
        }

4、解析XML格式数据

4.1 Pull解析方式

image.png
    private String xml = "\n" +
            "\t\n" +
            "\t\t1\n" +
            "\t\t1\n" +
            "\t\t1\n" +
            "\t\n" +
            "\t\n" +
            "\t\t1\n" +
            "\t\t1\n" +
            "\t\t1\n" +
            "\t\n" +
            "\t\n" +
            "\t\t1\n" +
            "\t\t1\n" +
            "\t\t1\n" +
            "\t\n" +
            "";

    private void parseXMLWithPull(String xmlData){
        try {
            XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
            XmlPullParser xmlPullParser = factory.newPullParser();
            xmlPullParser.setInput(new StringReader(xmlData));
            int eventType = xmlPullParser.getEventType();
            String id = "";
            String name = "";
            String version = "";
            while (eventType != XmlPullParser.END_DOCUMENT){
                String nodeName = xmlPullParser.getName();
                switch (eventType){
                    //开始解析某个节点
                    case XmlPullParser.START_TAG:
                        if ("id".equals(nodeName)){
                            id = xmlPullParser.nextText();
                        }else if ("name".equals(nodeName)){
                            name = xmlPullParser.nextText();
                        }else if ("version".equals(nodeName)){
                            version = xmlPullParser.nextText();
                        }
                        break;
                    case XmlPullParser.END_TAG:
                        if ("app".equals(nodeName)){
                            Log.d(TAG,"id is:"+id);
                            Log.d(TAG,"name is:"+name);
                            Log.d(TAG,"version is:"+version);
                        }
                        break;
                    default:
                        break;
                }
                eventType = xmlPullParser.next();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

4.2 SAX解析方式

ContentHandler.java文件

public class ContentHandler extends DefaultHandler {

    private static final String TAG = ContentHandler.class.getSimpleName();

    private String nodename;
    private StringBuilder id;
    private StringBuilder name;
    private StringBuilder version;

    @Override
    public void startDocument() throws SAXException {
        id = new StringBuilder();
        name = new StringBuilder();
        version = new StringBuilder();
    }

    @Override
    public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
        super.startElement(uri, localName, qName, attributes);
        //记录当前节点名
        nodename = localName;
    }

    @Override
    public void characters(char[] ch, int start, int length) throws SAXException {
        super.characters(ch, start, length);
        if ("id".equals(nodename)){
            id.append(ch,start,length);
        }else if ("name".equals(nodename)){
            name.append(ch,start,length);
        }else if ("version".equals(nodename)){
            version.append(ch, start, length);
        }
    }

    @Override
    public void endElement(String uri, String localName, String qName) throws SAXException {
        super.endElement(uri, localName, qName);
        if ("app".equals(localName)){
            Log.d(TAG,"id is : "+id.toString().trim());
            Log.d(TAG,"name is : "+name.toString().trim());
            Log.d(TAG,"version is : "+version.toString().trim());
            id.setLength(0);
            name.setLength(0);
            version.setLength(0);
        }
    }

    @Override
    public void endDocument() throws SAXException {
        super.endDocument();
    }


    private void parseXMLWithSAX(String xmlData){
        try {
            SAXParserFactory factory = SAXParserFactory.newInstance();
            XMLReader xmlReader = factory.newSAXParser().getXMLReader();
            ContentHandler handler = new ContentHandler();
            xmlReader.setContentHandler(handler);
            xmlReader.parse(new InputSource(new StringReader(xmlData)));
        } catch (SAXException e) {
            e.printStackTrace();
        } catch (ParserConfigurationException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

5、解析JSON格式数据

5.1 使用JSONObject

    private static final String jsonStr = "[\n" +
            "\n" +
            "{\"id\":\"5\",\"version\":\"5\",\"name\":\"5\"},\n" +
            "{\"id\":\"6\",\"version\":\"6\",\"name\":\"6\"},\n" +
            "{\"id\":\"7\",\"version\":\"7\",\"name\":\"7\"}\n" +
            "\n" +
            "]";

    private void parseJSONWithJSONObject(String jsonData){
        try {
            JSONArray jsonArray = new JSONArray(jsonData);
            for (int i = 0;i < jsonArray.length();i++){
                JSONObject jsonObject = jsonArray.getJSONObject(i);
                String id = jsonObject.getString("id");
                String name = jsonObject.getString("name");
                String version = jsonObject.getString("version");
                Log.d(TAG,"id is :"+id);
                Log.d(TAG,"name is :"+name);
                Log.d(TAG,"version is :"+version);
            }
        } catch (JSONException e) {
            e.printStackTrace();
        }
    }

6.2 使用GSON

可以将一段JSON格式的字符串自动转换成一个对象,从而不需要我们再去手动编写代码去解析了

implementation 'com.google.code.gson:gson:2.2.4'
5.2.1 解析一个json字符串(对象)

例如,{"name":"Tom","age":25}

public class Person {

    private String name;
    private int age;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
}

        Gson gson = new Gson();
        Person person = gson.fromJson(json_object, Person.class);
        Log.d(TAG,"person.getName()============"+person.getName());

对于如下的数据,例如:
{
"code":"200",
"message":"success",
"data":
[
{"name":"Tom1","age":1},
{"name":"Tom2","age":2},
{"name":"Tom3","age":3}
]

}
上面的方法同样有效

5.2.2 解析一个json数组

例如:
[
{"name":"Tom1","age":1},
{"name":"Tom2","age":2},
{"name":"Tom3","age":3}
]

public class Person {

    private String name;
    private int age;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
}

        Gson gson = new Gson();
        List peoplelsit = gson.fromJson(json_arr,new TypeToken>(){}.getType());

6、网络编程的最佳实践

HttpCallbackListener.java文件

public interface HttpCallbackListener {

    void onFinish(String response);

    void onError(Exception e);

}

HttpUtil.java文件

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);
                    connection.setDoInput(true);
                    connection.setDoOutput(true);
                    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);
                    }
                    if (listener != null) {
                        // 回调onFinish()方法
                        listener.onFinish(response.toString());
                    }
                } catch (Exception e) {
                    if (listener != null) {
                        // 回调onError()方法
                        listener.onError(e);
                    }
                } finally {
                    if (connection != null) {
                        connection.disconnect();
                    }
                }
            }
        }).start();
    }

    public static void sendOkHttpRequest(final String address, final okhttp3.Callback callback) {
        OkHttpClient client = new OkHttpClient();
        Request request = new Request.Builder()
                .url(address)
                .build();
        client.newCall(request).enqueue(callback);
    }

}

你可能感兴趣的:(第10章 网络编程)