Android最基本的異步網(wǎng)絡(luò)請求框架
本篇文章我們來一起寫一個(gè)最基本的Android異步網(wǎng)絡(luò)請求框架,借此來了解下Android中網(wǎng)絡(luò)請求的相關(guān)知識。由于個(gè)人水平有限,文中難免存在疏忽和謬誤,希望大家可以指出,謝謝大家。
1. 同步網(wǎng)絡(luò)請求
以HTTP的GET請求為例,我們來介紹一下Android中一個(gè)基本的同步請求框架的實(shí)現(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è)置超時(shí)時(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();
}
}
}
}
相信以上的代碼我們大家都不陌生,以上代碼就實(shí)現(xiàn)了基本的同步網(wǎng)絡(luò)請求功能,get 方法會返回一個(gè)byte[]數(shù)組,后續(xù)我們可以根據(jù)返回的相應(yīng)類型(文本或圖片)對這個(gè)字節(jié)數(shù)組作進(jìn)一步處理。
2. 異步網(wǎng)絡(luò)請求
通常一個(gè)異步HTTP GET請求是這樣的:發(fā)出get方法的調(diào)用后,相關(guān)任務(wù)會在后臺線程中自動執(zhí)行,而我們在主線程中繼續(xù)處理其他工作,它成功獲取GET請求的響應(yīng)時(shí),就會回調(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);
}
我們可以看到,以上實(shí)現(xiàn)異步GET請求的代碼很直截了當(dāng),然而存在著以下問題:每次請求時(shí)都會創(chuàng)建一個(gè)線程,這樣當(dāng)請求比較頻繁的情況下會創(chuàng)建大量大線程,這樣的話創(chuàng)建、銷毀線程以及線程調(diào)度的開銷會很大。而且Thread對象是一個(gè)匿名內(nèi)部類對象,會隱式持有外圍類引用,可能會引起Memory Leak。
針對以上問題,我們可以使用線程池來復(fù)用線程,以避免不必要的創(chuàng)建及銷毀線程的開銷,改進(jìn)后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;
//存活時(shí)間
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)建一個(gè)新的請求任務(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);
}
}
以上代碼主要就是使用了線程池來達(dá)到線程的復(fù)用的目的,希望本文所述對大家學(xué)習(xí)Android軟件編程有所幫助。
- Android異步消息機(jī)制詳解
- android開發(fā)教程之handle實(shí)現(xiàn)多線程和異步處理
- Android中BroadcastReceiver(異步接收廣播Intent)的使用
- android異步請求服務(wù)器數(shù)據(jù)示例
- Android多線程及異步處理問題詳細(xì)探討
- Android加載對話框同時(shí)異步執(zhí)行實(shí)現(xiàn)方法
- android開發(fā)教程之handler異步更新ui
- Android App中實(shí)現(xiàn)圖片異步加載的實(shí)例分享
- 詳解Android的OkHttp包編寫異步HTTP請求調(diào)用的方法
- 全面總結(jié)Android中線程的異步處理方式
- Android編程實(shí)現(xiàn)異步消息處理機(jī)制的幾種方法總結(jié)
相關(guān)文章
android實(shí)現(xiàn)用戶體驗(yàn)超棒的微信WebView進(jìn)度條
本篇文章主要介紹了android實(shí)現(xiàn)用戶體驗(yàn)超棒的微信WebView進(jìn)度條,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-03-03
Android中通過AsyncTask類來制作炫酷進(jìn)度條的實(shí)例教程
這篇文章主要介紹了Android中通過AsyncTask來制作炫酷進(jìn)度條的實(shí)例教程,借助AsyncTask類的線程操作方法來管理異步任務(wù),需要的朋友可以參考下2016-05-05
android開發(fā)實(shí)踐之ndk編譯命令簡單示例
這篇文章主要給大家介紹了在android中ndk編譯命令使用的相關(guān)資料,文中詳細(xì)介紹了ndk-build命令行參數(shù),并通過簡單的示例代碼給大家介紹了如何編寫 .c 文件,需要的朋友可以參考借鑒,下面來一起看看吧。2017-06-06
Android沉浸式狀態(tài)欄的實(shí)現(xiàn)代碼
這篇文章主要為大家詳細(xì)介紹了Android沉浸式狀態(tài)欄的實(shí)現(xiàn)代碼,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-09-09
Android通過HTTP協(xié)議實(shí)現(xiàn)斷點(diǎn)續(xù)傳下載實(shí)例
本篇文章主要介紹了Android通過HTTP協(xié)議實(shí)現(xiàn)斷點(diǎn)續(xù)傳下載實(shí)例,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下。2017-04-04
android ViewPager實(shí)現(xiàn)自動無限輪播和下方向?qū)A點(diǎn)
本篇文章主要介紹了android ViewPager實(shí)現(xiàn)自動輪播和下方向?qū)A點(diǎn),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下。2017-02-02
android TextView多行文本(超過3行)使用ellipsize屬性無效問題的解決方法
這篇文章介紹了android TextView多行文本(超過3行)使用ellipsize屬性無效問題的解決方法,有需要的朋友可以參考一下2013-09-09

