国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

Android System crash DeadSystemException(Service/Activity/終極解決方案)

這篇具有很好參考價值的文章主要介紹了Android System crash DeadSystemException(Service/Activity/終極解決方案)。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

DeadSystemException

The core Android system has died and is going through a runtime restart. All running apps will be promptly killed.
Android 核心系統(tǒng)服務已經(jīng)死亡,正在重啟中。全部正在運行的app即將被kill殺死。

更多請閱讀,DeadSystemException官方介紹

chatgpt給出的解決答案
Android中的DeadSystemException是一種非常嚴重的異常,表示系統(tǒng)已經(jīng)崩潰。如果不進行處理,應用程序將會崩潰并退出。

處理方式:

  1. 捕獲該異常:使用try-catch來捕獲DeadSystemException異常,或者注冊一個UncaughtExceptionHandler來處理未捕獲的異常
  2. 根據(jù)產品需求進行業(yè)務邏輯處理:進行相應的處理,例如輸出錯誤日志或者提示用戶重新啟動應用程序。

1.service create 發(fā)生該異常:

deadsystemexception,Android 應用層開發(fā),android
先來看下調用棧中拋出異常的地方:
/frameworks/base/core/java/android/app/ActivityThread.java 中handleCreateService():
deadsystemexception,Android 應用層開發(fā),android
deadsystemexception,Android 應用層開發(fā),android
從源碼可知 :

  1. app 進程已經(jīng)完成對service#oncreate()過程,接著與ams 通過binder通訊,發(fā)生了DeadObjectException 從而拋出了DeadSystemException。
  2. ActivityThread 中對service創(chuàng)建過程有異常處理機制try-catch ,會判斷Instrumentation 是否攔截該異常。

為了進一步了解原因,接著查看bugly上該異常中捕獲的日志,發(fā)現(xiàn)有幾條有效日志:

//系統(tǒng)服務已經(jīng)die死亡
AndroidRuntime: FATAL EXCEPTION: main
AndroidRuntime: Process: com.android.systemui, PID: 19210
AndroidRuntime: DeadSystemException: The system died; earlier logs will point to the root cause
AppErrors: Process com.android.systemui has crashed too many times: killing!

//binder 通訊異常拋出日志
JavaBinder: !!! FAILED BINDER TRANSACTION !!! (parcel size = 104)

根據(jù)分析,推斷系統(tǒng)服務已經(jīng)死亡,app進程通過binder與之通訊,會拋出DeadSystemException。

根據(jù)FAILED BINDER TRANSACTION檢索,找/frameworks/base/core/jni/android_util_Binder.cpp。
signalExceptionForError():
deadsystemexception,Android 應用層開發(fā),android
從binder通訊源碼中可知,當遇到異常返回status(failed_transansaction 和dead_object)時, 會拋出DeadObjectException異常。另外,單次讀寫超過200k的binder數(shù)據(jù),就會拋出TransactionTooLargeException 異常;

原因推斷:當app進程創(chuàng)建service 成功后,與ams 通訊過程中,binder 發(fā)生異常狀態(tài)status failed_transansaction,從而拋出異常導致。

解決方案:
采用hook 方式,代理Instrumentation 捕獲該異常:

 /**
     * 自定義 Instrumentation 子類,
     * 攔截對Activity和Service的系統(tǒng)異常攔截
     */
    private static class InstrumentationImpl extends Instrumentation{
        @Override
        public boolean onException(Object obj, Throwable e) {
             return isInterruptException(e);
        }
        public static void hookInstrumentation(){
            //基本上發(fā)生在7.0和7.1設備上
            if (Build.VERSION.SDK_INT==Build.VERSION_CODES.N_MR1||Build.VERSION.SDK_INT==Build.VERSION_CODES.N){
                try {
                    Instrumentation ins = new InstrumentationImpl();
                    Class cls = Class.forName("android.app.ActivityThread");
                    Method mthd = cls.getDeclaredMethod("currentActivityThread", (Class[]) null);
                    Object currentAT = mthd.invoke(null, (Object[]) null);
                    Field mInstrumentation = currentAT.getClass().getDeclaredField("mInstrumentation");
                    mInstrumentation.setAccessible(true);
                    mInstrumentation.set(currentAT, ins);
                }catch (Exception e){
                    e.printStackTrace();
                }
            }
        }
    }
}
private static boolean isInterruptException(Throwable e){
    if (e.toString().contains("DeadSystemException")){
        //攔截DeadSystemException
        return true;
    }
     return false;
}

以上代碼,在Application的oncreate()中調用。

