android學習二十四(網絡編程的最佳實踐) - 新聞資(zī)訊 - 雲南小程序開發|雲南軟件開發|雲南網站(zhàn)建設-西山區知普網絡科技工作室

159-8711-8523

雲南網建設/小程序開發/軟件開發

知識

不管是網站(zhàn),軟件還是小程序,都要直接或間接能為您産生價值,我們在追求其視覺表現的同時,更側重于功能的便捷,營銷的便利,運營的高效,讓網站(zhàn)成為營銷工具,讓軟件能切實提升企業(yè)内部管理水平和(hé)效率。優秀的程序為後期升級提供便捷的支持!

您當前位置>首頁 » 新聞資(zī)訊 » 技術(shù)分享 >

android學習二十四(網絡編程的最佳實踐)

發表時間:2021-1-10

發布人:葵宇科技

浏覽次數:27


 前面的博客已經講解了HttpURLConnection和(hé)HttpClient的用法,知道了如(rú)何發起HTTP請求,以及解析服務器(qì)返回
 的數據。但是可(kě)能你(nǐ)發現了,因為一個(gè)應用程序很多地方都可(kě)能使用網絡功能,而發送HTTP請求的代碼基本相同,如(rú)果每次我們都去編寫一遍發送HTTP請求的代碼,這顯然不太好。
    通(tōng)常情況下(xià)我們都應該将這些通(tōng)用的網絡操作提取到一個(gè)公共的類裡,并提供一個(gè)靜态方法,當想要發起網絡請求的時候隻需簡單地調用一下(xià)這個(gè)方法即可(kě)。比如(rú)下(xià)面的寫法:
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();
			}
		}
	}
}

以後每當要發起一條HTTP請求的時候就可(kě)以這樣寫:
  String address="http://www.baidu.com";
  String response=HttpUtil.sendHttpRequest(address);



         在獲取到服務器(qì)響應的數據後我們就可(kě)以對它進行解析和(hé)處理了。但是需要注意,網絡請求通(tōng)常都是屬于耗時操作,而 sendHttpRequest方法的内部并沒有開啟線程,這樣就可(kě)能導緻在調用sendHttpRequest方法的時候使得主線程阻塞住。你(nǐ)可(kě)能說,在sendHttpRequest方法内部開啟一個(gè)線程不就解決了阻塞這個(gè)問(wèn)題了嘛。其實沒那麼簡單,因為如(rú)果我們在sendHttpRequest方法中(zhōng)開啟了一個(gè)線程來發起HTTP請求,那麼服務器(qì)響應的數據是無法進行返回的,所有的耗時邏輯都是在子(zǐ)線程裡進行的,sendHttpRequest方法會在服務器(qì)還來得及響應的時候就執行結束了,當然也就無法返回響應的數據了。
  那麼這種情況該如(rú)何解決?其實解決方法可(kě)以使用java的回調機制,下(xià)面就讓我們來學習一下(xià)回調機制到底如(rú)何使用的。
  首先需要定義一個(gè)接口,比如(rú)将它命名成HttpCallbackListener,代碼如(rú)下(xià)所示:
  public interfac HttpCallbackListener{
  void onFinish(String response);
  void onError(Exception e);
  }
  可(kě)以看到,我們在接口中(zhōng)定義了兩個(gè)方法,onFinish(String response)方法表示當服務器(qì)成功響應我們請求
  的時候調用,onError(Exception e)表示當進行網絡操作出現錯誤的時候調用。這兩個(gè)方法都帶有參數,
  onFinish(String response)方法中(zhōng)的參數代表着服務器(qì)返回的數據,而onError(Exception e)方法
  中(zhōng)的參數記錄着錯誤的詳細信息。

       接着修改HttpUtil中(zhōng)的代碼:
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){
						//回調onFinish()方法
						listener.onFinish(response.toString());
					}
				}catch(Exception e){
					if(listener!=null){
						//回調onError()方法
						listener.onError(e);
					}
					
				}finally{
					if(connection!=null){
						connection.disconnect();
					}
					}
			}
				}).start();
		
		
	}
}



我們首先給sendHttpRequest方法添加了一個(gè)HttpCallbackListener參數,并在方法的内部開啟了一個(gè)子(zǐ)線程,然後
在子(zǐ)線程裡去執行具體的網絡操作。注意子(zǐ)線程中(zhōng)是無法通(tōng)過return語句來返回數據的,因此這裡我們将服務器(qì)響應的數據傳入了HttpCallbackListener的onFinish()方法中(zhōng),如(rú)果出現了異常就将異常原因傳入到onError()方法中(zhōng)。
  現在sendHttpRequest方法接收兩個(gè)參數了,因此我們在調用它的時候還需要将HttpCallbackListener的實例傳入
  如(rú)下(xià)所示:
HttpUtil.sendHttpRequest(address,new HttpCallbackListener(){
   public void onFinish(String response){
   //在這裡根據返回内容執行具體的邏輯
   }
   
   public void onError(Exception e){
      //在這裡對異常進行處理
   }
   
  });

這樣的話,當服務器(qì)成功響應的時候我們就可(kě)以在onFinish方法裡對響應數據進行處理了,類似地,如(rú)果出現了異常,就可(kě)以在onError方法裡對異常情況進行處理。如(rú)此一來,我們就巧妙的利用回調機制将響應數據成功返回給調用方了。
  另外需要注意的是,onFinish方法和(hé)onError方法最終還是在子(zǐ)線程中(zhōng)運行的,因此我們不可(kě)以在這裡執行任何的
  UI操作,如(rú)果需要根據返回的結果來更新UI,則仍然要使用異步消息處理機制。

http://blog.csdn.net/j903829182/article/details/42521437

相關(guān)案例查看更多