Java tutorial
/* * Copyright (C) 2010 mAPPn.Inc * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.mappn.gfan.common; import java.io.IOException; import java.io.UnsupportedEncodingException; import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; import org.apache.http.HttpStatus; import org.apache.http.ParseException; import org.apache.http.client.methods.HttpUriRequest; import org.apache.http.entity.StringEntity; import org.apache.http.util.EntityUtils; import android.app.Activity; import android.content.Context; import android.os.AsyncTask; import com.mappn.gfan.Session; import com.mappn.gfan.common.util.Utils; /** * API * * @author andrew.wang * @date 2010-10-27 * @since Version 0.4.0 */ public class ApiAsyncTask extends AsyncTask<Void, Void, Object> { // public static final int TIMEOUT_ERROR = 600; // public static final int BUSSINESS_ERROR = 610; private AndroidHttpClient mClient; private int mReuqestAction; private ApiRequestListener mHandler; private Object mParameter; private Session mSession; private Context mContext; private ResponseCacheManager mResponseCache; ApiAsyncTask(Context context, int action, ApiRequestListener handler, Object param) { this.mContext = context; this.mSession = Session.get(context); this.mReuqestAction = action; this.mHandler = handler; this.mParameter = param; this.mResponseCache = ResponseCacheManager.getInstance(); this.mClient = HttpClientFactory.get().getHttpClient(); } @Override protected Object doInBackground(Void... params) { if (!Utils.isNetworkAvailable(mContext)) { return TIMEOUT_ERROR; } String requestUrl = MarketAPI.API_URLS[mReuqestAction]; HttpEntity requestEntity = null; try { requestEntity = ApiRequestFactory.getRequestEntity(mReuqestAction, mParameter); } catch (UnsupportedEncodingException e) { Utils.D("OPPS...This device not support UTF8 encoding.[should not happend]"); return BUSSINESS_ERROR; } Object result = null; // String cacheKey = ""; if (!ApiRequestFactory.API_NO_CACHE_MAP.contains(mReuqestAction)) { final boolean isBodyEmpty = (requestEntity == null); if (isBodyEmpty) { // if no http entity then directly use the request url as cache key cacheKey = Utils.getMD5(requestUrl); } else { // we only cache string request if (requestEntity instanceof StringEntity) { try { cacheKey = Utils.getMD5(requestUrl + EntityUtils.toString(requestEntity)); } catch (ParseException e) { Utils.W("have ParseException when get cache key", e); } catch (IOException e) { Utils.W("have IOException when get cache key", e); } } } // fetch result from the cache result = mResponseCache.getResponse(cacheKey); if (result != null) { Utils.V("retrieve response from the cache"); return result; } } HttpResponse response = null; HttpUriRequest request = null; try { request = ApiRequestFactory.getRequest(requestUrl, mReuqestAction, requestEntity, mSession); response = mClient.execute(request); final int statusCode = response.getStatusLine().getStatusCode(); Utils.D("requestUrl " + requestUrl + " statusCode: " + statusCode); if (HttpStatus.SC_OK != statusCode) { // ? return statusCode; } // fetch result from remote server result = ApiResponseFactory.getResponse(mContext, mReuqestAction, response); if (result != null && !ApiRequestFactory.API_NO_CACHE_MAP.contains(mReuqestAction)) { mResponseCache.putResponse(cacheKey, result); } // ?API Response?BUSSINESS_ERROR?610 return result == null ? BUSSINESS_ERROR : result; } catch (IOException e) { Utils.D("Market API encounter the IO exception[mostly is timeout exception]", e); return TIMEOUT_ERROR; } finally { // release the connection if (request != null) { request.abort(); } if (response != null) { try { HttpEntity entity = response.getEntity(); if (entity != null) { entity.consumeContent(); } } catch (IOException e) { Utils.D("release low-level resource error"); } } } } @Override protected void onPostExecute(Object response) { if (mHandler == null) { return; } if (mContext instanceof Activity && ((Activity) mContext).isFinishing()) { // ???? return; } if (response == null) { mHandler.onError(this.mReuqestAction, BUSSINESS_ERROR); return; } else if (response instanceof Integer) { Integer statusCode = (Integer) response; if (!handleCommonError(statusCode)) { mHandler.onError(this.mReuqestAction, (Integer) response); return; } } mHandler.onSuccess(this.mReuqestAction, response); } // 225 ?? public static final int SC_DATA_NOT_EXIST = 225; // 232 ?? public static final int SC_ILLEGAL_COMMENT = 232; // 421 ???User-Agent public static final int SC_ILLEGAL_USER_AGENT = 421; // 422 xml? public static final int SC_XML_ERROR = 422; // 423 xml?? public static final int SC_XML_PARAMS_ERROR = 423; // 427 ? public static final int SC_ENCODE_ERROR = 427; // 520 DBSQL public static final int SC_SERVER_DB_ERROR = 520; /** * ?Http Status Code * @param statusCode Http Status Code * @return Code??True?? */ private boolean handleCommonError(int statusCode) { if (statusCode == 200) { return true; } // if(statusCode >= TIMEOUT_ERROR) { // Utils.makeEventToast(mContext, mContext.getString(R.string.notification_server_error), // false); // } else if(statusCode >= HttpStatus.SC_INTERNAL_SERVER_ERROR) { // Utils.makeEventToast(mContext, mContext.getString(R.string.notification_server_error), // false); // } else if(statusCode >= HttpStatus.SC_BAD_REQUEST) { // Utils.makeEventToast(mContext, mContext.getString(R.string.notification_client_error), // false); // } return false; } /** * API? * * @author andrew.wang * @date 2010-10-28 * @since Version 0.4.0 */ public interface ApiRequestListener { /** * The CALLBACK for success aMarket API HTTP response * * @param response * the HTTP response */ void onSuccess(int method, Object obj); /** * The CALLBACK for failure aMarket API HTTP response * * @param statusCode * the HTTP response status code */ void onError(int method, int statusCode); } }