之前一直在用HTML5开发移动本地应用,后来发现,实际上HTML5开发的本地应用,开发效率高,而且跨平台,但是体验,相应无法和原生应用,还有一定差距。
开发HTML5和远程交互,采用JSONP,是异步方式。Android的异步方式不太一样,采用的是多线程和Handler的方式处理。
1 首先是HttpConnection,方法包括HttPost, HttpGet
package com.juupoo.common; import java.util.ArrayList; import java.util.List; import org.apache.http.HttpResponse; import org.apache.http.NameValuePair; import org.apache.http.client.HttpClient; import org.apache.http.client.entity.UrlEncodedFormEntity; import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpPost; import org.apache.http.impl.client.DefaultHttpClient; import org.apache.http.message.BasicNameValuePair; import org.apache.http.params.BasicHttpParams; import org.apache.http.params.HttpConnectionParams; import org.apache.http.params.HttpParams; import org.apache.http.util.EntityUtils; import android.os.Bundle; import android.os.Handler; import android.os.Message; /** * Asynchronous HTTP connections * * @author Greg Zavitz & Joseph Roth */ public class HttpConnection implements Runnable { public static final int DID_START = 0; public static final int DID_ERROR = 1; public static final int DID_SUCCEED = 2; private static final int GET = 0; private static final int POST = 1; private static final int PUT = 2; private static final int DELETE = 3; private static final int BITMAP = 4; private String url; private int method; private String data; private CallbackListener listener; private HttpClient httpClient; // public HttpConnection() { // this(new Handler()); // } public void create(int method, String url, String data, CallbackListener listener) { this.method = method; this.url = url; this.data = data; this.listener = listener; ConnectionManager.getInstance().push(this); } public void get(String url) { create(GET, url, null, listener); } public void post(String url, String data, CallbackListener listener) { create(POST, url, data, listener); } public void put(String url, String data) { create(PUT, url, data, listener); } public void delete(String url) { create(DELETE, url, null, listener); } public void bitmap(String url) { create(BITMAP, url, null, listener); } public interface CallbackListener { public void callBack(String result); } private static final Handler handler = new Handler() { @Override public void handleMessage(Message message) { switch (message.what) { case HttpConnection.DID_START: { break; } case HttpConnection.DID_SUCCEED: { CallbackListener listener = (CallbackListener) message.obj; Object data = message.getData(); if (listener != null) { if(data != null) { Bundle bundle = (Bundle)data; String result = bundle.getString("callbackkey"); listener.callBack(result); } } break; } case HttpConnection.DID_ERROR: { break; } } } }; public void run() { // handler.sendMessage(Message.obtain(handler, HttpConnection.DID_START)); httpClient = getHttpClient(); try { HttpResponse httpResponse = null; switch (method) { case GET: httpResponse = httpClient.execute(new HttpGet( StaticInfos.Server_URL + url)); break; case POST: HttpPost httpPost = new HttpPost(StaticInfos.Server_URL + url); List<NameValuePair> params = new ArrayList<NameValuePair>(); BasicNameValuePair valuesPair = new BasicNameValuePair("args", data); params.add(valuesPair); httpPost.setEntity(new UrlEncodedFormEntity(params, "UTF-8")); httpResponse = httpClient.execute(httpPost); if (isHttpSuccessExecuted(httpResponse)) { String result = EntityUtils.toString(httpResponse .getEntity()); this.sendMessage(result); } else { this.sendMessage("fail"); } break; } } catch (Exception e) { this.sendMessage("fail"); } ConnectionManager.getInstance().didComplete(this); } // private void processBitmapEntity(HttpEntity entity) throws IOException { // BufferedHttpEntity bufHttpEntity = new BufferedHttpEntity(entity); // Bitmap bm = BitmapFactory.decodeStream(bufHttpEntity.getContent()); // handler.sendMessage(Message.obtain(handler, DID_SUCCEED, bm)); // } private void sendMessage(String result) { Message message = Message.obtain(handler, DID_SUCCEED, listener); Bundle data = new Bundle(); data.putString("callbackkey", result); message.setData(data); handler.sendMessage(message); } public static DefaultHttpClient getHttpClient() { HttpParams httpParams = new BasicHttpParams(); HttpConnectionParams.setConnectionTimeout(httpParams, 20000); HttpConnectionParams.setSoTimeout(httpParams, 20000); // HttpConnectionParams.setSocketBufferSize(httpParams, 8192); DefaultHttpClient httpClient = new DefaultHttpClient(httpParams); return httpClient; } public static boolean isHttpSuccessExecuted(HttpResponse response) { int statusCode = response.getStatusLine().getStatusCode(); return (statusCode > 199) && (statusCode < 400); } }
2 ConnectionManager类,将线程添加到队列中
package com.juupoo.common; import java.util.ArrayList; /** * Simple connection manager to throttle connections * * @author Greg Zavitz */ public class ConnectionManager { public static final int MAX_CONNECTIONS = 5; private ArrayList<Runnable> active = new ArrayList<Runnable>(); private ArrayList<Runnable> queue = new ArrayList<Runnable>(); private static ConnectionManager instance; public static ConnectionManager getInstance() { if (instance == null) instance = new ConnectionManager(); return instance; } public void push(Runnable runnable) { queue.add(runnable); if (active.size() < MAX_CONNECTIONS) startNext(); } private void startNext() { if (!queue.isEmpty()) { Runnable next = queue.get(0); queue.remove(0); active.add(next); Thread thread = new Thread(next); thread.start(); } } public void didComplete(Runnable runnable) { active.remove(runnable); startNext(); } }
3 调用:
new HttpConnection().post("user.login", args, callbackListener); private CallbackListener callbackListener = new HttpConnection.CallbackListener() { @Override public void callBack(String v) { if(v != "fail") { if("false".equals(v)) { LoginActivity.this.showInfo(R.string.username_or_pass_error); } else { // 登录 Intent intent = new Intent(); intent.setClass(LoginActivity.this, MainActivity.class); LoginActivity.this.startActivity(intent); } } else { LoginActivity.this.showInfo(R.string.network_transfer_error); } progressDialog.dismiss(); } };