需要在子活动返回时重新创建活动

时间:2014-05-20 08:53:49

标签: android

我遇到了第三方活动的问题,我来自ActivityA。从AI启动另一项活动,ActivityB然后当他们关闭B时,它会回到{ {1}}。

ActivityA写得不好W.R.T.到活动生命周期,有时从ActivityA恢复时有一个opengl异常。在开始新鲜时它永远不会有问题。

我宁愿绕过例外而不是试图通过重置活动来修复它。

我如何生效ActivityB finish()但不能将其从活动堆栈中删除?或者是否有一个标志会告诉android在从视图中消失时总是销毁活动?

1 个答案:

答案 0 :(得分:1)

您无法从ActivityA控制ActivityB的状态。在您的情况下,因为您无法修改ActivityA我不确定哪种解决方案适用于您,但因为您描述ActivityA必须启动您的ActivityB我认为您必须至少对这部分有一些控制权。此解决方案假定在这种情况下,您只处理2 Activities,即ActivityAActivityB。如果您的导航层次结构大于此值,则需要一些额外的工作。


1)基本解决方案

您可以使用标记ActivityA启动Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK以清除活动堆栈。这样可以确保ActivityA必须完全重新创建,并在再次打开时完成整个生命周期。启动ActivityB的代码应如下所示:

Intent intent = new Intent(this, ActivityB.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);

但是这个解决方案的缺点是ActivityB将是堆栈中唯一的Activity,因此默认的后退功能将不起作用。您要解决的问题是在onBackPressed()中覆盖ActivityB,然后再次启动ActivityA。像这样:

@Override
public void onBackPressed() {
    Intent intent = new Intent(this, ActivityA.class);
    intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);
    startActivity(intent);
}

您再次需要标记Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK来修复您的活动堆栈。否则,您可以在从ActivityA返回后退回时从ActivityB导航回ActivityB。如果ActivityB包含ActionBar并启用了向上导航,您可能还需要以特殊方式实施导航:

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()) {
        case android.R.id.home:
            Intent intent = new Intent(this, ActivityA.class);
            intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);
            startActivity(intent);
            return true;

        default:
            return super.onOptionsItemSelected(item);
    }
} 

这个解决方案的另一个缺点(虽然是一个小的化妆品 - 可以通过一些工作修复)是回到ActivityA时使用的动画不会是完成{{{}时播放的动画1}}而是用于打开新Activity

的动画

如果这一切看起来有点像你的黑客,那是因为它是。您不应该像这样修改活动堆栈。您必须执行此操作的唯一原因是因为Activity未正确实施。修复ActivityA应该是第一优先,但如果这是不可能的,你可能无法实现像我建议的那样的解决方法。


2)更好的解决方案:

如果您使用支持库,我建议您使用ActivityA导航回NavUtilsActivityA解决了上述解决方案的一些问题,即它们使动画问题变得更好 - 尽管它没有完全修复,它为您管理活动堆栈。它的工作原理如下:

NavUtils

3)更好的解决方案

如果可能的话,我建议您为清单@Override public void onBackPressed() { Intent intent = new Intent(this, ActivityA.class); NavUtils.navigateUpTo(this, intent); } @Override public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { case android.R.id.home: Intent intent = new Intent(this, ActivityA.class); NavUtils.navigateUpTo(this, intent); return true; default: return super.onOptionsItemSelected(item); } } 中预定义父级的所有Activities定义父级,如下所示:

android:parentActivityName

如果您使用支持库,则还需要添加名为<activity android:name="com.example.app.ui.activities.LoginActivity" android:theme="@style/Theme.AppCompat.Light.NoActionBar" android:screenOrientation="portrait" android:parentActivityName="com.example.app.ui.activities.MainActivity"> </activity> 的元标记,该值又是父android.support.PARENT_ACTIVITY的包名:

Activity

您从定义父级获得的优势是您不必自己管理导航,活动堆栈或任何内容。如果您将<activity android:name="com.example.app.ui.activities.LoginActivity" android:theme="@style/Theme.AppCompat.Light.NoActionBar" android:screenOrientation="portrait" android:parentActivityName="com.example.app.ui.activities.MainActivity"> <meta-data android:name="android.support.PARENT_ACTIVITY" android:value="com.example.app.ui.activities.MainActivity" /> </activity> 的父级设为ActivityB,则可以使用ActivityA并只需拨打NavUtils

navigateUpFromSameTask(...)