背景
通过deeplink启动应用之后,没关闭应用的情况下,再次使用deeplink会失效的问题,是系统bug导致的。此bug仅在某些设备(Nexus 5X)上重现,launchMode并且仅当应用程序最初通过深层链接启动并再次通过深层链接打开时才会重现。
在AndroidManifest中像这样设置了我的活动,即MainActivity。
<activity
android:name="com.package.name.MainActivity"
android:screenOrientation="portrait"
android:theme="@style/Theme.AppTheme">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="myscheme" android:host="myhost" />
</intent-filter>
</activity>
并且在 LaunchActivity.onCreate() 中打印一个日志来表明它已经在那里了。
使用如下测试深层链接。
adb shell am start -W -a android.intent.action.VIEW -d "dlscheme://dlhost/param" some.package.name
在应用程序被终止后,使用上述命令,它可以打开应用程序并路由到正确的活动,没有问题。并且有以下日志。
adb shell am start -W -a android.intent.action.VIEW -d "dlscheme://dlhost/param" some.package.name
Starting: Intent { act=android.intent.action.VIEW dat=dlscheme://dlhost/param pkg=some.package.name }
Status: ok
Activity: some.package.name/.activity.LaunchActivity
ThisTime: 898
TotalTime: 898
WaitTime: 919
Complete
但是,如果再次输入相同的命令,而不终止应用程序。它只会打开应用程序,但不会打开正确的活动,并生成以下日志。
adb shell am start -W -a android.intent.action.VIEW -d "dlscheme://dlhost/param" some.package.name
Starting: Intent { act=android.intent.action.VIEW dat=dlscheme://dlhost/param pkg=some.package.name }
Warning: Activity not started, its current task has been brought to the front
Status: ok
Activity: some.package.name/.activity.LaunchActivity
ThisTime: 0
TotalTime: 0
WaitTime: 6
Complete
注意到有这一行
Warning: Activity not started, its current task has been brought to the front
解决方案
在项目的清单文件中,需要将以下内容添加到MainActivity中。
android:launchMode="singleTask"
并处理内部的深层链接onNewIntent()
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_recipe);
onNewIntent(getIntent());
}
protected void onNewIntent(Intent intent) {
String action = intent.getAction();
String data = intent.getDataString();
if (Intent.ACTION_VIEW.equals(action) && data != null) {
String recipeId = data.substring(data.lastIndexOf("/") + 1);
Uri contentUri = RecipeContentProvider.CONTENT_URI.buildUpon()
.appendPath(recipeId).build();
showRecipe(contentUri);
}
}