還有其他hook 方式,ActivityThread#H 的handler callBack ,也可以通用實現(xiàn)以上效果;

捕獲該異常后,需要啟動的服務無法啟動,Bugly 不會捕捉到該異常,但app進程很可能會被殺死。

2.activity destory 發(fā)生該異常:

先查看調用棧:
deadsystemexception,Android 應用層開發(fā),android
查看下crash 所在的源碼:
deadsystemexception,Android 應用層開發(fā),android
與前面的問題有些不同,當app 進程已經(jīng)完成Activity銷毀過程后,通知ams 過程中,發(fā)生系統(tǒng)進程,死亡異常則直接拋出。

解決方案
App 銷毀Activity過程中沒有異常捕捉機制,但該調用棧是在ActivityThread 中名為H 的handler中調用的,因此考慮hook 進行異常捕獲。

再查看Handler的源碼,發(fā)現(xiàn)可以為它設置callBack便可以攔截其handleMessage()調用。

deadsystemexception,Android 應用層開發(fā),android
編寫代碼如下所示:

private static class  CallBackImpl implements Handler.Callback{
    private  Handler activityThreadHandler;
    public CallBackImpl(Handler activityThreadHandler) {
        this.activityThreadHandler = activityThreadHandler;
    }
    @Override
    public boolean handleMessage(Message msg) {
        try {
            activityThreadHandler.handleMessage(msg); 
        }catch (Exception e){
            if (!isInterruptException(e)){
                //不被攔截的異常,繼續(xù)拋出
                throw  e; 
            }   
        }
        return true;
    }
    public static void hook(){
        try {
            if (Build.VERSION.SDK_INT==Build.VERSION_CODES.N_MR1||Build.VERSION.SDK_INT==Build.VERSION_CODES.N){
            //獲取到ActivityThread
            Class<?> ActivityThreadClass = Class.forName("android.app.ActivityThread");
            Field sCurrentActivityThreadField = ActivityThreadClass.getDeclaredField("sCurrentActivityThread");
            sCurrentActivityThreadField.setAccessible(true);
            Object ActivityThread = sCurrentActivityThreadField.get(null);
            //獲取到ActivityThread中的handler
            Field mHField=ActivityThreadClass.getDeclaredField("mH");
            mHField.setAccessible(true);
            Handler mHandler=(Handler) mHField.get(ActivityThread);
            //給handler添加callback監(jiān)聽器,攔截
            Field mCallBackField = Handler.class.getDeclaredField("mCallback");
            mCallBackField.setAccessible(true);
            mCallBackField.set(mHandler, new CallBackImpl(mHandler));
            }
        }catch (Exception e){
            e.printStackTrace();
        }
    }
}

private static boolean isInterruptException(Throwable e){
    if (e.toString().contains("DeadSystemException")){
        //攔截DeadSystemException
        return true;
    }
     return false;
}

以上代碼,在Application的oncreate()中調用

3.activity stop發(fā)生該異常:

deadsystemexception,Android 應用層開發(fā),android
查看源碼:
deadsystemexception,Android 應用層開發(fā),android
StopInfo 這個任務是在ActivityThread 執(zhí)行Activity onstop狀態(tài)時添加的:
deadsystemexception,Android 應用層開發(fā),android
handleStopActivity() 是在ActivityThread中H的handler中調用的。

解決方案
因StopInfo是runnable接口,無法通過Handler的handleMessage()函數(shù)進行攔截,因此考慮直接代理H 這個Handler , 通過dispatchMessage()分發(fā),傳遞給H處理,進行異常捕捉。

