日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > Android >内容正文

Android

Android处理崩溃的一些实践

發(fā)布時間:2025/3/15 Android 25 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Android处理崩溃的一些实践 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

對于任何程序來說,崩潰都是一件很難避免的事情,當然Android程序也不例外。在Android程序中,引起崩潰的多屬于運行時異?;蛘咤e誤,對于這些異常我們很難做到類似Checked Exception那樣顯式捕獲,因而最終導致了程序崩潰。本文講介紹一些如何處理崩潰的實踐,比如收集崩潰的stacktrace,甚至如何避免出現(xiàn)程序已停止的對話框。

如何收集崩潰信息

收集崩潰信息,可以更好的修復問題,增強程序的穩(wěn)定性。Android中的崩潰收集沿用了Java的收集機制,實現(xiàn)起來比較簡單。

1.實現(xiàn)UncaughtExceptionHandler

我們需要實現(xiàn)UncaughtExceptionHandler接口中的uncaughtException方法。該方法體中最常見的操作就是讀取崩潰的stacktrace信息,然后上報到服務器數(shù)據(jù)便于開發(fā)者分析。實現(xiàn)代碼如下:

1 2 3 4 5 6 7 8 9 10 11 12 13 public class SimpleUncaughtExceptionHandler implements Thread.UncaughtExceptionHandler { private static final String LOGTAG = "SimpleUncaughtExceptionHandler"; @Override public void uncaughtException(Thread thread, Throwable ex) { //讀取stacktrace信息 final Writer result = new StringWriter(); final PrintWriter printWriter = new PrintWriter(result); ex.printStackTrace(printWriter); String errorReport = result.toString(); Log.i(LOGTAG, "uncaughtException errorReport=" + errorReport); } }

除此之外,還建議攜帶以下信息發(fā)送到服務器,幫助更快定位和重現(xiàn)問題。

  • 設備唯一ID(基于IMEI或者Android ID等),方便根據(jù)用戶提供的id,查找崩潰的stacktrace
  • 設備語言與區(qū)域 方便重現(xiàn)
  • 應用的版本號
  • 設備的系統(tǒng)版本
  • 設備類型,如平板,手機,TV等
  • 崩潰發(fā)生的時間等

注冊默認的異常處理

注冊默認的異常處理就是最后的一步,很簡單,通常建議放在Application的onCreate方法中進行。

1 2 3 4 5 6 7 8 9 10 public class DroidApplication extends Application { private static final String LOGTAG = "DroidApplication"; @Override public void onCreate() { super.onCreate(); Log.i(LOGTAG, "onCreate"); Thread.setDefaultUncaughtExceptionHandler(new SimpleUncaughtExceptionHandler()); } }

驗證

當我們刻意觸發(fā)一個NullPointerException時,過濾日志adb logcat | grep SimpleUncaughtExceptionHandler類似如下信息,則說明成功了。

1 2 3 4 5 6 7 8 9 10 11 12 13 14 I/SimpleUncaughtExceptionHandler(22469): uncaughtException errorReport=java.lang.NullPointerException I/SimpleUncaughtExceptionHandler(22469): at com.droidyue.avoidforceclosedemo.MainActivity.causeNPE(MainActivity.java:22) I/SimpleUncaughtExceptionHandler(22469): at com.droidyue.avoidforceclosedemo.MainActivity.onClick(MainActivity.java:29) I/SimpleUncaughtExceptionHandler(22469): at android.view.View.performClick(View.java:4470) I/SimpleUncaughtExceptionHandler(22469): at android.view.View$PerformClick.run(View.java:18593) I/SimpleUncaughtExceptionHandler(22469): at android.os.Handler.handleCallback(Handler.java:733) I/SimpleUncaughtExceptionHandler(22469): at android.os.Handler.dispatchMessage(Handler.java:95) I/SimpleUncaughtExceptionHandler(22469): at android.os.Looper.loop(Looper.java:157) I/SimpleUncaughtExceptionHandler(22469): at android.app.ActivityThread.main(ActivityThread.java:5867) I/SimpleUncaughtExceptionHandler(22469): at java.lang.reflect.Method.invokeNative(Native Method) I/SimpleUncaughtExceptionHandler(22469): at java.lang.reflect.Method.invoke(Method.java:515) I/SimpleUncaughtExceptionHandler(22469): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:858) I/SimpleUncaughtExceptionHandler(22469): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:674) I/SimpleUncaughtExceptionHandler(22469): at dalvik.system.NativeStart.main(Native Method)

不出現(xiàn)應用崩潰對話框

在Android崩潰的時候,我們都會看到類似這樣的對話框

然而,實際上有些情況下是不需要展示這個對話框的,一個常用的例子,我的程序中一個不太重要的推送服務采用了單獨的進程,當這個進程崩潰時,實際上是可以允許不讓用戶感知的。

如果我們采取主進程仍彈出對話框,其他進程不彈出的策略,那么我們的問題,可以總結成如下三個

  • 如何判斷進程為主進程還是其他進程,或者某個進程
  • 如何在某些進程不彈出應用崩潰對話框
  • 如何在主進程彈出崩潰對話框

既然問題來了,我們就開動挖掘機深挖吧。

進程判定

進行進程判定也比較容易,首先我們需要獲得進程名

1 2 3 4 5 6 7 8 9 10 11 12 public static String getProcessName(Context appContext) { String currentProcessName = ""; int pid = android.os.Process.myPid(); ActivityManager manager = (ActivityManager) appContext.getSystemService(Context.ACTIVITY_SERVICE); for (ActivityManager.RunningAppProcessInfo processInfo : manager.getRunningAppProcesses()) { if (processInfo.pid == pid) { currentProcessName = processInfo.processName; break; } } return currentProcessName; }

判斷主進程,則對比進程名是否和包名相同即可

1 mAppContext.getPackageName().equals(processName)

判斷為某個進程,在mainifest這樣這樣聲明

1 <service android:name=".DroidService" android:process=":service"></service>

其對應的完整進程名為com.droidyue.avoidforceclosedemo:service,我們判斷可以使用如下代碼

1 "com.droidyue.avoidforceclosedemo:service".equals(processName);

不彈框的處理

不彈框的需要做的就是不調(diào)用Android默認的異常處理,當異常出現(xiàn)時,收集完信息,執(zhí)行進程kill即可。

1 android.os.Process.killProcess(android.os.Process.myPid());

主進程保持彈窗的處理

想要保持彈窗也比較容易,就是調(diào)用Android默認的異常處理。

首先需要獲得Android默認的異常處理,在設置自定的異常處理之前,將Android默認處理保存起來。如下是在自定義異常處理的構造方法中獲取Android默認處理

1 2 3 4 public DroidUncaughtExceptionHandler(Context context) { mAppContext = context.getApplicationContext(); mDefaultExceptionHandler = Thread.getDefaultUncaughtExceptionHandler(); }

然后在異常處理方法uncaughtException中調(diào)用如下方法

1 mDefaultExceptionHandler.uncaughtException(thread, ex);

注意,如果你的應用崩潰后,不調(diào)用Android默認的異常處理,也不進行殺死進程,則進程處于不可交互,即UI點擊無響應狀態(tài)。

源碼

本示例源碼,存放在Github,地址為AvoidForceCloseDemo


https://droidyue.com/blog/2015/12/06/practise-about-crash-in-android/

總結

以上是生活随笔為你收集整理的Android处理崩溃的一些实践的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。