React Native安卓端深度链接异常:冷启动时无法触发跳转
React Native Android 深度链接冷启动失效修复方案
一、调整AndroidManifest配置
保持SplashActivity为启动页(LAUNCHER),同时修正两个Activity的启动模式和属性:
<!-- SplashActivity 配置 --> <activity android:name=".SplashActivity" android:launchMode="singleTask" android:noHistory="true" <!-- 启动后自动从任务栈移除 --> android:theme="@style/SplashTheme"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <!-- MainActivity 配置 --> <activity android:name=".MainActivity" android:launchMode="singleTask" android:configChanges="keyboard|keyboardHidden|orientation|screenLayout|screenSize|smallestScreenSize|uiMode" android:exported="true" android:windowSoftInputMode="adjustResize"> <!-- 深度链接的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" /> <!-- 替换成你的scheme和host --> <data android:scheme="your-scheme" android:host="your-host" /> </intent-filter> </activity>
二、修改SplashActivity代码,传递深度链接Intent
在SplashActivity的onCreate里,把接收到的深度链接数据完整传给MainActivity:
public class SplashActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); Intent mainIntent = new Intent(this, MainActivity.class); Intent incomingIntent = getIntent(); // 把Splash接收到的所有Intent数据传递给MainActivity if (incomingIntent != null) { mainIntent.setData(incomingIntent.getData()); mainIntent.putExtras(incomingIntent.getExtras()); } // 适配singleTask模式,确保MainActivity正确接收 mainIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); startActivity(mainIntent); finish(); } }
三、修改MainActivity代码,同步Intent给RN的Linking模块
冷启动时RN的Linking可能无法自动识别传递的Intent,需要手动同步:
import com.facebook.react.ReactActivity; import com.facebook.react.modules.core.DeviceEventManagerModule; import com.facebook.react.bridge.WritableMap; import com.facebook.react.bridge.Arguments; import android.content.Intent; public class MainActivity extends ReactActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); handleDeepLink(getIntent()); } @Override protected void onNewIntent(Intent intent) { super.onNewIntent(intent); handleDeepLink(intent); setIntent(intent); // 更新当前Intent,避免后续获取错误 } private void handleDeepLink(Intent intent) { if (intent != null && intent.getData() != null) { String deepLinkUrl = intent.getData().toString(); // 把链接发送给RN侧 if (getReactInstanceManager().getCurrentReactContext() != null) { WritableMap params = Arguments.createMap(); params.putString("url", deepLinkUrl); getReactInstanceManager().getCurrentReactContext() .getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class) .emit("deepLinkReceived", params); } } } // 保留你的其他默认代码(比如ReactActivityDelegate相关) }
四、RN端处理深度链接
同时监听初始URL和手动传递的事件,确保冷启动和后台唤醒都能触发跳转:
import { Linking, useEffect, NativeEventEmitter, NativeModules } from 'react-native'; const handleDeepLink = (url) => { // 这里写你的跳转逻辑,比如解析URL后导航到对应页面 console.log('处理深度链接:', url); // 示例:navigation.navigate('TargetScreen', { url }); }; useEffect(() => { // 处理冷启动的初始URL const fetchInitialUrl = async () => { const url = await Linking.getInitialURL(); if (url) handleDeepLink(url); }; fetchInitialUrl(); // 处理后台唤醒的URL事件 const urlListener = Linking.addEventListener('url', ({ url }) => handleDeepLink(url)); // 处理手动从Native传递的深度链接事件(冷启动时用) const eventEmitter = new NativeEventEmitter(NativeModules.DeviceEventManagerModule); const deepLinkListener = eventEmitter.addListener('deepLinkReceived', ({ url }) => { if (url) handleDeepLink(url); }); return () => { urlListener.remove(); deepLinkListener.remove(); }; }, []);
核心注意事项
- 不要把深度链接的intent-filter同时放在Splash和MainActivity,避免Intent分发混乱
- SplashActivity加
android:noHistory="true",防止它留在任务栈导致后续启动异常 - MainActivity的
launchMode="singleTask"必须保留,解决多实例问题 - 冷启动时Native侧主动把链接传给RN,弥补
Linking.getInitialURL()的失效问题
内容的提问来源于stack exchange,提问作者scgough
相关产品推荐
相关产品推荐

