第10章 網(wǎng)絡(luò)編程

本系列學(xué)習(xí)筆記第10章

前言

打算把android基本知識點寫一個系列,旨在把android基礎(chǔ)書,例如《Android 第一行代碼 第2版》、《愛上android》、《瘋狂android講義》等書的一些知識點記錄一下,會持續(xù)更新內(nèi)容,為了方便自己復(fù)習(xí),也希望可以幫助到大家!

1、HTTP協(xié)議

1.1 URL簡介

URL的全稱是統(tǒng)一資源定位符,通過一個URL能找到互聯(lián)網(wǎng)上唯一 的一個資源,URL就是資源的地址、位置。

URL的基本格式 = 協(xié)議://主機地址/路徑
協(xié)議:不同的協(xié)議,代表不同資源的查找方式、資源傳輸方式
主機地址:存放資源的主機IP地址或者域名
路徑:資源在主機中的具體位置

URL中常見的協(xié)議如下:
HTTP:超文本傳輸協(xié)議,訪問的是遠程網(wǎng)絡(luò)資源,格式是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 加載網(wǎng)絡(luò)頁面的用法

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 加載本地靜態(tài)頁面的用法

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


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

2.3 WebView的設(shè)置用法

        //支持獲取手勢焦點,輸入用戶名、密碼或其他
        webView.requestFocusFromTouch();

        //支持js,這樣有潛在的安全隱患,無需要,建議關(guān)閉
        webSettings.setJavaScriptEnabled(true);

        //提高渲染的優(yōu)先級,高版本廢棄了。
        webSettings.setRenderPriority(WebSettings.RenderPriority.HIGH);

        //  設(shè)置自適應(yīng)屏幕,兩者合用
        webSettings.setUseWideViewPort(true);  //將圖片調(diào)整到適合webview的大小
        webSettings.setLoadWithOverviewMode(true); // 縮放至屏幕的大小

        webSettings.setSupportZoom(true);  //支持縮放,默認為true。是下面那個的前提。
        //若下面是false,則該WebView不可縮放,這個不管設(shè)置什么都不能縮放。
        webSettings.setBuiltInZoomControls(true); //設(shè)置內(nèi)置的縮放控件。


        webSettings.setDisplayZoomControls(false); //隱藏原生的縮放控件

        webSettings.setLayoutAlgorithm(WebSettings.LayoutAlgorithm.SINGLE_COLUMN); //支持內(nèi)容重新布局
        webSettings.supportMultipleWindows();  //支持多窗口
        webSettings.setCacheMode(WebSettings.LOAD_CACHE_ELSE_NETWORK);  //關(guān)閉webview中緩存
        webSettings.setAllowFileAccess(true);  //設(shè)置可以訪問文件
        webSettings.setNeedInitialFocus(true); //當webview調(diào)用requestFocus時為webview設(shè)置節(jié)點
        webSettings.setJavaScriptCanOpenWindowsAutomatically(true); //支持通過JS打開新窗口
        webSettings.setLoadsImagesAutomatically(true);  //支持自動加載圖片
        webSettings.setDefaultTextEncodingName("utf-8");//設(shè)置編碼格式


        //----緩存
        //根據(jù)網(wǎng)頁中cache-control決定是否從網(wǎng)絡(luò)上取數(shù)據(jù)。
        webSettings.setCacheMode(WebSettings.LOAD_DEFAULT);

        webSettings.setCacheMode(WebSettings.LOAD_CACHE_ELSE_NETWORK);//沒網(wǎng),則從本地獲取,即離線加載


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

        String cacheDirPath = getCacheDir().getAbsolutePath();
        //設(shè)置  Application Caches 緩存目錄
        //每個 Application 只調(diào)用一次 WebSettings.setAppCachePath()
        webSettings.setAppCachePath(cacheDirPath);

        //Android 5.0上 Webview 默認不允許加載 Http 與 Https 混合內(nèi)容,加下下面的配置就解決了.
        webSettings.setMixedContentMode(WebSettings.MIXED_CONTENT_ALWAYS_ALLOW);

2.4 WebViewClient的介紹

