Android中onNewIntent未触发问题排查:自定义Scheme跳转异常
咱们一步步来拆解你遇到的问题,先从核心的onNewIntent不触发说起:
1. Intent Filter 写法错误(最关键的原因)
你在同一个<intent-filter>里写了两个<data android:host>标签,这里要注意:单个intent-filter内的多个<data>是「逻辑与」的关系,也就是说系统会要求传入的Intent同时满足scheme=myapp、host=app AND host=app.open——这显然不可能匹配到任何请求,所以每次调用自定义Scheme时,系统都会认为这是一个全新的、不匹配现有栈内Activity的Intent,要么创建新实例(移除noHistory时),要么因为noHistory=true销毁旧实例后再创建新的,自然不会触发onNewIntent。
修正后的Intent Filter写法
要匹配myapp://app和myapp://app.open两种Scheme,需要拆成两个独立的<intent-filter>:
<activity android:name=".activities.MyActivity" android:configChanges="keyboardHidden|orientation|screenSize" android:label="@string/title_my_activity" android:launchMode="singleTop" android:screenOrientation="portrait"> <!-- 先移除noHistory,后面解释原因 --> <!-- 匹配 myapp://app --> <intent-filter android:label="@string/my_intent"> <action android:name="android.intent.action.VIEW" /> <category android:name="android.intent.category.DEFAULT" /> <category android:name="android.intent.category.BROWSABLE" /> <data android:scheme="myapp" android:host="app" /> </intent-filter> <!-- 匹配 myapp://app.open --> <intent-filter android:label="@string/my_intent"> <action android:name="android.intent.action.VIEW" /> <category android:name="android.intent.category.DEFAULT" /> <category android:name="android.intent.category.BROWSABLE" /> <data android:scheme="myapp" android:host="app.open" /> </intent-filter> </activity>
2. noHistory属性的影响
这个属性不是必须的,它的作用是:当Activity离开前台(比如跳转到其他页面)时,会立即被销毁并从任务栈中移除。
你同时设置了singleTop和noHistory=true,就会导致一个矛盾:singleTop需要Activity留在栈顶才能复用,但noHistory=true会让Activity一旦不在前台就被销毁,下次调用Scheme时只能创建新实例,根本没有栈顶实例可以复用,所以onNewIntent永远不会触发。
3. 完善onNewIntent方法
即使修复了上面两个问题,还有一个容易忽略的点:一定要在onNewIntent里调用setIntent(intent),否则后续调用getIntent()拿到的还是旧的Intent数据:
@Override protected void onNewIntent(Intent intent) { Log.d("DEBUG", "New intent!"); setIntent(intent); // 必须更新Intent,否则getIntent()取到的是旧数据 super.onNewIntent(intent); // 在这里处理新Intent的逻辑,比如获取Scheme数据 Uri data = intent.getData(); if (data != null) { Log.d("DEBUG", "Received Scheme: " + data.toString()); } }
4. 关于移除noHistory后出现多实例的问题
这其实是之前Intent Filter匹配错误导致的——系统认为每次的Intent都不匹配栈内Activity,所以创建新实例。修复Intent Filter后,singleTop的逻辑会正常生效:当MyActivity已经在栈顶时,再次调用匹配的Scheme,系统会复用现有实例并触发onNewIntent,不会创建新实例。
内容的提问来源于stack exchange,提问作者Jumpa

