【问题标题】:Android Exceptions without Force Close没有强制关闭的Android异常
【发布时间】:2019-04-26 00:17:55
【问题描述】:

我可能遗漏了一些东西,但是每当在 Android(或 java)中抛出异常时,我的应用程序总是会强制关闭,并且整个程序都会终止。但是,当数据库查询出现问题时,我只想返回主菜单。

try {
        database.query(params);

} catch (Exception e) {
        Log.e("Game", "Failed Loading Level", e);
        returnToMenu();
    }

}

这例如强制关闭我的程序,我只想让它继续!

【问题讨论】:

  • 如果您捕捉到异常并且不重新引发它,您的应用将不会“强制关闭”。在您上面的示例中,query() 引发的异常不会导致“强制关闭”。如果你觉得你可以证明不是这样,请发布堆栈跟踪。
  • 如果这迫使你退出程序,那么returnToMenu()有问题

标签: java android exception exception-handling


【解决方案1】:

所有 android 开发者在开发应用程序时都必须面临强制关闭问题。 这是一种捕获该错误并优雅处理它的方法。

这将在您的 android 应用程序中创建一种错误页面机制。因此,当您的应用程序崩溃时,用户将无法看到令人讨厌的弹出对话框。而不是该应用程序将向用户显示预定义视图。

为了实现这种机制,我们需要创建一个错误处理程序和一个 Activity 类,该类将在应用程序被强制关闭时获取视图。

import java.io.*;

import android.content.*;
import android.os.Process;

public class ExceptionHandler implements java.lang.Thread.UncaughtExceptionHandler {
    private final Context myContext;

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

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

        Intent intent = new Intent(myContext, CrashActivity.class);
        intent.putExtra(BugReportActivity.STACKTRACE, stackTrace.toString());
        myContext.startActivity(intent);

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

以上类将作为强制关闭错误的侦听器。你可以看到 Intent 和 startActivity 用于在应用程序崩溃时启动新的 Activity。因此,只要应用程序崩溃,它就会启动名为 CrashActivity 的活动。现在我已将堆栈跟踪作为 Intent 的附加信息传递。

现在因为 CrashActivity 是一个常规的 Android Activity,您可以以任何您想要的方式处理它。

现在是重要的部分,即如何捕获该异常。 虽然很简单。在覆盖的 onCreate 方法中调用 super 方法之后,在每个 Activity 中复制以下代码行。

Thread.setDefaultUncaughtExceptionHandler(new UncaughtExceptionHandler(this));

您的 Activity 可能看起来像这样……

public class ForceClose extends Activity {

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    Thread.setDefaultUncaughtExceptionHandler(new UncaughtExceptionHandler(this));

    setContentView(R.layout.main);

    // Your mechanism is ready now.. In this activity from anywhere if you get force close error it will be redirected to the CrashActivity.
}}

您可以从此链接下载 zip 文件

http://trivedihardik.wordpress.com/2011/08/20/how-to-avoid-force-close-error-in-android/

【讨论】:

  • 崩溃后有什么方法可以继续当前的活动吗?
  • 你可以改变这一行 Intent intent = new Intent(myContext, CrashActivity.class);
  • 发生强制关闭时要打开哪些活动
  • 不打开其他活动,如果应用程序在一个活动上崩溃后崩溃继续同一活动
【解决方案2】:

如果您已实现 onSaveInstanceState () 和 onRestoreInstanceState(),则可以将 CrashActivity.class 替换为导致崩溃的活动。见http://developer.android.com/reference/android/app/Activity.html

【讨论】:

    【解决方案3】:

    我遇到了类似的问题并最终访问了此页面,因为我不明白为什么我的应用程序没有捕捉到我抛出的异常。事实证明这是出于明显的原因,所以我将分享。

    在我的例子中,我有一些从 HTTPS 请求接收 JSON 数据的代码。这导致编译器发牢骚,我不得不在解析 JSON 的代码周围放置一个 try/catch。到目前为止,一切顺利。

    JSON 包含自定义格式的版本字符串,我想将该版本字符串与应用程序连接到的设备上的固件版本进行比较。所以我创建了一个类,它接受版本字符串并将其解析为各种组件,然后以特定顺序使用它们进行比较。在我将字符串解析为组件的构造函数中,如果字符串无效,我会抛出异常。同样,这很好,完全正常。

    从事固件工作的人告诉我,我的应用程序崩溃了。好的 - 必须弄清楚为什么。原来他们将无效的版本字符串放入固件中。好没问题。应该发生的是 Version 类引发了一个异常,该异常被我的 try/catch 捕获,并且只是阻止了与版本比较相关的逻辑,并且它不会显示可用的固件更新,这在这种(不寻常的)情况下是可以的。

    在绞尽脑汁想弄清楚为什么异常没有被捕获后,我终于发现这是因为我的 try/catch 正在捕获 JSONException 而我的 Version 类抛出了 RuntimeException。

    因此,如果您无法弄清楚为什么您的 try/catch 没有捕获到您认为它应该捕获的异常并且您最终到了这里,请仔细检查您正在处理的异常类型,并确保您有适当的异常输入渔获物。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-06-29
      • 2023-04-08
      • 1970-01-01
      • 2011-06-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多