WebViewClient就是幫助WebView 處理各種通知,請求事件的。

   WebViewClient mWebViewClient = new WebViewClient() {
        //在網(wǎng)頁上的所有加載都經(jīng)過這個方法,這個函數(shù)我們可以做很多操作。
        //比如獲取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;
        }

        //這個事件就是開始載入頁面調(diào)用的,我們可以設(shè)定一個loading的頁面,告訴用戶程序在等待網(wǎng)絡(luò)響應(yīng)。
        @Override
        public void onPageStarted(WebView view, String url, Bitmap favicon) {
            super.onPageStarted(view, url, favicon);
        }

        //在頁面加載結(jié)束時調(diào)用。同樣道理,我們可以關(guān)閉loading 條,切換程序動作。
        @Override
        public void onPageFinished(WebView view, String url) {
            super.onPageFinished(view, url);
        }

        // 在加載頁面資源時會調(diào)用,每一個資源(比如圖片)的加載都會調(diào)用一次。
        @Override
        public void onLoadResource(WebView view, String url) {
            super.onLoadResource(view, url);
        }

        // 攔截替換網(wǎng)絡(luò)請求數(shù)據(jù),  API 11開始引入,API 21棄用
        @Override
        public WebResourceResponse shouldInterceptRequest(WebView view, String url) {
            return super.shouldInterceptRequest(view, url);
        }

        // 攔截替換網(wǎng)絡(luò)請求數(shù)據(jù),  從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);
        }

        //應(yīng)用程序重新請求網(wǎng)頁數(shù)據(jù)
        @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);
        }


        //獲取返回信息授權(quán)請求
        @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事件未被加載時調(diào)用
        @Override
        public void onUnhandledKeyEvent(WebView view, KeyEvent event) {
            super.onUnhandledKeyEvent(view, event);
        }

        // WebView發(fā)生改變時調(diào)用
        @Override
        public void onScaleChanged(WebView view, float oldScale, float newScale) {
            super.onScaleChanged(view, oldScale, newScale);
        }

    };
        webView.setWebViewClient(mWebViewClient);

2.5 WebChromeClient 的介紹

WebChromeClient 是輔助WebView處理JavaScript對話框、網(wǎng)站圖標、網(wǎng)站標題、加載進度等,下面方法中的代碼都是android端自己處理。

   WebChromeClient mWebChromeClient = new WebChromeClient() {

        //獲得網(wǎng)頁的加載進度
        @Override
        public void onProgressChanged(WebView view, int newProgress) {

        }

        //獲取Web頁中的title用來設(shè)置自己界面中的title
        //當加載出錯的時候,比如無網(wǎng)絡(luò),這時onReceiveTitle中獲取的標題為 找不到該網(wǎng)頁,
        //因此建議當觸發(fā)onReceiveError時,不要使用獲取到的title
        @Override
        public void onReceivedTitle(WebView view, String title) {

        }

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

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

        //關(guān)閉窗口
        @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為負數(shù)則為后退,正數(shù)則為前進
        // 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 清除緩存數(shù)據(jù)
webView.clearCache(true);//清除網(wǎng)頁訪問留下的緩存,由于內(nèi)核緩存是全局的因此這個方法不僅僅針對webview而是針對整個應(yīng)用程序.
        webView.clearHistory();//清除當前webview訪問的歷史記錄,只會webview訪問歷史記錄里的所有記錄除了當前訪問記錄.
        webView.clearFormData();//這個api僅僅清除自動完成填充的表單數(shù)據(jù),并不會清除WebView存儲到本地的數(shù)據(jù)。
2.6.3 WebView的狀態(tài)
        webView.onResume(); //激活WebView為活躍狀態(tài),能正常執(zhí)行網(wǎng)頁的響應(yīng)
        webView.onPause();//當頁面被失去焦點被切換到后臺不可見狀態(tài),需要執(zhí)行onPause動過, onPause動作通知內(nèi)核暫停所有的動作,比如DOM的解析、plugin的執(zhí)行、JavaScript執(zhí)行。

        webView.pauseTimers();//當應(yīng)用程序被切換到后臺我們使用了webview, 這個方法不僅僅針對當前的webview而是全局的全應(yīng)用程序的webview,它會暫停所有webview的layout,parsing,javascripttimer。降低CPU功耗。
        webView.resumeTimers();//恢復(fù)pauseTimers時的動作。

        webView.destroy();//銷毀,關(guān)閉了Activity時,音樂或視頻,還在播放。就必須銷毀

注意點,當destroy調(diào)用destroy方法時,destroy仍然綁定在Activity上,這是因為構(gòu)建自定義的webview時傳入了該Activity的Context對象,因此需要從父容器中移除webview,再對webview進行destroy銷毀。

3、使用HTTP協(xié)議訪問網(wǎng)絡(luò)

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);
                    }
                    
                    //將接口返回的數(shù)據(jù)處理
                } 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);
                    }

                    //將接口返回的數(shù)據(jù)處理
                } 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 {
            // 創(chuàng)建一個URL對象
            URL mURL = new URL(url);
            // 調(diào)用URL的openConnection()方法,獲取HttpURLConnection對象
            conn = (HttpURLConnection) mURL.openConnection();

            conn.setRequestMethod("POST");// 設(shè)置請求方法為post
            conn.setReadTimeout(5000);// 設(shè)置讀取超時為5秒
            conn.setConnectTimeout(10000);// 設(shè)置連接網(wǎng)絡(luò)超時為10秒
            conn.setDoOutput(true);// 設(shè)置此方法,允許向服務(wù)器輸出內(nèi)容

            // post請求的參數(shù)
            String data = content;
            // 獲得一個輸出流,向服務(wù)器寫數(shù)據(jù),默認情況下,系統(tǒng)不允許向服務(wù)器輸出內(nèi)容
            OutputStream out = conn.getOutputStream();// 獲得一個輸出流,向服務(wù)器寫數(shù)據(jù)
            out.write(data.getBytes());
            out.flush();
            out.close();

            //獲取服務(wù)器返回碼 調(diào)用此方法就不必再使用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();// 關(guān)閉連接
            }
        }

        return null;
    }
    /**get請求*/
    public static String get(String url) {
        HttpURLConnection conn = null;
        try {
            // 利用string url構(gòu)建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轉(zhuǎn)換成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();
        // 把流中的數(shù)據(jù)轉(zhuǎn)換成字符串,采用的編碼是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格式數(shù)據(jù)

4.1 Pull解析方式

image.png
    private String xml = "<apps>\n" +
            "\t<app>\n" +
            "\t\t<id>1</id>\n" +
            "\t\t<name>1</name>\n" +
            "\t\t<version>1</version>\n" +
            "\t</app>\n" +
            "\t<app>\n" +
            "\t\t<id>1</id>\n" +
            "\t\t<name>1</name>\n" +
            "\t\t<version>1</version>\n" +
            "\t</app>\n" +
            "\t<app>\n" +
            "\t\t<id>1</id>\n" +
            "\t\t<name>1</name>\n" +
            "\t\t<version>1</version>\n" +
            "\t</app>\n" +
            "</apps>";

    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){
                    //開始解析某個節(jié)點
                    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);
        //記錄當前節(jié)點名
        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格式數(shù)據(jù)

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格式的字符串自動轉(zhuǎn)換成一個對象,從而不需要我們再去手動編寫代碼去解析了

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());

