活动创建了两次

时间:2017-05-22 03:14:44

标签: android screen-orientation activity-lifecycle

我设置了锁定方向

enter image description here

并添加了两个简单类的示例代码,如下所示:

SplashLandscapeActivity.java

public class SplashLandscapeActivity extends AppCompatActivity {
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Log.d("start", "xxxx start Activity SplashLandscapeActivity");
        new Handler().postDelayed(new Runnable() {
            @Override
            public void run() {
                startActivity(new Intent(SplashLandscapeActivity.this, TestActivity.class));
                finish();
            }
        }, 500);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        Log.d("start", "xxxx onDestroy Activity SplashLandscapeActivity");
    }
}

TestActivity.java

public class TestActivity extends AppCompatActivity {

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Log.d("start", "xxxx start Activity TestActivity "
                + getResources().getConfiguration().orientation);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        Log.d("start", "xxxx onDestroy Activity TestActivity "
                + getResources().getConfiguration().orientation);
    }
}

的AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example">

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity
            android:name=".SplashLandscapeActivity"
            android:theme="@style/SplashTheme"
            android:screenOrientation="landscape">
            <intent-filter>
                <action android:name="android.intent.action.MAIN"/>

                <category android:name="android.intent.category.LAUNCHER"/>
            </intent-filter>
        </activity>

        <activity
            android:name=".TestActivity"
            android:screenOrientation="portrait"/>
    </application>
</manifest>

当我使用new Handler().postDelayedSplashLandscapeActivity.java)启动TestActivity时,它会启动两次,第一个有Landscape方向,然后切换回portrait。日志显示了一切:

  

xxxx启动Activity SplashLandscapeActivity

     

xxxx start Activity TestActivity 2 //&lt; == landscape

     

xxxx onDestroy活动TestActivity 1

     

xxxx start Activity TestActivity 1 //&lt; == portrait

     

xxxx onDestroy活动SplashLandscapeActivity

如果我删除了HandlerTestActivity现在就像普通人一样开始使用。

  

xxxx启动Activity SplashLandscapeActivity

     

xxxx start Activity TestActivity 1

     

xxxx onDestroy活动SplashLandscapeActivity

所以,我的问题是:

1-此系统问题或其预期行为?即使在activity中修复了screenOrientation,为什么Manifest重新启动?

2-实际上,我的真实项目没有任何Handler但是activity开始两次(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK开始后)的问题相同。我该如何处理这个问题?

5 个答案:

答案 0 :(得分:3)

在您的清单文件中,像这样编辑TestActivity块

<activity android:name=".TestActivity" android:launchMode="singleInstance" android:screenOrientation="portrait"/>

答案 1 :(得分:1)

有两条评论可以阻止TestActivity启动两次。希望能帮到你

  1. 在TestActivity中使用sensorPortrait代替portrait。并且TestActivity不会启动两次,但会将其旋转以匹配用户持有设备的方式。
  2. android:configChanges="keyboardHidden|orientation|screenSize"添加到Manifest.xml中的T​​estAcitivty。它将调用public void onConfigurationChanged(Configuration newConfig)而不是重新启动。
  3. 我在Android N中没有发现此问题。

答案 2 :(得分:1)

我认为你需要添加标志

android:configChanges="orientation|screenSize"

清单文件中的TestActivity如下所示:

<activity
android:name=".TestActivity"
android:screenOrientation="portrait"
android:configChanges="orientation|screenSize"
/>

这可以解决您的问题。

原因,为什么需要更改配置是: 现在关于为什么需要configChanges,来自android docs:

  

如果您的应用程序不需要在特定期间更新资源   配置更改,你有一个性能限制   要求您避免活动重启,然后您可以声明   您的活动处理配置更改本身,这会阻止   系统重新启动您的活动。

访问android doc

答案 3 :(得分:1)

更新manifest.xml

 <?xml version="1.0" encoding="utf-8"?>
    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
        package="com.example">

        <application
            android:allowBackup="true"
            android:icon="@mipmap/ic_launcher"
            android:label="@string/app_name"
            android:supportsRtl="true"
            android:theme="@style/AppTheme">
            <activity
                android:name=".SplashLandscapeActivity"
                android:theme="@style/SplashTheme"
                android:screenOrientation="landscape"
            android:configChanges="keyboardHidden|orientation|screenSize">
                <intent-filter>
                    <action android:name="android.intent.action.MAIN"/>

                    <category android:name="android.intent.category.LAUNCHER"/>
                </intent-filter>
            </activity>

            <activity
                android:name=".TestActivity"
                android:screenOrientation="portrait"
android:configChanges="keyboardHidden|orientation|screenSize"/>
        </application>
    </manifest>

答案 4 :(得分:0)

可以将MainActicity更改为

MY_URL = "{% url 'create_exam' letnik_id=letnik_id classes_id=classes_id subject_id=subject_id %}";
<script src="myscripts.js"></script>

处理程序在另一个线程中调用,当您更改屏幕方向时,前一个处理程序消失并运行,该线程不会消失。您可以有更多时间多次测试处理程序以更改屏幕方向。