一、背景
有两个应用,分别是应用a和应用b,点击a应用的Activity的按钮后跳转到b应用的Activity。分析此时a应用的activity和b应用的activity所处任务栈的情况。
二、项目代码
应用a的代码:
activity部分
public class AMainActivity extends AppCompatActivity {
private Button btn_dump;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_amain);
btn_dump = findViewById(R.id.dump);
btn_dump.setOnClickListener(v->{
Intent intent = new Intent();
ComponentName cn = new ComponentName("com.example.b","com.example.b.BMainActivity");
intent.setComponent(cn);
//intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
});
}
}
布局代码
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".AMainActivity">
<Button
android:id="@+id/dump"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="跳到B应用的acti"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
应用b的代码:
配置文件代码(布局就一段文字很简单,此处省略)
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.b">
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.LearnAndroid">
<activity android:name="com.example.b.BMainActivity" android:exported="true" 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代码
public class BMainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_bmain);
}
}
三、任务栈分析
①AMainActivity的启动模式默认,BMainActivity的启动模式为standard。
启动应用a,然后点击按钮跳转到应用b的activity。
打开adb shell使用dumpsys activity activities查看运行栈情况。以下我截出了关键部分。
由下图可以看出只有一个栈,栈中包含应用a的activity和应用b的activity
应用b的activity
应用a的activity
由此可见此模式下跨应用启动activity时被启动的activity是直接被压入调用者(这里的应用a)的任务栈顶。
②AMainActivity的启动模式默认,BMainActivity的启动模式为singleTop。
运行后使用dumpsys activity activities查看运行栈情况。
此模式下运行后,其工作栈情况同①一样,即跨应用时被启动的activity是直接被压入调用者(这里的应用a)的任务栈顶。
③AMainActivity的启动模式默认,BMainActivity的启动模式为singleTask。
运行后使用dumpsys activity activities查看运行栈情况。
由上两图看出启动的应用b的activity是在一个单独的任务栈中。
④AMainActivity的启动模式默认,BMainActivity的启动模式为singleInstance。
运行后使用dumpsys activity activities查看运行栈情况。
由上两图看出启动的应用b的activity是在一个单独的任务栈中。同③一样。
四、总结
当被启动应用的activity是standard、singleTop时,被启动的activity是直接被压入调用者(这里的应用a)的任务栈顶。
当被启动应用的activity是singleTask、singleInstance时,被启动的activity是使用单独的任务栈。
另外,不论哪种模式,跨应用启动的activity都是运行在其所属应用的进程中。可在每种模式下使用PS -A | grep 包名查看进程情况。