处理"Activity已被破坏"(java.lang.IllegalStateException)异常?

Sha*_*n91 1 java android illegalstateexception android-activity

我正在寻找一种通用的方法来迎合这个例外.如果用户例如非常快速地保持切换活动,则总会发生这种情况.因为很明显有很多地方我们会尝试访问活动引用,当它为null时,应用程序会因此异常而崩溃.一种方法是每次访问活动参考时检查"isFinishing()",我想知道是否有另一种更好和通用的方法来解决应用程序级别的这个问题.

请原谅我,如果我的问题听起来很愚蠢或没有任何意义,但我想在问:)没有害处.

Mar*_*ini 9

作为一般规则,Android上下文应尽可能少地存储,仅在需要时使用.

如果您在尝试使用"活动"上下文时遇到空或无效异常,则表示您正在执行活动的标准Android生命周期之外的操作.

由于生命周期的特性(异步),有时很难预测何时会出现这些情况...... 除非您避免在保证上下文存活的生命周期事件之外执行操作.

例如:在onPostExecuteasynctasks甚至线程的方法中执行Activity/Context操作是一个定时炸弹.

作为一般规则,在尝试在生命周期方法之外使用Activity/Context之前(例如onResume),也是危险的,并且应始终伴随null检查.

我曾经有一个简单的方法来检查这个:

if (activity != null && !activity.isFinishing()) {
   // safe
}
Run Code Online (Sandbox Code Playgroud)

在Jelly Bean(API 17 afaik)之后你也可以检查activity.isDestroyed()或类似(现在不记得了).

如果必须存储上下文(稍后执行某些与上下文相关的操作),请始终尝试存储应用程序上下文(activity.getApplicationContext()),它是对Application单例的静态引用,并且不会泄漏.

话虽如此,请记住每种类型的上下文有哪些限制.如果有疑问,请为此保留一个书签,特别是要了解为什么尝试使用应用程序上下文来扩充布局可能会产生意外结果.

更新:

如果你需要一个通用/通用的地方来操作你的片段,保持一个方便的util类(伪代码):

public final class FragmentUtils {
    private FragmentUtils() {
    }
    public static void add(FragmentActivity fragmentActivity, int layoutId, Fragment fragment) {
        if (isContextInvalid(fragmentActivity)) {
           return
        }
        FragmentTransaction fragmentTransaction = fragmentActivity.getSupportFragmentManager().beginTransaction();
        fragmentTransaction.add(layoutId, fragment);
        fragmentTransaction.commit();
    }

    public static void replace(FragmentActivity fragmentActivity, int layoutId, Fragment fragment) {
        if (isContextInvalid(fragmentActivity)) {
           return
        }
       // TODO: you do this one ;)

    }

    public static void remove(FragmentActivity fragmentActivity, Fragment fragment) {
        if (isContextInvalid(fragmentActivity)) {
           return
        }
        // TODO: you do this one ;)
        if (fragment.isAdded()) {
            …
        }
    }

    public static void show(FragmentActivity fragmentActivity, Fragment fragment) {
        // TODO: you do this one ;)
        if (fragment.isAdded()) {
            …
        }
    }

    public static void hide(FragmentActivity fragmentActivity, Fragment fragment) {
        // TODO: you do this one ;)
        if (fragment.isAdded()) {
            …
        }
    }
    public boolean isContextInvalid(final Context context) {
        if (context == null || context.isFinishing()) {
            return true;
        }
        return false;
    }
}
Run Code Online (Sandbox Code Playgroud)

并在那里添加null /检查到您的上下文.(或类似) 注意上面的代码是不完整的,我只是写在这里在此编辑器....