方向改变后的第二次活动

Posted

技术标签:

【中文标题】方向改变后的第二次活动【英文标题】:Second instance of activity after orientation change 【发布时间】:2012-03-23 08:24:28 【问题描述】:

我的应用程序在方向更改时有一个奇怪的行为

正常行为: 当我打开我的应用程序时,我的家庭活动开始了。当我进入下一个活动(画廊)时,它会正常启动(从右到左滑入动画)。 当我使用返回键返回时,当前活动(画廊)已完成(从左到右滑出动画)。

奇怪的行为:

当我以纵向模式启动应用程序并将方向更改为横向时。然后有类似家庭活动的第二个实例。因为然后在横向模式下按下后退按钮不会像没有方向更改那样关闭应用程序(主活动是我的应用程序中的第一个活动),而是从左到右制作滑动动画(比如开始一个新活动)并再次显示家庭活动(但我认为是另一个实例)。再次按下返回按钮将关闭应用程序。 当我在横向模式下启动应用程序并将方向更改为纵向模式时,按下后退按钮会导致从右到左的幻灯片动画(如关闭活动)并再次显示主页活动。 当我启动应用程序并进行两次方向更改纵向-横向-纵向时,后退按钮会正常关闭应用程序。

所以就好像横向和纵向模式被视为两种不同的活动。

我不使用android:configChanges="orientation|keyboardHidden|screenSize",因此方向更改应遵循正常的 android 活动生命周期并破坏活动的“旧”纵向(或横向)版本。 我的活动继承自FragmentActivity。 我使用onSaveInstanceState 传递一个parceable(不包含对活动的任何引用),我使用onRetainCustomNonConfigurationInstance (read here) 传递几个AsyncTasks。但是这些任务中的所有引用(如果有的话)都在onRetainCustomNonConfigurationInstance 中销毁,并在getLastCustomNonConfigurationInstance 之后恢复(使用新创建的活动)。

任何想法可能导致这种行为?

编辑: Manifest-File 中的活动声明:<activity android:name=".activities.smartphone.HomeSmartphone" android:label="@string/app_name"></activity>

家庭智能手机扩展家庭 主页扩展 MyFragmentActivity MyFragmentActivity 扩展了 android.support.v4.app.FragmentActivity

在 MyFragmentActivity 中,我只是通过调用跟踪类的一些静态方法来在 onCreate、onRestart、onStart、onSaveInstanceState、onPause、onResume、onStop、onDestroy 中执行一些日志记录/跟踪工作,该跟踪类仅包含对应用程序上下文的引用。不是活动上下文。

Home 是一个由 HomeSmartphone 和 HomeTablet 扩展的抽象类。这两个类只是在不同的布局中进行一些特殊的加载/刷新/初始化。

大部分任务都是在抽象的 Home 类中完成的。



    public HomeRetainedObjects retained = new HomeRetainedObjects();

    public boolean adIsShown = false;

    @Override
    public void onCreate(Bundle savedInstanceState) 
        super.onCreate(savedInstanceState);
        this.setContentView(R.layout.home);

        Log.i("DEBUG", "onCreate(Home)");

        if (savedInstanceState != null) 
            this.adIsShown = savedInstanceState.getBoolean("adIsShown");
        

    // write/update values in shared preferences
        this.initPreferences();

    // recover retained objects (mostly AsyncTasks)
        this.recoverRetained();

    // show content / refresh content
        this.init();
    

    @Override
    protected void onSaveInstanceState(Bundle outState) 
        super.onSaveInstanceState(outState);

        outState.putBoolean("adIsShown", this.adIsShown);

        Log.i("DEBUG", "onSaveInstanceState(Home)");
    

    public void recoverRetained() 
        Object retained = this.getLastCustomNonConfigurationInstance();
        if (retained instanceof HomeRetainedObjects) 
            this.retained = (HomeRetainedObjects) retained;

            if (this.retained.loadMessageTask != null) 
                this.retained.loadMessageTask.restoreContext(this);
            
        
    

    @Override
    public Object onRetainCustomNonConfigurationInstance() 
        if (this.retained.loadMessageTask != null) 
            this.retained.loadMessageTask.destroyContext();
        

        return this.retained;
    

我希望这会有所帮助?!

【问题讨论】:

...包括清单中的活动声明,请。 +1 提出一个很好的问题,向我们展示你的努力:) 【参考方案1】:

我遇到了类似的问题,您的问题的原因似乎是覆盖onRetainCustomNonConfigurationInstance()

我查看了我的保留状态对象,发现它包含对 Context 的引用。我将它包裹在 WeakReference 中,然后恢复正常行为,并且没有奇怪的双重实例徘徊。

也许您的保留状态还包含对 Context 的引用?

【讨论】:

以上是关于方向改变后的第二次活动的主要内容,如果未能解决你的问题,请参考以下文章

方向更改后片段中的 getActivity() 为空

GPT-4创造者:第二次改变AI浪潮的方向

LeetCode:Database 89.获取最近第二次的活动

第一次通知活动显示时,第二次通知中未显示GCM通知活动

允许 UIScrollView 在长按处于活动状态时通过第二次触摸滚动

仅在第二次导航到 Fragment 时导致 java.IllegalStateException 错误,无活动