private static class HandlerImpl extends Handler {
    private Handler proxy;
    public HandlerImpl(Handler proxy) {
        super(proxy.getLooper());
        this.proxy = proxy;
    }
    @Override
    public void dispatchMessage(@NonNull Message msg) {
        try {
            proxy.dispatchMessage(msg);
        } catch (Exception e) {
            if (!isInterruptException(e)) {
                //不被攔截的異常,繼續(xù)拋出
                throw e;
            }
        }
    }
    public static void hook() {
        try {
            if (Build.VERSION.SDK_INT == Build.VERSION_CODES.N_MR1 || Build.VERSION.SDK_INT == Build.VERSION_CODES.N) {
                //獲取到ActivityThread
                Class<?> ActivityThreadClass = Class.forName("android.app.ActivityThread");
                Field sCurrentActivityThreadField = ActivityThreadClass.getDeclaredField("sCurrentActivityThread");
                sCurrentActivityThreadField.setAccessible(true);
                Object ActivityThread = sCurrentActivityThreadField.get(null);
                //獲取到ActivityThread中的handler
                Field mHField = ActivityThreadClass.getDeclaredField("mH");
                mHField.setAccessible(true);
                Handler mHandler = (Handler) mHField.get(ActivityThread);
                mHField.set(ActivityThread, new HandlerImpl(mHandler));
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
private static boolean isInterruptException(Throwable e) {
    if (e.toString().contains("DeadSystemException")) {
        //攔截DeadSystemException
        return true;
    }
    return false;
}

Hook H 這個Handler 可以解決Activity或者Service 生命周期中該異常的捕獲。在Application的oncreate()中調用。

4. (終極解決方案,捕獲任何地方發(fā)生該問題的調用棧):

實際上可能其他的線程或者其他的handler 中調用跨進程有關的api都可能會遇到該問題,單純hook ActivityThread中Handler是無法解決的。
終極解決方案:通過主線程的異常處理器,捕獲該異常,自定義Thread.UncaughtExceptionHandler。

/**
 * 終極解決方案
 */
private static class ExceptionHandlerImpl implements Thread.UncaughtExceptionHandler{
    private final Thread.UncaughtExceptionHandler mOldHandler;
    public ExceptionHandlerImpl(Thread.UncaughtExceptionHandler mOldHandler) {
        this.mOldHandler = mOldHandler;
    }

    @Override
    public void uncaughtException(@NonNull Thread t, @NonNull Throwable e) {
        if (isInterruptException( e)) {
            // 異常邏輯 1: 繼續(xù)執(zhí)行,進程不結束
            resumeMainThreadLoop();
            // restartApp() 或者直接中斷該進程,進行重啟重啟該app 的邏輯2
            return;
        }
        if (mOldHandler != null) {
            mOldHandler.uncaughtException(t, e);
        }
    }
    private void restartApp(Context context){
        // 重新啟動應用程序或者系統(tǒng)服務
        final Intent intent = context.getPackageManager().getLaunchIntentForPackage(context.getPackageName());
        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
        PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, 0);
        AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
        alarmManager.set(AlarmManager.RTC, System.currentTimeMillis() + 1000, pendingIntent);
        // 退出應用程序或者停止服務
        System.exit(0);
    }
    private void resumeMainThreadLoop() {
        if (Looper.myLooper() != Looper.getMainLooper()) {
             return;
        }
        try {
            Looper.loop();
        } catch (Exception e) {
            uncaughtException(Thread.currentThread(), e);
        }
    }
    public static void init(){
            //在bugly初始化或者自定義crash上報組件之后調用
            Thread.UncaughtExceptionHandler mOldHandler = Thread.getDefaultUncaughtExceptionHandler();
            if (!(mOldHandler instanceof ExceptionHandlerImpl)) {
                Thread.setDefaultUncaughtExceptionHandler(new ExceptionHandlerImpl(mOldHandler));
            }
    }
}

以上代碼在bugly或者異常捕獲組件之后調用。文章來源地址http://www.zghlxwxcb.cn/news/detail-686517.html

到了這里,關于Android System crash DeadSystemException(Service/Activity/終極解決方案)的文章就介紹完了。如果您還想了解更多內容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。如若轉載,請注明出處: 如若內容造成侵權/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經(jīng)查實,立即刪除!

領支付寶紅包贊助服務器費用

相關文章

  • system service exception藍屏

    system service exception藍屏

    電腦藍屏 問題是用戶最為頭疼的問題之一,而一般藍屏問題都會有一個藍屏終止代碼也就是我們的常說的錯誤代碼。那么如果遇到SYSTEM_SERVICE_EXCEPTION藍屏怎么辦呢? 解決方法一: 1、使用 Windows鍵+R打開運行,輸入“control.exe”,點擊確定,如下圖: 2、選擇“電源選項”,如

    2024年02月12日
    瀏覽(24)
  • Android Native crash觸發(fā)原理及處理

    Android Native crash觸發(fā)原理及處理

    當程序執(zhí)行以下操作,會觸發(fā)native crash: 1)程序自己調用 abort() 函數(shù)觸發(fā),用于表示出現(xiàn)嚴重的錯誤或異常情況,需要終止程序執(zhí)行 2)內存對齊錯誤或非法地址訪問 3)零除錯誤(除數(shù)為零),浮點溢出或下溢出等 4)使用了非法的機器指令或指令參數(shù)不當而導致 5)進程試

    2024年01月15日
    瀏覽(16)
  • Android 查看ANR和Crash日志(adb bugreport)

    Android 查看ANR和Crash日志(adb bugreport)

    今天測試那兒出了個ANR,我自己手機沒問題,很煩,定位不了位置。 于是還是得用ADB連接來看一下,之前用,但是老是會忘記,今天總結一下。 ADB命令查看應用包名_adb查看包名命令_歲月不待人的博客-CSDN博客 上面的連接是之前用adb后寫的一篇常用的一些密令總結。 ANR的排

    2024年02月13日
    瀏覽(22)
  • Android 獲取奔潰crash的日志(adb logcat或者dropbox)

    Android 獲取奔潰crash的日志(adb logcat或者dropbox)

    1.通過adb logcat 來獲取 : 使用場景 :測試或者開發(fā)小伙伴 抓取。 先執(zhí)行 adb logcat -c 清理緩存日志 接著,抓取當前時間段開始的日志: adb logcat -v time D:/crash.log 也可以抓取指定進程的日志: adb logcat -v time | find \\\"com.xxx\\\" D:/crash.log 其中 -v 和 time 是指log的v級別日志,也可用w 警告

    2024年02月08日
    瀏覽(21)
  • Activity之間數(shù)據(jù)回傳【Android、activity回傳、結合實例】

    Activity之間數(shù)據(jù)回傳【Android、activity回傳、結合實例】

    在Android應用中,有時需要從一個Activity向另一個Activity傳遞數(shù)據(jù),并在第二個Activity處理后將結果傳遞回第一個Activity。 這種情況下,我們可以使用 startActivityForResult() 和 onActivityResult() 方法來實現(xiàn)數(shù)據(jù)回傳。 創(chuàng)建新的Android項目: 打開Android Studio并創(chuàng)建一個新的Android項目,確

    2024年02月08日
    瀏覽(29)
  • Android Activity啟動流程一:從Intent到Activity創(chuàng)建

    Android Activity啟動流程一:從Intent到Activity創(chuàng)建

    關于作者:CSDN內容合伙人、技術專家, 從零開始做日活千萬級APP。 專注于分享各領域原創(chuàng)系列文章 ,擅長java后端、移動開發(fā)、人工智能等,希望大家多多支持。 學習前,建議有相關知識儲備: 【Android 基礎】 應用(Application)啟動流程 通過本文你可以學習到Activity啟動流

    2024年02月10日
    瀏覽(20)
  • Android Activity的啟動流程(Android-10)

    Android Activity的啟動流程(Android-10)

    在Android開發(fā)中,我們經(jīng)常會用到startActivity(Intent)方法,但是你知道startActivity(Intent)后Activity的啟動流程嗎?今天就專門講一下最基礎的startActivity(Intent)看一下Activity的啟動流程,同時由于Launcher的啟動后續(xù)和這里基本類似,就記錄在一起。注意本章都是基于Android-10來講解的。

    2024年01月17日
    瀏覽(21)
  • [Android 四大組件] --- Activity

    [Android 四大組件] --- Activity

    ??Activity??是一個Android的應用組件,它提供屏幕進行交互。每個Activity都會獲得一個用于繪制其用戶界面的窗口,窗口可以充滿哦屏幕也可以小于屏幕并浮動在其他窗口之上。 一個應用通常是由多個彼此松散聯(lián)系的Activity組成,一般會指定應用中的某個Activity為主活動,也

    2024年02月10日
    瀏覽(25)
  • Android --- Activity

    Android --- Activity

    官方文檔-activity Activity 提供窗口,供應在其中多個界面。此窗口通常會填滿屏幕,但也可能小于屏幕并浮動在其他窗口之上。 大多數(shù)應用包含多個屏幕,這意味著它們包含多個 Activity。通常,應用中的一個 Activity 會被指定主 Activity,即用戶啟動應用時顯示的第一個屏幕。然

    2024年04月23日
    瀏覽(30)
  • Android內嵌Unity (Activity)

    Android內嵌Unity (Activity)

    Unity2019.4.4 AndropidStudio4.2.1 參考文檔: Android內嵌Unity并實現(xiàn)互相跳轉的實例代碼_Android_腳本之家 Android Fragment中加載,嵌套Unity視圖_unity 導入并作為fragment_周灬浩的博客-CSDN博客 本文只實現(xiàn)了Activity整個切換過去,而Fragment,這種像h5似的與app共存,目前還未實現(xiàn),可參考的第二

    2024年01月18日
    瀏覽(22)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領取紅包,優(yōu)惠每天領

二維碼1

領取紅包

二維碼2

領紅包