我可以在我的应用程序崩溃之前调用一个方法吗?

5

我是Android的新手,当我运行代码时经常会遇到异常。请问有没有办法在应用程序崩溃之前调用一个方法而不需要使用“try-catch”语句?


你能贴一些代码和堆栈跟踪吗? - Emmanuel
3
一般来说,不行。请参阅此处的文档:http://docs.oracle.com/javase/tutorial/essential/exceptions/handling.html。 - mpontillo
取决于是什么类型的异常,如果您想事先检测它是否会失败? - Shobhit Puri
3
可以通过实现UncaughtExceptionHandler来完成。 - Biraj Zalavadia
最好你应该修复你的代码。请发布代码和日志记录。 - Shakeeb Ayaz
5个回答

13

这将是更好的处理未捕获异常的方式:

public class MyApplication extends Application {
@Override
    public void onCreate() {
        super.onCreate();
        appInitialization();
    }

    private void appInitialization() {
         defaultUEH = Thread.getDefaultUncaughtExceptionHandler();
         Thread.setDefaultUncaughtExceptionHandler(_unCaughtExceptionHandler);
    }

    private UncaughtExceptionHandler defaultUEH;

    // handler listener
    private Thread.UncaughtExceptionHandler _unCaughtExceptionHandler = new Thread.UncaughtExceptionHandler() {
        @Override
        public void uncaughtException(Thread thread, Throwable ex) {
            ex.printStackTrace();
            // TODO handle exception here
        }
    };
}

Application是一个基类,适用于需要维护全局应用程序状态的人。因此,在这里,处理这些异常将是更好的选择。

编辑: 如果未捕获的异常发生在UI线程中,则上述代码将处理它们。 如果异常发生在工作线程中,则可以按以下方式处理:

private boolean isUIThread(){
        return Looper.getMainLooper().getThread() == Thread.currentThread();
    }
// Setup handler for uncaught exceptions.
    Thread.setDefaultUncaughtExceptionHandler (new Thread.UncaughtExceptionHandler()
    {
        @Override
        public void uncaughtException (Thread thread, Throwable e)
        {
            handleUncaughtException (thread, e);
        }
    });

    public void handleUncaughtException(Thread thread, Throwable e) {
        e.printStackTrace(); // not all Android versions will print the stack trace automatically

        if (isUIThread()) {
            // exception occurred from UI thread
            invokeSomeActivity();

        } else {  //handle non UI thread throw uncaught exception

            new Handler(Looper.getMainLooper()).post(new Runnable() {
                @Override
                public void run() {
                    invokeSomeActivity();
                }
            });
        }
    }

1
哦天啊,使用这个工具我可以追踪到应用程序意外关闭的情况... 这将非常有用。 - Shakeeb Ayaz
但是如果我在应用程序类中实现这个,我的应用程序就不会崩溃了。 - Rajendra Verma
1
这很好。我有一个关于多线程的问题。这只能在主线程上工作吗?因为你调用了Thread.setDefaultUncaughtExceptionHandler,所以我认为它只获取当前线程。如果我错了,请指导如何处理多线程。 - j2emanue
嗨@j2emanue,说得好。早期的代码片段将在UI线程抛出异常的情况下抛出异常。为了处理工作线程的情况,更新后的代码片段应该可以工作。感谢您的解决。 :) - Shrikant Ballal
嗨@ Shrikant,我刚刚在Android上进行了测试,似乎您的初始代码片段并不适用于所有线程。我在子线程上抛出了异常,并调用了未捕获异常的回调。FYI。我一直在遇到这个大问题,所以我在这里写了一个答案,但它涉及Crashlytics,如果有人需要使用Crashlytics,请在此处查看:http://stackoverflow.com/questions/42260890/crashlytics-in-android-how-to-capture-all-exceptions-crashes-in-one-place - j2emanue
1
@Shrikant,你的回答真是太棒了。感谢你提供这么好的代码片段。 - Sebastian Breit

0

尝试这种方式

1)创建类

import android.content.Context;
import android.content.Intent;
import android.os.Process;

import java.io.PrintWriter;
import java.io.StringWriter;
import java.lang.Thread.UncaughtExceptionHandler;

public class CrashReportHandler implements UncaughtExceptionHandler {

    public static void attach(Context context) {
        Thread.setDefaultUncaughtExceptionHandler(
                new CrashReportHandler(context)
        );
    }

    ///////////////////////////////////////////// implementation

    private CrashReportHandler(Context context) {
        m_context = context;
    }

    public void uncaughtException(Thread thread, Throwable exception) {
        StringWriter stackTrace = new StringWriter();
        exception.printStackTrace(new PrintWriter(stackTrace));

        //You will get call back here when app crashes.

        // from RuntimeInit.crash()
        Process.killProcess(Process.myPid());
        System.exit(10);
    }

    private Context m_context;

}

如何使用这个类?

在你的活动 onCreate() 方法中写入以下行:

CrashReportHandler.attach(this);

但是如果每个活动都在注册该类,那么当活动结束时肯定会出现内存泄漏。即使该活动已经完成,CrashReportHandler 仍将包含对每个活动的引用。 - Shrikant Ballal
我的问题是,除了执行Process.killProcess(Process.myPid()); System.exit(10);之外,是否可以再次抛出异常?我想要做的是在另一个日志文件中记录异常,然后像往常一样使应用程序崩溃。如果我在uncaughtException方法中再次抛出异常,那么会不会形成无限循环? - j2emanue

0

0

如果您使用设置/强制关闭,进程将被终止,代码将不会执行。 - Bamaco

-1

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接