【问题标题】:How to prevent android app from being Crash [closed]如何防止android应用程序崩溃[关闭]
【发布时间】:2017-10-03 07:26:38
【问题描述】:

我想阻止我的应用因未捕获的异常而崩溃。我希望将异常存储在日志中并防止应用程序崩溃。我如何做到这一点?提前致谢。

【问题讨论】:

  • 没有code和logcat怎么回答?
  • 我们都希望我们的应用程序不会崩溃 ;)。有时它可以防止它,而其他的则不能。但是没有代码......这是不可能的
  • @Ivan 谢谢!为您的评论。但你没有明白我想说的。

标签: android exception crash firebase-crash-reporting uncaught-exception


【解决方案1】:

为此,您只需要两个类,只需复制粘贴它们即可。 当您的应用程序中发生任何异常时,将调用此类。

public class CrashHandler implements
        java.lang.Thread.UncaughtExceptionHandler {
    private final Context myContext;
    private final String LINE_SEPARATOR = "\n";

    public CrashHandler(Context context) {
        myContext = context;
    }

    public void uncaughtException(Thread thread, Throwable exception) {
        StringWriter stackTrace = new StringWriter();
        exception.printStackTrace(new PrintWriter(stackTrace));
        StringBuilder errorReport = new StringBuilder();
        errorReport.append("************ CAUSE OF ERROR ************\n\n");
        errorReport.append(stackTrace.toString());

        errorReport.append("\n************ DEVICE INFORMATION ***********\n");
        errorReport.append("Brand: ");
        errorReport.append(Build.BRAND);
        errorReport.append(LINE_SEPARATOR);
        errorReport.append("Device: ");
        errorReport.append(Build.DEVICE);
        errorReport.append(LINE_SEPARATOR);
        errorReport.append("Model: ");
        errorReport.append(Build.MODEL);
        errorReport.append(LINE_SEPARATOR);
        errorReport.append("Id: ");
        errorReport.append(Build.ID);
        errorReport.append(LINE_SEPARATOR);
        errorReport.append("Product: ");
        errorReport.append(Build.PRODUCT);
        errorReport.append(LINE_SEPARATOR);
        errorReport.append("\n************ FIRMWARE ************\n");
        errorReport.append("SDK: ");
        errorReport.append(Build.VERSION.SDK);
        errorReport.append(LINE_SEPARATOR);
        errorReport.append("Release: ");
        errorReport.append(Build.VERSION.RELEASE);
        errorReport.append(LINE_SEPARATOR);
        errorReport.append("Incremental: ");
        errorReport.append(Build.VERSION.INCREMENTAL);
        errorReport.append(LINE_SEPARATOR);

        Intent intent = new Intent(myContext, ExceptionDisplay.class);
        intent.putExtra("error", errorReport.toString());
        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
        myContext.startActivity(intent);

        android.os.Process.killProcess(android.os.Process.myPid());
        System.exit(10);
    }

}

现在创建一个显示错误的活动:-

public class ExceptionDisplay extends AppCompatActivity {

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.exception_display_layout);

        TextView exception_text = (TextView) findViewById(R.id.exception_text);
        Button btnBack = (Button) findViewById(R.id.btnBack);
        exception_text.setText(getIntent().getExtras().getString("error"));

        btnBack.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                intentData();
            }
        });
    }

    @Override
    public void onBackPressed() {
        intentData();
    }

    public void intentData() {

        Log.d("CDA", "onBackPressed Called");
        Intent setIntent = new Intent(ExceptionDisplay.this, AppDataSourceSelection.class);
        setIntent.addCategory(Intent.CATEGORY_HOME);
        setIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        startActivity(setIntent);
    }
}

现在你可以通过扩展应用程序类的类来调用这个类:

public class ErrorHandler extends Application {


    @Override
    public void onCreate() {
        super.onCreate();
       Thread.setDefaultUncaughtExceptionHandler(new CrashHandler(getApplicationContext()));

        }}

【讨论】:

  • @Champandroid 谢谢(Y)
  • 欢迎您@Asad
  • 如果应用了 crashlytics,我们可以向 Firebase 控制台报告崩溃吗?
  • @garry 您可以将所有报告作为字符串发送到 firebase 数据库。
  • @Abhishek Bhardwaj 你能不能也给我们看看AppDataSourceSelection.class 的课程?提前致谢
【解决方案2】:

您可以自己处理未捕获的异常。 在您的应用程序类中使用以下代码。

public class MyApplication extends Application {
    private UncaughtExceptionHandler defaultUEH;

    private Thread.UncaughtExceptionHandler _unCaughtExceptionHandler =
        new Thread.UncaughtExceptionHandler() {
            @Override
            public void uncaughtException(Thread thread, Throwable ex) {

                // here I do logging of exception to a db
                Log.d("MyApp", "Uncaught exception.");     
               // Do what you want.

              // re-throw exception to O.S. if that is serious and need to be handled by o.s. Uncomment the next line that time.
            //defaultUEH.uncaughtException(thread, ex);
            }
        };

    public MyApplication() {
        defaultUEH = Thread.getDefaultUncaughtExceptionHandler();

        // setup Thread.setDefaultUncaughtExceptionHandler(_unCaughtExceptionHandler);
    }
}

【讨论】:

    【解决方案3】:

    您可以使用 try catch 块来捕获异常,这样可以防止应用程序崩溃。在 catch 块中获取预期的异常并将其记录下来以供您帮助。 但请记住,并非所有异常都可以被捕获 因为有些异常不是从异常派生的——例如Throwable 和 Error。

    基本上类型层次是:

       Object
         |
      Throwable
       /       \
    Exception  Error
    

    只有 Throwable 和派生类可以被抛出,所以如果你捕获 Throwable,那真的会捕获一切。

    除从 RuntimeException 派生的异常外,任何从 Exception(或 Exception 本身)派生的异常都算作检查异常 - 它们是您必须声明将抛出的异常,或者如果您调用抛出它们的东西则捕获它们。

    总而言之,Java 异常层次结构有点混乱......

    【讨论】:

    • 啊,所以我一直在寻找一些方法来让我的应用程序在崩溃之前记录一些东西……我尝试检查 logcat,但那里也没有未捕获的异常……花了我两个几天,但我很高兴我找到了这个答案,并且花了不到一分钟的时间来找出问题所在......谢谢伙计,你让我开心:)
    • 我很高兴它有帮助。
    猜你喜欢
    • 1970-01-01
    • 2013-03-08
    • 1970-01-01
    • 1970-01-01
    • 2018-07-17
    • 2021-01-28
    • 1970-01-01
    • 1970-01-01
    • 2021-12-08
    相关资源
    最近更新 更多