android-async-http是一個強大的第三方開源網絡請求庫,php
官網源碼:https://github.com/loopj/android-async-httphtml
官網教程:http://loopj.com/android-async-http/java
這個網絡請求庫是基於Apache HttpClient庫之上的一個異步網絡請求處理庫,網絡處理均基於Android的非UI線程,經過回調方法處理請求結果。android
主要類介紹git
AsyncHttpRequestgithub
繼承自Runnabler,被submit至線程池執行網絡請求併發送start,success等消息apache
AsyncHttpResponseHandlerjson
接收請求結果,通常重寫onSuccess及onFailure接收請求成功或失敗的消息,還有onStart,onFinish等消息數組
TextHttpResponseHandler服務器
繼承自AsyncHttpResponseHandler,只是重寫了AsyncHttpResponseHandler的onSuccess和onFailure方法,將請求結果由byte數組轉換爲String
JsonHttpResponseHandler
繼承自TextHttpResponseHandler,一樣是重寫onSuccess和onFailure方法,將請求結果由String轉換爲JSONObject或JSONArray
BaseJsonHttpResponseHandler
繼承自TextHttpResponseHandler,是一個泛型類,提供了parseResponse方法,子類須要提供實現,將請求結果解析成須要的類型,子類能夠靈活地使用解析方法,能夠直接原始解析,使用gson等。
RequestParams
請求參數,能夠添加普通的字符串參數,並可添加File,InputStream上傳文件
AsyncHttpClient
核心類,使用HttpClient執行網絡請求,提供了get,put,post,delete,head等請求方法,使用起來很簡單,只需以url及RequestParams調用相應的方法便可,還能夠選擇性地傳入Context,用於取消Content相關的請求,同時必須提供ResponseHandlerInterface(AsyncHttpResponseHandler繼承自ResponseHandlerInterface)的實現類,通常爲AsyncHttpResponseHandler的子類,AsyncHttpClient內部有一個線程池,當使用AsyncHttpClient執行網絡請求時,最終都會調用sendRequest方法,在這個方法內部將請求參數封裝成AsyncHttpRequest(繼承自Runnable)交由內部的線程池執行。
SyncHttpClient
繼承自AsyncHttpClient,同步執行網絡請求,AsyncHttpClient把請求封裝成AsyncHttpRequest後提交至線程池,SyncHttpClient把請求封裝成AsyncHttpRequest後直接調用它的run方法。
服務器端php測試代碼:
<?php $data = array( 'status'=>'success', 'get'=>json_encode($_GET), 'post'=>json_encode($_POST), 'upload'=>json_encode($_FILES) ); echo json_encode($data); ?>
android客戶端測試代碼:
package com.penngo.http; import com.loopj.android.http.AsyncHttpClient; import com.loopj.android.http.AsyncHttpResponseHandler; import com.loopj.android.http.FileAsyncHttpResponseHandler; import com.loopj.android.http.RequestParams; public class HttpUtil { private static final String BASE_URL = "http://192.168.17.99/"; private static AsyncHttpClient client = new AsyncHttpClient(); public static void setTimeout(){ client.setTimeout(60000); } public static void get(String url, RequestParams params, AsyncHttpResponseHandler responseHandler) { client.get(getAbsoluteUrl(url), params, responseHandler); } public static void post(String url, RequestParams params, AsyncHttpResponseHandler responseHandler) { client.post(getAbsoluteUrl(url), params, responseHandler); } public static void download(String url, RequestParams params, FileAsyncHttpResponseHandler fileAsyncHttpResponseHandler){ client.get(getAbsoluteUrl(url), params, fileAsyncHttpResponseHandler); } private static String getAbsoluteUrl(String relativeUrl) { return BASE_URL + relativeUrl; } }
package com.penngo.http; import android.app.Activity; import android.os.Bundle; import android.util.Log; import android.view.View; import android.widget.Button; import com.loopj.android.http.FileAsyncHttpResponseHandler; import com.loopj.android.http.RequestParams; import com.loopj.android.http.TextHttpResponseHandler; import org.apache.http.Header; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.util.Locale; public class MainActivity extends Activity { private final static String tag = "MainActivity-->"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Button getBtn = (Button)this.findViewById(R.id.getBtn); getBtn.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { testGet(); } }); Button postBtn = (Button)this.findViewById(R.id.postBtn); postBtn.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { testPost(); } }); Button upLoadBtn = (Button)this.findViewById(R.id.upLoadBtn); upLoadBtn.setOnClickListener(new View.OnClickListener(){ public void onClick(View v){ testUploadFile(); } }); Button downloadBtn = (Button)this.findViewById(R.id.downloadBtn); downloadBtn.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { testDownloadFile(); } }); } private void testGet(){ HttpUtil.get("test/android.php", getParames(), responseHandler); } private RequestParams getParames(){ RequestParams params = new RequestParams(); params.put("user", "penngo"); params.put("psw", "penngo"); return params; } private TextHttpResponseHandler responseHandler = new TextHttpResponseHandler(){ @Override public void onStart() { Log.e(tag, "onStart===="); } @Override public void onSuccess(int statusCode, Header[] headers, String response) { Log.e(tag, "onSuccess===="); StringBuilder builder = new StringBuilder(); for (Header h : headers) { String _h = String.format(Locale.US, "%s : %s", h.getName(), h.getValue()); builder.append(_h); builder.append("\n"); } Log.e(tag, "statusCode:" + statusCode + " headers:" + builder.toString() + " response:" + response); } @Override public void onFailure(int statusCode, Header[] headers, String errorResponse, Throwable e) { Log.e(tag, "onFailure===="); StringBuilder builder = new StringBuilder(); for (Header h : headers) { String _h = String.format(Locale.US, "%s : %s", h.getName(), h.getValue()); builder.append(_h); builder.append("\n"); } Log.e(tag, "statusCode:" + statusCode + " headers:" + builder.toString(), e); } @Override public void onRetry(int retryNo) { // called when request is retried } }; private void testPost(){ HttpUtil.post("test/android.php", getParames(), responseHandler); } private void testUploadFile(){ RequestParams params = new RequestParams(); try { InputStream is = this.getAssets().open("png/launcher.png"); String png = this.getExternalCacheDir().getAbsolutePath() + "/launcher.png"; File myFile = new File(png); Log.e(tag, "png====" + png); this.copyToSD(png, "png/launcher.png"); params.put("pngFile", myFile, RequestParams.APPLICATION_OCTET_STREAM); } catch(Exception e) { Log.e(tag,"上傳失敗", e); } HttpUtil.post("test/android.php", params, responseHandler); } private void testDownloadFile(){ String mp3 = this.getExternalCacheDir().getAbsolutePath() + "/fa.mp3"; File mp3File = new File(mp3); FileAsyncHttpResponseHandler fileHandler = new FileAsyncHttpResponseHandler(mp3File){ public void onSuccess(int statusCode, Header[] headers, File file){ Log.e(tag, "onSuccess===="); StringBuilder builder = new StringBuilder(); for (Header h : headers) { String _h = String.format(Locale.US, "%s : %s", h.getName(), h.getValue()); builder.append(_h); builder.append("\n"); } Log.e(tag, "statusCode:" + statusCode + " headers:" + builder.toString() + " file:" + file.getAbsolutePath()); } public void onFailure(int statusCode, Header[] headers, Throwable throwable, File file){ } }; HttpUtil.download("test/fa.mp3", null, fileHandler); } /** * 複製文件到sdcard */ private void copyToSD(String strOut, String srcInput) throws IOException { InputStream myInput; OutputStream myOutput = new FileOutputStream(strOut); myInput = this.getAssets().open(srcInput); byte[] buffer = new byte[1024]; int length = myInput.read(buffer); while(length > 0) { myOutput.write(buffer, 0, length); length = myInput.read(buffer); } myOutput.flush(); myInput.close(); myOutput.close(); } }
執行輸出結果:
E/MainActivity-->﹕ onStart====
E/MainActivity-->﹕ onSuccess====
E/MainActivity-->﹕ statusCode:200 headers:Date : Wed, 05 Aug 2015 04:30:00 GMT
Server : Apache/2.2.25 (Win32) mod_ssl/2.2.25 OpenSSL/0.9.8y mod_wsgi/3.3 Python/2.7.3
X-Powered-By : ZendServer 6.3.0
Set-Cookie : ZDEDebuggerPresent=php,phtml,php3; path=/
Keep-Alive : timeout=5, max=100
Connection : Keep-Alive
Transfer-Encoding : chunked
Content-Type : text/html
response:{"status":"success","get":"{\"user\":\"penngo\",\"psw\":\"penngo\"}","post":"[]","upload":"[]"}
E/MainActivity-->﹕ onStart====
E/MainActivity-->﹕ onSuccess====
E/MainActivity-->﹕ statusCode:200 headers:Date : Wed, 05 Aug 2015 04:30:15 GMT
Server : Apache/2.2.25 (Win32) mod_ssl/2.2.25 OpenSSL/0.9.8y mod_wsgi/3.3 Python/2.7.3
X-Powered-By : ZendServer 6.3.0
Set-Cookie : ZDEDebuggerPresent=php,phtml,php3; path=/
Keep-Alive : timeout=5, max=100
Connection : Keep-Alive
Transfer-Encoding : chunked
Content-Type : text/html
response:{"status":"success","get":"[]","post":"{\"user\":\"penngo\",\"psw\":\"penngo\"}","upload":"[]"}
E/MainActivity-->﹕ png====/mnt/sdcard/Android/data/com.penngo.http/cache/launcher.png
E/MainActivity-->﹕ onStart====
E/MainActivity-->﹕ onSuccess====
E/MainActivity-->﹕ statusCode:200 headers:Date : Wed, 05 Aug 2015 04:30:24 GMT
Server : Apache/2.2.25 (Win32) mod_ssl/2.2.25 OpenSSL/0.9.8y mod_wsgi/3.3 Python/2.7.3
X-Powered-By : ZendServer 6.3.0
Set-Cookie : ZDEDebuggerPresent=php,phtml,php3; path=/
Keep-Alive : timeout=5, max=100
Connection : Keep-Alive
Transfer-Encoding : chunked
Content-Type : text/html
response:{"status":"success","get":"[]","post":"[]","upload":"{\"pngFile\":{\"name\":\"launcher.png\",\"type\":\"application\\\/octet-stream\",\"tmp_name\":\"C:\\\\Windows\\\\Temp\\\\phpFDC4.tmp\",\"error\":0,\"size\":3418}}"}
E/MainActivity-->﹕ onSuccess====
E/MainActivity-->﹕ statusCode:200 headers:Date : Wed, 05 Aug 2015 04:30:30 GMT
Server : Apache/2.2.25 (Win32) mod_ssl/2.2.25 OpenSSL/0.9.8y mod_wsgi/3.3 Python/2.7.3
Last-Modified : Fri, 19 Dec 2014 08:10:00 GMT
ETag : "13200000000a25c-4776aa-50a8d3c355700"
Accept-Ranges : bytes
Content-Length : 4683434
Keep-Alive : timeout=5, max=100
Connection : Keep-Alive
Content-Type : audio/mpeg
file:/mnt/sdcard/Android/data/com.penngo.http/cache/fa.mp3