編輯:關於Android編程
由於 AndroidAsyncHttp 1.4.4 的 JsonHttpResponseHandler 存在死循環的 BUG,1.4.5 版本發布不知道要何時,所以只能臨時替換該類來修復這個錯誤。
Android開源庫loopj的android-async-http的 JsonHttpResponseHandler 存在死循環GC_CONCURRENT
package com.ai9475.extend; import com.ai9475.meitian.AppManager; import com.ai9475.meitian.R; import com.loopj.android.http.JsonHttpResponseHandler; import android.app.AlertDialog; import android.content.DialogInterface; import android.util.Log; import org.apache.http.Header; import org.apache.http.HttpStatus; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; import org.json.JSONTokener; import java.io.UnsupportedEncodingException; /** * 復寫 AndroidAsyncHttp 1.4.4 開源庫的 JsonHttpResponseHandler 類 * 當 1.4.5 released 後失效 * * Created by ZHOUZ on 2014/3/22. */ public class ZJsonHttpResponseHandler extends JsonHttpResponseHandler { private static final String LOG_TAG = "JsonHttpResponseHandler"; /** * Returns when request succeeds * * @param statusCode http response status line * @param headers response headers if any * @param response parsed response if any */ public void onSuccess(int statusCode, Header[] headers, JSONObject response) { } /** * Returns when request succeeds * * @param statusCode http response status line * @param headers response headers if any * @param response parsed response if any */ public void onSuccess(int statusCode, Header[] headers, JSONArray response) { } /** * Returns when request failed * * @param statusCode http response status line * @param headers response headers if any * @param throwable throwable describing the way request failed * @param errorResponse parsed response if any */ public void onFailure(int statusCode, Header[] headers, Throwable throwable, JSONObject errorResponse) { } /** * Returns when request failed * * @param statusCode http response status line * @param headers response headers if any * @param throwable throwable describing the way request failed * @param errorResponse parsed response if any */ public void onFailure(int statusCode, Header[] headers, Throwable throwable, JSONArray errorResponse) { } @Override public void onFailure(int statusCode, Header[] headers, String responseString, Throwable throwable) { final AlertDialog.Builder dialog = new AlertDialog.Builder(AppManager.ActivityManager.current()); dialog.setIcon(android.R.drawable.ic_dialog_info); dialog.setTitle(R.string.app_error); dialog.setMessage(responseString); dialog.setNegativeButton(R.string.sure, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { dialog.dismiss(); } }); dialog.show(); } @Override public void onSuccess(int statusCode, Header[] headers, String responseString) { } @Override public final void onSuccess(final int statusCode, final Header[] headers, final byte[] responseBytes) { if (statusCode != HttpStatus.SC_NO_CONTENT) { new Thread(new Runnable() { @Override public void run() { try { final Object jsonResponse = parseResponse(responseBytes); postRunnable(new Runnable() { @Override public void run() { if (jsonResponse instanceof JSONObject) { onSuccess(statusCode, headers, (JSONObject) jsonResponse); } else if (jsonResponse instanceof JSONArray) { onSuccess(statusCode, headers, (JSONArray) jsonResponse); } else if (jsonResponse instanceof String) { onFailure(statusCode, headers, (String) jsonResponse, new JSONException("Response cannot be parsed as JSON data")); } else { onFailure(statusCode, headers, new JSONException("Unexpected response type " + jsonResponse.getClass().getName()), (JSONObject) null); } } }); } catch (final JSONException ex) { postRunnable(new Runnable() { @Override public void run() { onFailure(statusCode, headers, ex, (JSONObject) null); } }); } } }).start(); } else { onSuccess(statusCode, headers, new JSONObject()); } } @Override public final void onFailure(final int statusCode, final Header[] headers, final byte[] responseBytes, final Throwable throwable) { if (responseBytes != null) { new Thread(new Runnable() { @Override public void run() { try { final Object jsonResponse = parseResponse(responseBytes); postRunnable(new Runnable() { @Override public void run() { if (jsonResponse instanceof JSONObject) { onFailure(statusCode, headers, throwable, (JSONObject) jsonResponse); } else if (jsonResponse instanceof JSONArray) { onFailure(statusCode, headers, throwable, (JSONArray) jsonResponse); } else if (jsonResponse instanceof String) { onFailure(statusCode, headers, (String) jsonResponse, throwable); } else { onFailure(statusCode, headers, new JSONException("Unexpected response type " + jsonResponse.getClass().getName()), (JSONObject) null); } } }); } catch (final JSONException ex) { postRunnable(new Runnable() { @Override public void run() { onFailure(statusCode, headers, ex, (JSONObject) null); } }); } } }).start(); } else { Log.v(LOG_TAG, "response body is null, calling onFailure(Throwable, JSONObject)"); onFailure(statusCode, headers, throwable, (JSONObject) null); } } /** * Returns Object of type {@link JSONObject}, {@link JSONArray}, String, Boolean, Integer, Long, * Double or {@link JSONObject#NULL}, see {@link org.json.JSONTokener#nextValue()} * * @param responseBody response bytes to be assembled in String and parsed as JSON * @return Object parsedResponse * @throws org.json.JSONException exception if thrown while parsing JSON */ protected Object parseResponse(byte[] responseBody) throws JSONException { if (null == responseBody) return null; Object result = null; //trim the string to prevent start with blank, and test if the string is valid JSON, because the parser don't do this :(. If Json is not valid this will return null String jsonString = getResponseString(responseBody, getCharset()); if (jsonString != null) { jsonString = jsonString.trim(); if (jsonString.startsWith("{") || jsonString.startsWith("[")) { result = new JSONTokener(jsonString).nextValue(); } } if (result == null) { result = jsonString; } return result; } /** * Attempts to encode response bytes as string of set encoding * * @param charset charset to create string with * @param stringBytes response bytes * @return String of set encoding or null */ public static String getResponseString(byte[] stringBytes, String charset) { try { return stringBytes == null ? null : new String(stringBytes, charset); } catch (UnsupportedEncodingException e) { Log.e(LOG_TAG, "Encoding response into string failed", e); return null; } } }
首先apk不能被代碼混淆(或未經編譯優化),如果混淆了,反編譯出來的代號還是看不懂, 當然,在你沒反編譯出來之前,你也不知道有沒有混淆。 網上各種反編譯工具,&
前言最近開發的一個產品需要涉及到訂單,訂單頁涉及到了一個UI元素,類似餓了麼的訂單頁以及支付寶口碑外賣訂單頁的彩帶(通俗點講就是一條兩種顏色相間而成的分割線): 
上節中我們是手動拼接xml文件,但是上節中那樣的做法會有一個問題,比如: //插入消息的內容sBuffer.append(); sBuffer.append(s
在開發應用程序的時候,經常會遇到這樣的情況,會在運行時動態根據條件來決定顯示哪個View或某個布局。那麼最通常的想法就是把可能用到的View都寫在上面,先把它們的可見性都