對于如下的數(shù)據(jù),例如:
{
"code":"200",
"message":"success",
"data":
[
{"name":"Tom1","age":1},
{"name":"Tom2","age":2},
{"name":"Tom3","age":3}
]

}
上面的方法同樣有效

5.2.2 解析一個json數(shù)組

例如:
[
{"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<Person> peoplelsit = gson.fromJson(json_arr,new TypeToken<List<Person>>(){}.getType());

6、網(wǎng)絡(luò)編程的最佳實踐

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) {
                        // 回調(diào)onFinish()方法
                        listener.onFinish(response.toString());
                    }
                } catch (Exception e) {
                    if (listener != null) {
                        // 回調(diào)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);
    }

}

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,501評論 6 544
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 99,673評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,610評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,939評論 1 318
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,668評論 6 412
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 56,004評論 1 329
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 44,001評論 3 449
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 43,173評論 0 290
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 49,705評論 1 336
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 41,426評論 3 359
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,656評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,139評論 5 364
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 44,833評論 3 350
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,247評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,580評論 1 295
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,371評論 3 400
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,621評論 2 380

推薦閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,761評論 25 708
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 134,829評論 18 139
  • 一個人,來到世界,就是一個人;一個人,離開世界,也是一個人。 一個人學(xué)會哇哇大哭,一個人試著偷偷微笑,一個...
    七人閱讀 182評論 2 0
  • 今天的話題就從大學(xué)畢業(yè)開始說起吧。 大學(xué)四年匆匆而過,臨近畢業(yè)的時候早就沒有了要學(xué)習(xí)的心思,于是順理成章得考編失利...
    童Vs源閱讀 223評論 0 1
  • 0.序言 今天是5.4,雖然可能一直以為自己只是個少年。 但事實是,沒多久就要被人以為是中年了。 不過沒關(guān)系。 根...
    小腿1988閱讀 691評論 0 2