知識(shí)
不管是網(wǎng)站,軟件還是小程序,都要直接或間接能為您產(chǎn)生價(jià)值,我們在追求其視覺表現(xiàn)的同時(shí),更側(cè)重于功能的便捷,營銷的便利,運(yùn)營的高效,讓網(wǎng)站成為營銷工具,讓軟件能切實(shí)提升企業(yè)內(nèi)部管理水平和效率。優(yōu)秀的程序?yàn)楹笃谏壧峁┍憬莸闹С郑?
android學(xué)習(xí)二十四(網(wǎng)絡(luò)編程的最佳實(shí)踐)
發(fā)表時(shí)間:2021-1-10
發(fā)布人:葵宇科技
瀏覽次數(shù):57
前面的博客已經(jīng)講解了HttpURLConnection和HttpClient的用法,知道了如何發(fā)起HTTP請求,以及解析服務(wù)器返回
的數(shù)據(jù)。但是可能你發(fā)現(xiàn)了,因?yàn)橐粋€(gè)應(yīng)用程序很多地方都可能使用網(wǎng)絡(luò)功能,而發(fā)送HTTP請求的代碼基本相同,如果每次我們都去編寫一遍發(fā)送HTTP請求的代碼,這顯然不太好。
通常情況下我們都應(yīng)該將這些通用的網(wǎng)絡(luò)操作提取到一個(gè)公共的類里,并提供一個(gè)靜態(tài)方法,當(dāng)想要發(fā)起網(wǎng)絡(luò)請求的時(shí)候只需簡單地調(diào)用一下這個(gè)方法即可。比如下面的寫法:
package com.jack.networktest; import java.io.BufferedReader; import java.io.InputStream; import java.io.InputStreamReader; import java.net.HttpURLConnection; import java.net.URL; public class HttpUtil { public static String sendHttpRequest(String address){ 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); } return response.toString(); }catch(Exception e){ e.printStackTrace(); return e.getMessage(); }finally{ if(connection!=null){ connection.disconnect(); } } } }
以后每當(dāng)要發(fā)起一條HTTP請求的時(shí)候就可以這樣寫:
String address="http://www.baidu.com";
String response=HttpUtil.sendHttpRequest(address);
在獲取到服務(wù)器響應(yīng)的數(shù)據(jù)后我們就可以對它進(jìn)行解析和處理了。但是需要注意,網(wǎng)絡(luò)請求通常都是屬于耗時(shí)操作,而 sendHttpRequest方法的內(nèi)部并沒有開啟線程,這樣就可能導(dǎo)致在調(diào)用sendHttpRequest方法的時(shí)候使得主線程阻塞住。你可能說,在sendHttpRequest方法內(nèi)部開啟一個(gè)線程不就解決了阻塞這個(gè)問題了嘛。其實(shí)沒那么簡單,因?yàn)槿绻覀冊趕endHttpRequest方法中開啟了一個(gè)線程來發(fā)起HTTP請求,那么服務(wù)器響應(yīng)的數(shù)據(jù)是無法進(jìn)行返回的,所有的耗時(shí)邏輯都是在子線程里進(jìn)行的,sendHttpRequest方法會(huì)在服務(wù)器還來得及響應(yīng)的時(shí)候就執(zhí)行結(jié)束了,當(dāng)然也就無法返回響應(yīng)的數(shù)據(jù)了。
那么這種情況該如何解決?其實(shí)解決方法可以使用java的回調(diào)機(jī)制,下面就讓我們來學(xué)習(xí)一下回調(diào)機(jī)制到底如何使用的。
首先需要定義一個(gè)接口,比如將它命名成HttpCallbackListener,代碼如下所示:
public interfac HttpCallbackListener{
void onFinish(String response);
void onError(Exception e);
}
可以看到,我們在接口中定義了兩個(gè)方法,onFinish(String response)方法表示當(dāng)服務(wù)器成功響應(yīng)我們請求
的時(shí)候調(diào)用,onError(Exception e)表示當(dāng)進(jìn)行網(wǎng)絡(luò)操作出現(xiàn)錯(cuò)誤的時(shí)候調(diào)用。這兩個(gè)方法都帶有參數(shù),
onFinish(String response)方法中的參數(shù)代表著服務(wù)器返回的數(shù)據(jù),而onError(Exception e)方法
中的參數(shù)記錄著錯(cuò)誤的詳細(xì)信息。
接著修改HttpUtil中的代碼:
import java.io.BufferedReader; import java.io.InputStream; import java.io.InputStreamReader; import java.net.HttpURLConnection; import java.net.URL; public class HttpUtil { public static void sendHttpRequest(final String address, final HttpCallbackListener listener){ new Thread(new Runnable(){ @Override public void run() { // TODO Auto-generated method stub 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(); } }
我們首先給sendHttpRequest方法添加了一個(gè)HttpCallbackListener參數(shù),并在方法的內(nèi)部開啟了一個(gè)子線程,然后
在子線程里去執(zhí)行具體的網(wǎng)絡(luò)操作。注意子線程中是無法通過return語句來返回?cái)?shù)據(jù)的,因此這里我們將服務(wù)器響應(yīng)的數(shù)據(jù)傳入了HttpCallbackListener的onFinish()方法中,如果出現(xiàn)了異常就將異常原因傳入到onError()方法中。
現(xiàn)在sendHttpRequest方法接收兩個(gè)參數(shù)了,因此我們在調(diào)用它的時(shí)候還需要將HttpCallbackListener的實(shí)例傳入
如下所示:
HttpUtil.sendHttpRequest(address,new HttpCallbackListener(){ public void onFinish(String response){ //在這里根據(jù)返回內(nèi)容執(zhí)行具體的邏輯 } public void onError(Exception e){ //在這里對異常進(jìn)行處理 } });
這樣的話,當(dāng)服務(wù)器成功響應(yīng)的時(shí)候我們就可以在onFinish方法里對響應(yīng)數(shù)據(jù)進(jìn)行處理了,類似地,如果出現(xiàn)了異常,就可以在onError方法里對異常情況進(jìn)行處理。如此一來,我們就巧妙的利用回調(diào)機(jī)制將響應(yīng)數(shù)據(jù)成功返回給調(diào)用方了。
另外需要注意的是,onFinish方法和onError方法最終還是在子線程中運(yùn)行的,因此我們不可以在這里執(zhí)行任何的
UI操作,如果需要根據(jù)返回的結(jié)果來更新UI,則仍然要使用異步消息處理機(jī)制。
http://blog.csdn.net/j903829182/article/details/42521437
相關(guān)案例查看更多
相關(guān)閱讀
- 云南網(wǎng)站維護(hù)
- 昆明網(wǎng)站開發(fā)
- 云南省建設(shè)廳官方網(wǎng)站
- 云南網(wǎng)站建設(shè)特性
- 汽車拆解管理軟件
- 云南科技公司
- 海南小程序制作公司
- 網(wǎng)絡(luò)公司
- 汽車報(bào)廢軟件
- 國內(nèi)知名網(wǎng)站建設(shè)公司排名
- flex
- 云南網(wǎng)站制作哪家好
- 小程序設(shè)計(jì)
- 河南小程序制作
- 汽車報(bào)廢
- 云南小程序開發(fā)公司哪家好
- 微信分銷系統(tǒng)
- 大理網(wǎng)站建設(shè)公司
- painter
- 云南手機(jī)網(wǎng)站建設(shè)
- 云南小程序開發(fā)公司推薦
- 網(wǎng)絡(luò)公司排名
- 小程序退款
- 紅河小程序開發(fā)
- .net網(wǎng)站
- 網(wǎng)站建設(shè)價(jià)格
- 小程序的開發(fā)公司
- 小程序商城
- 云南省住房建設(shè)廳網(wǎng)站
- 云南etc小程序