Android 如何收集已釋出程式的崩潰資訊
我們寫程式的時候都希望能寫出一個沒有任何Bug的程式,期望在任何情況下都不會發生程式崩潰。不過理想是豐滿的,現實是骨感的。沒有一個程式設計師能保證自己寫的程式絕對不會出現異常崩潰。特別是針對使用者數達到幾十萬幾百萬的程式,當你使用者數達到一定數量級後,就算你的程式出現個別異常崩潰情況也不用驚訝。
既然我們寫的程式都有可能發生異常崩潰,如果是還沒釋出的程式,我們可以通過測試抓取Log來分析。不過針對已經發布的程式,我們沒法重現現象,所以讓使用者反饋程式異常資訊就很重要。下面我們說說如何收集程式執行過程的異常資訊。
1、Android異常捕獲介面
複製程式碼 程式碼如下:
//當執行緒因未捕獲的異常而突然終止時,呼叫處理程式的介面
static interface UncaughtExceptionHandler
2、設定執行緒捕獲異常
從上面的介面我們可以看到,這個介面是針對執行緒來說,也就是說我們如果需要監控某個執行緒執行情況,只要把這個介面實現了,然後把監控方法設定到具體的執行緒裡面即可。一般來說,我們最需要監控的就是我們的UI執行緒也就是主執行緒。
複製程式碼 程式碼如下:
//設定當執行緒由於未捕獲到異常而突然終止,並且沒有為該執行緒定義其他處理程式時所呼叫的預設處理程式。
static void setDefaultUncaughtExceptionHandler(Thread.UncaughtExceptionHandler eh)
3、UncaughtExceptionHandler 例項
複製程式碼 程式碼如下:
class MythouCrashHandler implements UncaughtExceptionHandler
{
private static final String TAG = "MythouCrashHandler---->";
private UncaughtExceptionHandler defaultUEH;
//建構函式,獲取預設的處理方法
public MythouCrashHandler()
{
this.defaultUEH = Thread.getDefaultUncaughtExceptionHandler();
}
//這個介面必須重寫,用來處理我們的異常資訊
@Override
public void uncaughtException(Thread thread, Throwable ex)
{
final Writer result = new StringWriter();
final PrintWriter printWriter = new PrintWriter(result);
//獲取跟蹤的棧資訊,除了系統棧資訊,還把手機型號、系統版本、編譯版本的唯一標示
StackTraceElement[] trace = ex.getStackTrace();
StackTraceElement[] trace2 = new StackTraceElement[trace.length+3];
System.arraycopy(trace, 0, trace2, 0, trace.length);
trace2[trace.length+0] = new StackTraceElement("Android", "MODEL", android.os.Build.MODEL, -1);
trace2[trace.length+1] = new StackTraceElement("Android", "VERSION", android.os.Build.VERSION.RELEASE, -1);
trace2[trace.length+2] = new StackTraceElement("Android", "FINGERPRINT", android.os.Build.FINGERPRINT, -1);
//追加資訊,因為後面會回撥預設的處理方法
ex.setStackTrace(trace2);
ex.printStackTrace(printWriter);
//把上面獲取的堆疊資訊轉為字串,列印出來
String stacktrace = result.toString();
printWriter.close();
Log.e(TAG, stacktrace);
//這裡把剛才異常堆疊資訊寫入SD卡的Log日誌裡面
if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED))
{
String sdcardPath = Environment.getExternalStorageDirectory().getPath();
writeLog(stacktrace, sdcardPath + "/mythou");
}
defaultUEH.uncaughtException(thread, ex);
}
//寫入Log資訊的方法,寫入到SD卡里面
private void writeLog(String log, String name)
{
CharSequence timestamp = DateFormat.format("yyyyMMdd_kkmmss", System.currentTimeMillis());
String filename = name + "_" + timestamp + ".log";
try
{
FileOutputStream stream = new FileOutputStream(filename);
OutputStreamWriter output = new OutputStreamWriter(stream);
BufferedWriter bw = new BufferedWriter(output);
//寫入相關Log到檔案
bw.write(log);
bw.newLine();
bw.close();
output.close();
}
catch (IOException e)
{
e.printStackTrace();
}
}
}
上面就是實現了獲取處理跟蹤資訊的方法,上面的方法是參照VLC的異常處理機制編寫的。做了一些簡單修改。不過上面只是獲取了異常資訊,如果程式安裝到使用者機器上,我們沒法獲取到這些資訊,總不能讓使用者把機器拿過來給你,然後你把Log拷貝出來吧。(這個我以前做嵌入式的時候到試過,讓客戶把機器拿過來,拷貝里面的Log,那時候做的機器無法聯網。現在想起來都糾結,O(∩_∩)O哈哈~) 為了不再糾結,我們需要一個可以把Log傳送到我們伺服器的功能,下面是把一個服務資訊傳送到我們指定伺服器功能。
3、通過網路傳送Log
複製程式碼 程式碼如下:
public class SendCrashLog extends AsyncTask<String, String, Boolean>
{
public SendCrashLog() { }
@Override
protected Boolean doInBackground(String... params)
{
if (params[0].length() == 0)
return false;
HttpClient httpClient = new DefaultHttpClient();
//你的伺服器,這裡只是舉個例子。把異常資訊當作http請求傳送到伺服器
HttpPost httpPost = new HttpPost("http://www.mythou/getlog.php");
//這裡把相關的異常資訊轉為http post請求的資料引數
try {
List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(1);
nameValuePairs.add(new BasicNameValuePair("model", params[0]));
nameValuePairs.add(new BasicNameValuePair("device", params[1]));
httpPost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
//傳送相關請求資訊
httpClient.execute(httpPost);
} catch (ClientProtocolException e) {
e.printStackTrace();
return false;
} catch (IOException e) {
e.printStackTrace();
return false;
}
Log.d(TAG, "Device model sent.");
return true;
}
@Override
protected void onPostExecute(Boolean result) {
}
}
上面就是我上一篇文章講的非同步任務的使用,我們在非同步任務裡面編寫了一個傳送http請求的服務,用來把相關的異常資訊傳送到我們指定的伺服器上面。這個需要你的伺服器解析傳送的http請求,這個難度不大,一般做個web的人都知道如何做。在上面的異常處理裡面再呼叫這裡的傳送方法:
複製程式碼 程式碼如下:
SendCrashLogsendLog = new SendCrashLog();
//剛才的異常資訊字串
sendLog .execute(stacktrace);
通過上面的方法就可以把異常資訊傳送到指定的伺服器,也就可以跟蹤客戶使用軟體的情況,方便我們修改程式的問題。當然這個資訊收集一般都隱私和後臺流量問題,這個需要在程式裡面做點提示,免得背上流氓軟體的罵名。
相關文章
- Android 收集程式崩潰異常資訊Android
- android Activity崩潰日誌收集Android
- 簡便地Android崩潰日誌收集Android
- iOS安全–不同平臺的崩潰收集iOS
- 【安卓筆記】崩潰日誌收集安卓筆記
- WkWebView 令人崩潰的崩潰WebView
- Android將程式崩潰資訊儲存本地檔案傳送至伺服器Android伺服器
- Go程式崩潰現場應該如何保留?Go
- Android | 零程式碼快速整合AGC崩潰服務AndroidGC
- Android Service入門到崩潰Android
- Flutter異常捕獲和Crash崩潰日誌收集Flutter
- Crittercism:iOS 8崩潰率已從3.6%降至2.6%iOS
- 最短的崩潰程式(C語言版)C語言
- Android 12 “致命”崩潰解決之路Android
- Android中處理崩潰異常Android
- WKWebView崩潰WebView
- Redis崩潰Redis
- 如何釋出Android應用程式Android
- app 崩潰的原因APP
- 如何挽救崩潰的WindowsXP作業系統Windows作業系統
- C++記錄程式崩潰時的dumpfileC++
- Android7.1.1Toast崩潰解決方案AndroidAST
- Android進階;App的異常崩潰處理AndroidAPP
- Crittercism:KitKat崩潰率0.7% iOS 7.1崩潰率1.6%iOS
- win10系統崩潰藍屏什麼原因 win10系統出現崩潰藍屏如何修復Win10
- APP防崩潰APP
- 如何使Java虛擬機器崩潰Java虛擬機
- WWDC 2018:理解崩潰以及崩潰日誌
- 讓 Chrome 崩潰的一行 CSS 程式碼ChromeCSS
- Android 崩潰日誌採集元件-DhccCrashLibAndroid元件
- TestBird 崩潰分析(Artisan) Android SDK 使用指南Android
- 系統崩潰了,網站響應慢了,你是如何快速定位錯誤資訊的?網站
- 現已釋出:Android 7.1 Developer PreviewAndroidDeveloperView
- Android P Beta 3 現已釋出!Android
- 如何收集Oracle程式中的SQL跟蹤資訊KUOracleSQL
- Android中Activity頻繁進入再退出時程式崩潰的解決方案Android
- 如何定位瀏覽器頁面崩潰的問題瀏覽器
- 分享一款移動平臺崩潰卡頓的收集分析利器——網易雲捕