Android - 在提交之前(期间)检查 FragmentManager 事务是否存在由片段代码引起的异常

Android - Checking FragmentManager transaction for exceptions caused by fragment code before (during) commit

我在 Android.

上有一个几乎可以完全工作的 模块化 (即时外部片段加载)应用程序

剩下的就是处理异常和错误了。可能发生的一种可能性是 模块(片段)代码中的错误 ,例如调用不存在的方法或普通的空指针(这可能而且确实会发生)。

片段基本方法似乎在提交 fragmentTransaction 时被调用(这不是在调用 fragmentTransaction.commit() 时),这使得异常很难捕捉到。我可以 "force" 通过调用 getSupportFragmentManager().executePendingTransactions() 捕获异常,如图所示。

问题是提交仍然会在某个时候发生——例如暂停应用程序会保存其状态并因此提交所有未决事务,这将以异常结束(意味着由错误引起的异常片段代码,而不是 IllegalStateException) 即使提交已被 catch 块推迟。以下方法会导致此行为。

private void showFragment(String name) {
    fragmentTransaction = getSupportFragmentManager().beginTransaction();
    fragmentTransaction.add(R.id.linear_main, fragmentMap.get(name));
    try {
        fragmentTransaction.commit();
        getSupportFragmentManager().executePendingTransactions();
    } catch (Exception e) {
        // Do nothing :)
    }
}

我尝试了各种对策(都在不同的时间点以不同的异常结束,但是none正常工作),选择了一个看起来最合理的,虽然仍然行不通全部。 :D 那是下面的代码,它实际上显示了一些不同的行为——它立即抛出一个 java.lang.IllegalStateException: Recursive entry to executePendingTransactions,我想这与提交的冲突和试图弹出堆栈有关。 (是的,我不太了解 FragmentManager 行为...)

搜索此错误会找到片段内片段问题的解决方案,这与我的问题完全无关。

private void showFragment(String name) {
    fragmentTransaction = getSupportFragmentManager().beginTransaction();
    fragmentTransaction.add(R.id.linear_main, fragmentMap.get(name));
    fragmentTransaction.addToBackStack(null);
    try {
        fragmentTransaction.commit();
        getSupportFragmentManager().executePendingTransactions();
    } catch (Exception e) {
        getSupportFragmentManager().popBackStackImmediate();
        fragmentMap.remove(name);
        Log.e("showFragments", name + " removed", e);
    }
}

所以,基本上我需要检查片段的 onCreate(和 onCreateView 等等...)是否 在实际执行 fragmentTransaction 之前不要引发异常。似乎在提交时使用 try-catch 并不能解决问题。我只需要停止渲染片段,而不是让整个应用程序崩溃。有什么开箱即用的想法吗?

谢谢。 :)

编辑:

我意识到,由于任何上述类型的错误都可能在片段运行期间的任何地方发生,因此在添加片段时尝试捕获错误是毫无意义的。 (哦,愚蠢的我......)

设置默认的未捕获异常处理程序(感谢 Jakar 将我指向 this post)可以帮助通知用户错误是由插件引起的,但应用程序仍然必须崩溃,因为这实际上是不可能的告诉哪个插件导致异常并删除它或其他任何东西(如果在初始化期间发生异常,则无法删除,但如果稍后发生异常,则应该可以删除)。

因此,这使我的问题变得不重要,尽管能够按照我所描述的进行操作会很有趣。

最后的结论是,目前这是不可能的。正如我在编辑问题时所说:

I realised that since any error of the mentioned kind can happen anywhere later on during runtime of the fragment, it's pointless trying to catch the errors when the fragment is added.

因此,尝试实现这一点毫无意义。