android學習二十四(網絡編程的(de)最佳實踐) - 新聞資訊 - 雲南小程序開發|雲南軟件開發|雲南網站建設-昆明融晨信息技術有限公司

159-8711-8523

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

知識

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

您當前位置>首頁 » 新聞資訊 » 技術分享 >

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

發表時(shí)間:2021-1-10

發布人(rén):融晨科技

浏覽次數:57


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

以(yǐ)後每當要(yào / yāo)發起一條HTTP請求的(de)時(shí)候就(jiù)可以(yǐ)這(zhè)樣寫:
  String address="http://www.baidu.com";
  String response=HttpUtil.sendHttpRequest(address);



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

       接着修改HttpUtil中的(de)代碼:
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方法添加了(le/liǎo)一個(gè)HttpCallbackListener參數,并在(zài)方法的(de)内部開啓了(le/liǎo)一個(gè)子(zǐ)線程,然後
在(zài)子(zǐ)線程裏去執行具體的(de)網絡操作。注意子(zǐ)線程中是(shì)無法通過return語句來(lái)返回數據的(de),因此這(zhè)裏我們将服務器響應的(de)數據傳入了(le/liǎo)HttpCallbackListener的(de)onFinish()方法中,如果出(chū)現了(le/liǎo)異常就(jiù)将異常原因傳入到(dào)onError()方法中。
  現在(zài)sendHttpRequest方法接收兩個(gè)參數了(le/liǎo),因此我們在(zài)調用它的(de)時(shí)候還需要(yào / yāo)将HttpCallbackListener的(de)實例傳入
  如下所示:
HttpUtil.sendHttpRequest(address,new HttpCallbackListener(){
   public void onFinish(String response){
   //在(zài)這(zhè)裏根據返回内容執行具體的(de)邏輯
   }
   
   public void onError(Exception e){
      //在(zài)這(zhè)裏對異常進行處理
   }
   
  });

這(zhè)樣的(de)話,當服務器成功響應的(de)時(shí)候我們就(jiù)可以(yǐ)在(zài)onFinish方法裏對響應數據進行處理了(le/liǎo),類似地(dì / de),如果出(chū)現了(le/liǎo)異常,就(jiù)可以(yǐ)在(zài)onError方法裏對異常情況進行處理。如此一來(lái),我們就(jiù)巧妙的(de)利用回調機制将響應數據成功返回給調用方了(le/liǎo)。
  另外需要(yào / yāo)注意的(de)是(shì),onFinish方法和(hé / huò)onError方法最終還是(shì)在(zài)子(zǐ)線程中運行的(de),因此我們不(bù)可以(yǐ)在(zài)這(zhè)裏執行任何的(de)
  UI操作,如果需要(yào / yāo)根據返回的(de)結果來(lái)更新UI,則仍然要(yào / yāo)使用異步消息處理機制。

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

相關案例查看更多