Android Activity只创建一次的实现

1. 流程图

flowchart TD
    A[启动Activity] --> B{判断Activity是否已存在}
    B --> |已存在| C[将已存在的Activity调至前台]
    B --> |不存在| D[创建新的Activity]

2. 步骤和代码

Step 1: 在AndroidManifest.xml文件中声明Activity的launchMode属性为singleTask

<activity
    android:name=".MainActivity"
    android:launchMode="singleTask">

Step 2: 在Activity中重写onNewIntent()方法

@Override
protected void onNewIntent(Intent intent) {
    super.onNewIntent(intent);
}

Step 3: 在需要启动Activity的地方,使用FLAG_ACTIVITY_CLEAR_TOP和FLAG_ACTIVITY_SINGLE_TOP标记

Intent intent = new Intent(this, MainActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
startActivity(intent);

这个方法会先检查是否已存在目标Activity的实例,如果存在的话,会将该Activity之上的所有Activity关闭,并调用目标Activity的onNewIntent()方法。如果不存在目标Activity的实例,则会创建一个新的实例。

3. 代码解释

  • android:launchMode="singleTask":这个属性定义了Activity的启动模式,singleTask模式表示该Activity只能有一个实例存在,如果已经有实例存在,新的启动请求会直接调用该实例的onNewIntent()方法,而不会创建新的实例。
  • onNewIntent(Intent intent):这个方法是在Activity已存在的情况下,新的启动请求会调用的方法。你可以在这个方法中处理传递过来的Intent或者其他逻辑。
  • Intent.FLAG_ACTIVITY_CLEAR_TOP:这个标记会将目标Activity之上的所有Activity都关闭。
  • Intent.FLAG_ACTIVITY_SINGLE_TOP:这个标记会告诉系统,如果目标Activity已经存在,不会创建新的实例,而是调用已存在的实例的onNewIntent()方法。

4. 完整代码示例

MainActivity.java

public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // 启动Activity
        findViewById(R.id.btn_start).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent(MainActivity.this, MainActivity.class);
                intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
                startActivity(intent);
            }
        });
    }

    @Override
    protected void onNewIntent(Intent intent) {
        super.onNewIntent(intent);
        // 处理新的启动请求
        Toast.makeText(this, "Activity已存在,不会创建新实例", Toast.LENGTH_SHORT).show();
    }
}

AndroidManifest.xml

<manifest xmlns:android="
    package="com.example.app">

    <application
        ...>

        <activity
            android:name=".MainActivity"
            android:launchMode="singleTask">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

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

上述代码中,点击按钮启动Activity时,会先判断目标Activity是否已存在。如果已存在,则不会创建新的实例,而是调用已存在的实例的onNewIntent()方法;如果不存在,则会创建一个新的实例。

5. 总结

通过设置Activity的launchMode属性为singleTask,并使用FLAG_ACTIVITY_CLEAR_TOP和FLAG_ACTIVITY_SINGLE_TOP标记,可以实现Android Activity只创建一次的效果。这样可以避免重复创建Activity实例,节省系统资源,提高应用性能。