我在Android上有一个几乎完全可以工作的模块化(动态外部碎片加载)应用程序。
剩下的就是处理异常和错误。可能发生的一种可能性是模块(片段)代码中的错误,例如调用不存在的方法或平均空指针(这种情况可能也确实发生)。
片段基本方法似乎是在提交fragmentTransaction
时调用的(而不是在调用fragmentTransaction.commit()
时),这使得很难捕捉到异常。我可以通过调用getSupportFragmentManager().executePendingTransactions()
来"强制"捕获异常,如图所示。
问题是,提交仍然会在某个时候发生——例如,暂停应用程序会使其保存状态,从而提交所有挂起的事务,即使提交已被catch块推迟,也会以异常(意味着由碎片代码中的错误而不是IllegalStateException
引起的异常)结束。以下方法会导致这种行为。
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 :)
}
}
我尝试了各种应对措施(在不同的时间点都以不同的例外结束,但没有一种能正常工作),选择了一种似乎最合理的应对措施,尽管仍然根本不起作用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);
}
}
因此,基本上我需要在实际生成fragmentTransaction
之前,检查片段的onCreate
(以及onCreateView
等等…)是否没有引起异常。看起来,在提交时尝试接球是行不通的。我只需要停止渲染片段,而不是让整个应用程序崩溃。有现成的想法吗?
谢谢。:)
编辑:
我意识到,由于上述类型的任何错误都可能在片段运行时的稍后发生,因此在添加片段时试图捕捉错误是毫无意义的。(哦,我真傻…)
设置默认的未捕获异常处理程序(感谢Jakar向我介绍了这篇文章)可以帮助通知用户错误是由插件引起的,但应用程序仍然必须崩溃,因为实际上不可能判断是哪个插件导致了异常并将其删除或其他什么(如果在初始化期间发生异常,则不可能删除,但如果稍后发生异常,应该可以删除)。
因此,这使得我的问题不重要,尽管能够按照我所描述的那样做会很有趣。
最后的结论是,目前这是不可能的。正如在编辑我的问题时所说:
我意识到,由于上述任何错误都可能发生在片段运行时以后的任何地方,这都是毫无意义的试图在添加片段时捕捉错误。
因此,试图实现这一点毫无意义。