http://note.youdao.com/share/?id=f14d304548003f65e34255d3ddf9df31&type=note
網絡編程:Http通訊與Socket通訊(移動互聯核心)
知識點概述:
1.Socket通訊:面向鏈接(TCP)和無鏈接的(UDP)
2.HttpURLConnection 接口:Get和Post方式
3.HttpClient接口:Get和Post方式
知識點詳述:
1 Socket通訊
Socket稱爲」套接字「,用於描述IP地址和端口,它是支持TCP/IP協議的網絡通訊的基本操做單元。有兩種主要的操做方式:
面向鏈接(TCP協議)和無鏈接(
UDP協議)的。面向鏈接的操做比無鏈接操做的效率更低,可是數據的安全性更高。
OSI七層模型
TCP與UDP區別:
TCP---傳輸控制協議,提供的是面向鏈接、可靠的字節流服務,傳輸數據前通過「三次握手」創建鏈接,保證數據傳輸的可靠性,但效率比較低。通常用於對於數據傳輸安全性較高的場合。html
UDP---用戶數據報協議,是一個簡單的面向數據報的運輸層協議,面向無鏈接。UDP不提供可靠性,數據傳輸可能發生錯序,丟包,但效率較高。通常用於對於實時性要求較高的場合。java
Android Socket編程
(1)服務器實現步驟:
指定端口實例化一個ServerSocket 1. 實例化ServerSocket實例,指定端口號
調用ServerSocket的accept()以在等待鏈接期間形成阻塞 2. 調用accept方法,等待客戶端請求
獲取位於該底層Socket的流以進行讀寫操做 3. 有請求則返回Socket鏈接實例
將數據封裝成流 4. 經過Socket獲取輸入流讀取請求數據,並得到輸出流作出響應
對Socket進行讀寫 5.關閉流
關閉打開的流
ServerSocket ss = null;
// 建立一個ServerSocket,監聽一個端口號
try {
ss = new ServerSocket(8080);
// 等待一個socket鏈接
Socket s = ss.accept();
// 緩衝讀取數據類
BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream()));
// 從流中讀取一行數據
String msgFromClient = br.readLine();
System.out.println("msgFromClient:" + msgFromClient);
// 參數2:true 表示數據自動刷新
PrintWriter pw = new PrintWriter(new OutputStreamWriter(s.getOutputStream()), true);
pw.println("接受到了!");
//刷新數據
pw.flush();
} catch (IOException e) {
e.printStackTrace();
}
(2)客戶端實現步驟:
經過IP地址和端口實例化Socket,請求鏈接服務器 1.實例化Socket實例,指定服務端ip,以及服務端監聽此服務的端口號
獲取Socket上的流以進行讀寫 2. 經過Socket獲取輸出流向服務端發送消息
把流包裝進BufferedReader/PrintWriter的實例 3.再經過Socket獲取輸入流讀取服務端響應數據
對Socket進行讀寫 4.關閉流
關閉打開的流
Socket s = null;
try {
//和服務器斷創建鏈接
s = new Socket("127.0.0.1", 8080);
//將輸出流輸出
PrintWriter pw = new PrintWriter(new OutputStreamWriter(s.getOutputStream()));
pw.println("我是客戶端,我給你一些數據");
// 刷新提交過去
pw.flush();
//接收客戶端的消息
BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream()));
String msgFromServer = br.readLine();
System.out.println("msgFromServer:" + msgFromServer);
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
前序:HTTP通訊 (B/S, C/S)
HTTP(
超文本傳輸協議)用於傳送www方式的數據,採用了請求/響應模型。客戶端向服務器發送一個請求,請求頭包含了請求的方法、URI、協議版本,以及包含請求修飾符、
客戶信息和內容的相似於MIME的消息結構。服務器以一個狀態行做爲響應,響應的內容包括消息協議的版本、成功或者錯誤編碼,還包含服務器信息、實體元信息以及可能的實體內容。它是一個屬於應用層的面向對象的協議,因爲其簡潔、快速,它適用於分佈式超媒體信息系統。在internet上,http通訊一般發生在TCP/IP鏈接之上,缺省端口是TCP 80,但其餘的端口也是可用的。這並不預示着http協議在internet或其它網絡的其餘協議之上才能完成,http只預示着一個可靠地傳輸。Android提供了HttpURLConnection和HttpClient接口來開發http程序。
2.HttpURLConnection 接口 java.net.*提供
HTTP通訊中使用最多的就是Get和Post,Get請求能夠獲取靜態頁面,也能夠把參數放在URL字符串後面,傳遞給服務器。Post與Get的不一樣之處在於Post的參數不是放在URL字符串裏面,而是放在http請求數據中。HttpURLConnection是Java的標準類,繼承自URLConnection類,兩個類都是抽象類,沒法直接實例化對象。其對象主要經過URL的openConnection方法得到。每次openConnection都將建立一個新的鏈接實例,在鏈接以前咱們能夠對其一些屬性進行設置,好比超時時間等:
connection.setDoOutput(true); //設置輸入流(Post時必須設置)
connection.setDoInput(true); // 設置輸出流(Post時必須設置)
connection.setRequestMethod("POST"); // 設置方式爲POST(Post時必須設置)
connection.setInstanceFollowRedirects(true); //設置該請求是否重定向
connection.disconnect(); //關閉HttpURLConnection鏈接
connection.setConnectionTimeout(int time); //設置鏈接超時
connection.setReadTimeout(int time); //設置讀取超時
注:若是使用post方式,還須要設置請求的Content-Type
connection.setRequestProperty("Content-Type","application/x-www-form-urlencoded");
3. HttpClient接口(Apache接口,包名:org.apache.http.*),須要瞭解一些類:
HttpClient實現移動互聯的步驟,以及須要的類:
1) 封裝請求 HttpGet / HttpPost
2) 封裝鏈接參數 HttpParams--》BasicHttpParams, HttpConnectionParams
注:若是是Get方式則省略3)4)步驟
3)封裝請求參數 NameValuePair--》BasicNameValuePair--》List<NameValuePair>-->HttpEntity-->UrlEncodedFormEntity
4 ) 設置請求參數 HttpPost-->setEntity(請求參數)
5) 封裝執行請求的客戶端實例而且設置鏈接參數 HttpClient--》DefaultHttpClient(HttpParams)
6)發送請求,接收響應 client.execute(HttpGet/HttpPost)--->HttpResponse
7 ) 判斷響應碼是不是200,若是正常則接收響應數據 resp.getStatusLine().getStatusCode()-->200-->getEntity()-->HttpEntity
8 ) 根據響應數據類型進行轉換
(圖片--》HttpEntity.getConent()-->InputStream--->BitmapFactory.decodeStream())
(文本--》EntityUtils.toString(HttpEntity, "utf-8")
(1)HttpClient使用Get方式獲取數據,須要使用HttpGet來構建一個Get方式的http請求,而後經過HttpClient來執行這個請求,HttpResponse在接收這個請求後給出響應,最後經過「HttpResponse.getStatusLine().getStatusCode()"來判斷請求是否成功,並處理。能夠直接使用以下方法將響應的實體元信息轉化爲字符串
String strResult = EntityUtils.toString(httpResponse.getEntity());
HttpClient的Get方式請求步驟:
封裝HttpGet請求 new HttpGet(urlStr)
經過HttpParams設置鏈接參數
獲取HttpClient實例 new DefaultHttpClient();
發送請求,接收響應
HttpResponse = httpClient.excute(httpGet)
判斷響應碼是否是200.若是是200,接收響應數據
HttpEntity = httpResponse.getEntity();
HttpClient使用Post方式獲取數據稍微複雜一點。首先好使用HttpPost來構建一個Post方式的http請求,
HttpPost httpRequest=new HttpPost("url");
須要使用NameValuePair來保存要傳遞的參數,可使用BasicNameValuePair來構造一個要被傳遞的參數,而後經過add方法添加這個參數到NameValuePair中,
List<NameValuePair> params=new ArrayList<NameValuePair>(); //使用NameValuePair來保存要傳遞的Post參數
params.add(new BasicNameValuePair("par","HttpClient_android_Post"));
//添加要傳遞的參數Post方式還須要設置所使用的字符集,最後就和Get方式同樣經過HttpClient來請求這個鏈接,返回響應並處理,
HttpEntity httpentity=new UrlEncodedFormEntity(params,"utf-8"); //設置字符集
httpRequest.setEntity(httpentity); //爲請求設置實體元信息
(2)DefaultHttpClient是默認的一個HTTP客戶端,咱們可使用它建立一個HTTP鏈接。
代碼以下:HttpClient hc=new DefaultHttpClient();
(3) HttpResponse是一個HTTP鏈接響應,當執行一個http鏈接後,就會返回一個HttpResponse,能夠經過其得到一些響應信息。下面是請求一個HTTP鏈接並得到該請求是否成功的代碼:
HttpResponse hresponse=hc.execute(httpRequest);
if(hresponse.getStatusLine().getStatusCode()==HttpStatus.SC_OK){ //鏈接成功
}
示例代碼:
//HttpClient接口經過Post方式獲取數據
private String requestStringGet(String urlStr, String param){
String content = "";
//構建Post請求
HttpPost request = new HttpPost(urlStr);
//構建設置鏈接參數實例
HttpParams connParams = new BasicHttpParams();
//設置鏈接超時
HttpConnectionParams.setConnectionTimeout(connParams, 10 * 1000);
//設置Socket超時
HttpConnectionParams.setSoTimeout(connParams, 10 * 1000);
//構建請求參數
List<NameValuePair> requestParams = new ArrayList<NameValuePair>();
requestParams.add(new BasicNameValuePair("name", param));
requestParams.add(new BasicNameValuePair("pass", param));
try{
//將請求參數列表轉化爲請求實體元信息
HttpEntity paramEntity = new UrlEncodedFormEntity(requestParams,"utf-8");
//將請求實體元信息設置到請求中
request.setEntity(paramEntity);
//獲取執行請求的HttpClient
HttpClient client = new DefaultHttpClient(connParams);
//執行請求,獲取響應
HttpResponse response = client.execute(request);
//判斷是否正確響應
if(response.getStatusLine().getStatusCode() == 200){
//獲取響應內容
HttpEntity entity = response.getEntity();
if(entity!=null){
content = EntityUtils.toString(entity, "utf-8");
Log.d("TAG", "content: " + content);
content = parseJson(content).toString();
}else{
content = "服務器沒有給出響應內容";
}
}else{
content = "獲取響應失敗!";
}
}catch(SocketTimeoutException e){
Toast.makeText(this, "請求超時!", Toast.LENGTH_LONG).show();
}catch(IOException e){
e.printStackTrace();
Toast.makeText(this, "網絡鏈接出錯!", Toast.LENGTH_LONG).show();
}
return content;
}
如何避免ANR:
Thread + Handler
AsyncTask
關於Handler:
關於AsyncTask:
AsyncTask:異步任務類<----------------------->handlerandroid
//若是我有耗時工做,而且耗時工做結束以後要更新UIapache
異步任務的泛型類型編程
AsynTask<參數,進度條參數,返回值>json
啓動異步任務類: 調用 execute(參數); //不定長參數數組
當調用execute的時候執行 doInBackground(參數)。安全
doInBackground方法在子線程執行,當其執行完畢後返回返回值,服務器
而後執行
onPostExe
擴展: 網絡通訊的中文亂碼問題
網絡通訊中,產生亂碼的緣由主要是通訊過程當中使用了不一樣的編碼方式:服務器中的編碼方式,傳輸過程當中的編碼方式,傳輸到達中斷設備的編碼方式。所以在傳輸過程當中就須要至少兩次編碼轉換:首先從服務器編碼轉換爲網絡編碼,再從網絡編碼轉換爲終端設備編碼。在轉換過程當中發生任何狀況均可能引發編碼混亂,通常狀況下咱們能夠經過如下兩種方式來避免這個問題。
一種方式是:因爲大部分終端設備都支持Unicode字符集,因此在鏈接網頁時,咱們但願網頁數據在網絡傳輸時使用utf-8方式傳輸,這樣就能夠很簡單地將utf-8轉換成
Unicode字符集了。
另外一種方式是在數據傳遞過程當中使用ISO-8859-1字符集,這樣就是直接使用ASCII編碼方式,固然在傳遞到終端設備時,須要將其數據反轉纔可以正常顯示。歸根結底,解決中文亂碼只須要兩個步驟:
使用getBytes("編碼方式");來對漢字進行重編碼,獲得它的字節數組
再使用new String(Bytes[],"解碼方式");來對字節數組進行相應的解碼
做業描述:
訪問服務器文件內容並經過TextView將內容顯示出來
要求:1. 訪問data.xml文件用HttpUrlConnection實現,經過Thread + Handler優化性能,要求必須設置超時鏈接參數,注意編碼規範
2. 訪問data.json文件用HttpClient實現,經過AsyncTask優化性能,要求必須設置超時鏈接參數,注意編碼規範
http://note.youdao.com/share/?id=f14d304548003f65e34255d3ddf9df31&type=note
網絡編程:Http通訊與Socket通訊(移動互聯核心)
知識點概述:
1.Socket通訊:面向鏈接(TCP)和無鏈接的(UDP)
2.HttpURLConnection 接口:Get和Post方式
3.HttpClient接口:Get和Post方式
知識點詳述:
1 Socket通訊
Socket稱爲」套接字「,用於描述IP地址和端口,它是支持TCP/IP協議的網絡通訊的基本操做單元。有兩種主要的操做方式:
面向鏈接(TCP協議)和無鏈接(
UDP協議)的。面向鏈接的操做比無鏈接操做的效率更低,可是數據的安全性更高。
OSI七層模型
TCP與UDP區別:
TCP---傳輸控制協議,提供的是面向鏈接、可靠的字節流服務,傳輸數據前通過「三次握手」創建鏈接,保證數據傳輸的可靠性,但效率比較低。通常用於對於數據傳輸安全性較高的場合。網絡
UDP---用戶數據報協議,是一個簡單的面向數據報的運輸層協議,面向無鏈接。UDP不提供可靠性,數據傳輸可能發生錯序,丟包,但效率較高。通常用於對於實時性要求較高的場合。
Android Socket編程
(1)服務器實現步驟:
指定端口實例化一個ServerSocket 1. 實例化ServerSocket實例,指定端口號
調用ServerSocket的accept()以在等待鏈接期間形成阻塞 2. 調用accept方法,等待客戶端請求
獲取位於該底層Socket的流以進行讀寫操做 3. 有請求則返回Socket鏈接實例
將數據封裝成流 4. 經過Socket獲取輸入流讀取請求數據,並得到輸出流作出響應
對Socket進行讀寫 5.關閉流
關閉打開的流
ServerSocket ss = null;
// 建立一個ServerSocket,監聽一個端口號
try {
ss = new ServerSocket(8080);
// 等待一個socket鏈接
Socket s = ss.accept();
// 緩衝讀取數據類
BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream()));
// 從流中讀取一行數據
String msgFromClient = br.readLine();
System.out.println("msgFromClient:" + msgFromClient);
// 參數2:true 表示數據自動刷新
PrintWriter pw = new PrintWriter(new OutputStreamWriter(s.getOutputStream()), true);
pw.println("接受到了!");
//刷新數據
pw.flush();
} catch (IOException e) {
e.printStackTrace();
}
(2)客戶端實現步驟:
經過IP地址和端口實例化Socket,請求鏈接服務器 1.實例化Socket實例,指定服務端ip,以及服務端監聽此服務的端口號
獲取Socket上的流以進行讀寫 2. 經過Socket獲取輸出流向服務端發送消息
把流包裝進BufferedReader/PrintWriter的實例 3.再經過Socket獲取輸入流讀取服務端響應數據
對Socket進行讀寫 4.關閉流
關閉打開的流
Socket s = null;
try {
//和服務器斷創建鏈接
s = new Socket("127.0.0.1", 8080);
//將輸出流輸出
PrintWriter pw = new PrintWriter(new OutputStreamWriter(s.getOutputStream()));
pw.println("我是客戶端,我給你一些數據");
// 刷新提交過去
pw.flush();
//接收客戶端的消息
BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream()));
String msgFromServer = br.readLine();
System.out.println("msgFromServer:" + msgFromServer);
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
前序:HTTP通訊 (B/S, C/S)
HTTP(
超文本傳輸協議)用於傳送www方式的數據,採用了請求/響應模型。客戶端向服務器發送一個請求,請求頭包含了請求的方法、URI、協議版本,以及包含請求修飾符、
客戶信息和內容的相似於MIME的消息結構。服務器以一個狀態行做爲響應,響應的內容包括消息協議的版本、成功或者錯誤編碼,還包含服務器信息、實體元信息以及可能的實體內容。它是一個屬於應用層的面向對象的協議,因爲其簡潔、快速,它適用於分佈式超媒體信息系統。在internet上,http通訊一般發生在TCP/IP鏈接之上,缺省端口是TCP 80,但其餘的端口也是可用的。這並不預示着http協議在internet或其它網絡的其餘協議之上才能完成,http只預示着一個可靠地傳輸。Android提供了HttpURLConnection和HttpClient接口來開發http程序。
2.HttpURLConnection 接口 java.net.*提供
HTTP通訊中使用最多的就是Get和Post,Get請求能夠獲取靜態頁面,也能夠把參數放在URL字符串後面,傳遞給服務器。Post與Get的不一樣之處在於Post的參數不是放在URL字符串裏面,而是放在http請求數據中。HttpURLConnection是Java的標準類,繼承自URLConnection類,兩個類都是抽象類,沒法直接實例化對象。其對象主要經過URL的openConnection方法得到。每次openConnection都將建立一個新的鏈接實例,在鏈接以前咱們能夠對其一些屬性進行設置,好比超時時間等:
connection.setDoOutput(true); //設置輸入流(Post時必須設置)
connection.setDoInput(true); // 設置輸出流(Post時必須設置)
connection.setRequestMethod("POST"); // 設置方式爲POST(Post時必須設置)
connection.setInstanceFollowRedirects(true); //設置該請求是否重定向
connection.disconnect(); //關閉HttpURLConnection鏈接
connection.setConnectionTimeout(int time); //設置鏈接超時
connection.setReadTimeout(int time); //設置讀取超時
注:若是使用post方式,還須要設置請求的Content-Type
connection.setRequestProperty("Content-Type","application/x-www-form-urlencoded");
3. HttpClient接口(Apache接口,包名:org.apache.http.*),須要瞭解一些類:
HttpClient實現移動互聯的步驟,以及須要的類:
1) 封裝請求 HttpGet / HttpPost
2) 封裝鏈接參數 HttpParams--》BasicHttpParams, HttpConnectionParams
注:若是是Get方式則省略3)4)步驟
3)封裝請求參數 NameValuePair--》BasicNameValuePair--》List<NameValuePair>-->HttpEntity-->UrlEncodedFormEntity
4 ) 設置請求參數 HttpPost-->setEntity(請求參數)
5) 封裝執行請求的客戶端實例而且設置鏈接參數 HttpClient--》DefaultHttpClient(HttpParams)
6)發送請求,接收響應 client.execute(HttpGet/HttpPost)--->HttpResponse
7 ) 判斷響應碼是不是200,若是正常則接收響應數據 resp.getStatusLine().getStatusCode()-->200-->getEntity()-->HttpEntity
8 ) 根據響應數據類型進行轉換
(圖片--》HttpEntity.getConent()-->InputStream--->BitmapFactory.decodeStream())
(文本--》EntityUtils.toString(HttpEntity, "utf-8")
(1)HttpClient使用Get方式獲取數據,須要使用HttpGet來構建一個Get方式的http請求,而後經過HttpClient來執行這個請求,HttpResponse在接收這個請求後給出響應,最後經過「HttpResponse.getStatusLine().getStatusCode()"來判斷請求是否成功,並處理。能夠直接使用以下方法將響應的實體元信息轉化爲字符串
String strResult = EntityUtils.toString(httpResponse.getEntity());
HttpClient的Get方式請求步驟:
封裝HttpGet請求 new HttpGet(urlStr)
經過HttpParams設置鏈接參數
獲取HttpClient實例 new DefaultHttpClient();
發送請求,接收響應
HttpResponse = httpClient.excute(httpGet)
判斷響應碼是否是200.若是是200,接收響應數據
HttpEntity = httpResponse.getEntity();
HttpClient使用Post方式獲取數據稍微複雜一點。首先好使用HttpPost來構建一個Post方式的http請求,
HttpPost httpRequest=new HttpPost("url");
須要使用NameValuePair來保存要傳遞的參數,可使用BasicNameValuePair來構造一個要被傳遞的參數,而後經過add方法添加這個參數到NameValuePair中,
List<NameValuePair> params=new ArrayList<NameValuePair>(); //使用NameValuePair來保存要傳遞的Post參數
params.add(new BasicNameValuePair("par","HttpClient_android_Post"));
//添加要傳遞的參數Post方式還須要設置所使用的字符集,最後就和Get方式同樣經過HttpClient來請求這個鏈接,返回響應並處理,
HttpEntity httpentity=new UrlEncodedFormEntity(params,"utf-8"); //設置字符集
httpRequest.setEntity(httpentity); //爲請求設置實體元信息
(2)DefaultHttpClient是默認的一個HTTP客戶端,咱們可使用它建立一個HTTP鏈接。
代碼以下:HttpClient hc=new DefaultHttpClient();
(3) HttpResponse是一個HTTP鏈接響應,當執行一個http鏈接後,就會返回一個HttpResponse,能夠經過其得到一些響應信息。下面是請求一個HTTP鏈接並得到該請求是否成功的代碼:
HttpResponse hresponse=hc.execute(httpRequest);
if(hresponse.getStatusLine().getStatusCode()==HttpStatus.SC_OK){ //鏈接成功
}
示例代碼:
//HttpClient接口經過Post方式獲取數據
private String requestStringGet(String urlStr, String param){
String content = "";
//構建Post請求
HttpPost request = new HttpPost(urlStr);
//構建設置鏈接參數實例
HttpParams connParams = new BasicHttpParams();
//設置鏈接超時
HttpConnectionParams.setConnectionTimeout(connParams, 10 * 1000);
//設置Socket超時
HttpConnectionParams.setSoTimeout(connParams, 10 * 1000);
//構建請求參數
List<NameValuePair> requestParams = new ArrayList<NameValuePair>();
requestParams.add(new BasicNameValuePair("name", param));
requestParams.add(new BasicNameValuePair("pass", param));
try{
//將請求參數列表轉化爲請求實體元信息
HttpEntity paramEntity = new UrlEncodedFormEntity(requestParams,"utf-8");
//將請求實體元信息設置到請求中
request.setEntity(paramEntity);
//獲取執行請求的HttpClient
HttpClient client = new DefaultHttpClient(connParams);
//執行請求,獲取響應
HttpResponse response = client.execute(request);
//判斷是否正確響應
if(response.getStatusLine().getStatusCode() == 200){
//獲取響應內容
HttpEntity entity = response.getEntity();
if(entity!=null){
content = EntityUtils.toString(entity, "utf-8");
Log.d("TAG", "content: " + content);
content = parseJson(content).toString();
}else{
content = "服務器沒有給出響應內容";
}
}else{
content = "獲取響應失敗!";
}
}catch(SocketTimeoutException e){
Toast.makeText(this, "請求超時!", Toast.LENGTH_LONG).show();
}catch(IOException e){
e.printStackTrace();
Toast.makeText(this, "網絡鏈接出錯!", Toast.LENGTH_LONG).show();
}
return content;
}
如何避免ANR:
Thread + Handler
AsyncTask
關於Handler:
關於AsyncTask:
AsyncTask:異步任務類<----------------------->handler
//若是我有耗時工做,而且耗時工做結束以後要更新UI
異步任務的泛型類型
AsynTask<參數,進度條參數,返回值>
啓動異步任務類: 調用 execute(參數); //不定長參數
當調用execute的時候執行 doInBackground(參數)。
doInBackground方法在子線程執行,當其執行完畢後返回返回值,
而後執行
onPostExe
擴展: 網絡通訊的中文亂碼問題
網絡通訊中,產生亂碼的緣由主要是通訊過程當中使用了不一樣的編碼方式:服務器中的編碼方式,傳輸過程當中的編碼方式,傳輸到達中斷設備的編碼方式。所以在傳輸過程當中就須要至少兩次編碼轉換:首先從服務器編碼轉換爲網絡編碼,再從網絡編碼轉換爲終端設備編碼。在轉換過程當中發生任何狀況均可能引發編碼混亂,通常狀況下咱們能夠經過如下兩種方式來避免這個問題。
一種方式是:因爲大部分終端設備都支持Unicode字符集,因此在鏈接網頁時,咱們但願網頁數據在網絡傳輸時使用utf-8方式傳輸,這樣就能夠很簡單地將utf-8轉換成
Unicode字符集了。
另外一種方式是在數據傳遞過程當中使用ISO-8859-1字符集,這樣就是直接使用ASCII編碼方式,固然在傳遞到終端設備時,須要將其數據反轉纔可以正常顯示。歸根結底,解決中文亂碼只須要兩個步驟:
使用getBytes("編碼方式");來對漢字進行重編碼,獲得它的字節數組
再使用new String(Bytes[],"解碼方式");來對字節數組進行相應的解碼
做業描述:
訪問服務器文件內容並經過TextView將內容顯示出來
要求:1. 訪問data.xml文件用HttpUrlConnection實現,經過Thread + Handler優化性能,要求必須設置超時鏈接參數,注意編碼規範
2. 訪問data.json文件用HttpClient實現,經過AsyncTask優化性能,要求必須設置超時鏈接參數,注意編碼規範