国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 系統(tǒng) > Android > 正文

Android最基本的異步網(wǎng)絡(luò)請求框架

2019-12-12 06:32:42
字體:
供稿:網(wǎng)友

 本篇文章我們來一起寫一個最基本的Android異步網(wǎng)絡(luò)請求框架,借此來了解下Android中網(wǎng)絡(luò)請求的相關(guān)知識。由于個人水平有限,文中難免存在疏忽和謬誤,希望大家可以指出,謝謝大家。

1. 同步網(wǎng)絡(luò)請求

    以HTTP的GET請求為例,我們來介紹一下Android中一個基本的同步請求框架的實現(xiàn)。直接貼代碼:

public class HttpUtils { public static byte[] get(String urlString) {  HttpURLConnection urlConnection = null;  try {   URL url = new URL(urlString);   urlConnection = (HttpURLConnection) url.openConnection();   //設(shè)置請求方法   urlConnection.setRequestMethod("GET");   //設(shè)置超時時間   urlConnection.setConnectTimeout(5000);   urlConnection.setReadTimeout(3000);   //獲取響應(yīng)的狀態(tài)碼   int responseCode = urlConnection.getResponseCode();   if (responseCode == 200) {    ByteArrayOutputStream bos = new ByteArrayOutputStream();    InputStream in = urlConnection.getInputStream();    byte[] buffer = new byte[4 * 1024];    int len = -1;    while((len = in.read(buffer)) != -1) {     bos.write(buffer, 0, len);    }    close(in);    byte[] result = bos.toByteArray();    close(bos);    return result;   } else {    return null;   }  } catch (Exception e) {   e.printStackTrace();  } finally {   if (urlConnection != null) {    urlConnection.disconnect();   }  }  return null; } private static void close(Closeable stream) {  if (stream != null) {   try {    stream.close();   } catch (IOException e) {    e.printStackTrace();   }  } }} 

    相信以上的代碼我們大家都不陌生,以上代碼就實現(xiàn)了基本的同步網(wǎng)絡(luò)請求功能,get 方法會返回一個byte[]數(shù)組,后續(xù)我們可以根據(jù)返回的相應(yīng)類型(文本或圖片)對這個字節(jié)數(shù)組作進一步處理。 

2. 異步網(wǎng)絡(luò)請求

    通常一個異步HTTP GET請求是這樣的:發(fā)出get方法的調(diào)用后,相關(guān)任務(wù)會在后臺線程中自動執(zhí)行,而我們在主線程中繼續(xù)處理其他工作,它成功獲取GET請求的響應(yīng)時,就會回調(diào)onSuccess方法。最直接的寫法通常如下所示:

public class AsyncHttpUtils {public static byte[] get(String url, ResponseHandler handler) {  final Handler mHandler = new Handler();  new Thread(new Runnable() {   @Override   public void run() {    final byte[] result = HttpUtils.get(url);    handler.post(new Runnable() {     @Override     public void run() {      responseHandler.onSuccess(result);     }    });   }  }); }} 

       其中,ResponseHandler接口的定義如下:

public interface ResponseHandler { void onSucess(bytep[] result);} 

    我們可以看到,以上實現(xiàn)異步GET請求的代碼很直截了當(dāng),然而存在著以下問題:每次請求時都會創(chuàng)建一個線程,這樣當(dāng)請求比較頻繁的情況下會創(chuàng)建大量大線程,這樣的話創(chuàng)建、銷毀線程以及線程調(diào)度的開銷會很大。而且Thread對象是一個匿名內(nèi)部類對象,會隱式持有外圍類引用,可能會引起Memory Leak。

    針對以上問題,我們可以使用線程池來復(fù)用線程,以避免不必要的創(chuàng)建及銷毀線程的開銷,改進后AsyncHttpUtils類的代碼如下:

public class AsyncHttpUtils { //獲取當(dāng)前設(shè)備的CPU數(shù) public static final int CPU_COUNT = Runtime.getRuntime().availableProcessors(); //核心池大小設(shè)為CPU數(shù)加1 private static final int CORE_POOL_SIZE = CPU_COUNT + 1; //設(shè)置線程池的最大大小 private static final int MAX_POOL_SIZE = 2 * CPU_COUNT + 1; //存活時間 private static final long KEEP_ALIVE = 5L;  //創(chuàng)建線程池對象 public static final Executor threadPoolExecutor = new ThreadPoolExecutor(CORE_POOL_SIZE,   MAX_POOL_SIZE, KEEP_ALIVE, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>()); public static void get(final String url, final ResponseHandler responseHandler) {  final Handler mHandler = new Handler(Looper.getMainLooper());    //創(chuàng)建一個新的請求任務(wù)  Runnable requestRunnable = new Runnable() {   @Override   public void run() {    final byte[] result = HttpUtils.get(url);    if (result != null) {     mHandler.post(new Runnable() {      @Override      public void run() {       //result不為空表明請求成功,回調(diào)onSuccess方法       responseHandler.onSuccess(result);      }     });    }   }  };  threadPoolExecutor.execute(requestRunnable); }}

以上代碼主要就是使用了線程池來達到線程的復(fù)用的目的,希望本文所述對大家學(xué)習(xí)Android軟件編程有所幫助。

發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 昌图县| 当雄县| 柘荣县| 武定县| 鄂州市| 鄂伦春自治旗| 澄迈县| 和林格尔县| 正定县| 曲周县| 综艺| 乐清市| 河南省| 霍林郭勒市| 金寨县| 乌兰浩特市| 涟水县| 西吉县| 泾阳县| 南安市| 塘沽区| 松原市| 当阳市| 巴塘县| 襄垣县| 涿州市| 黄大仙区| 凌源市| 于田县| 崇州市| 乐都县| 灵武市| 涿州市| 广元市| 安顺市| 嘉荫县| 佛坪县| 调兵山市| 五家渠市| 张家港市| 长宁区|