简介:本文详细讲解React Native在Android端实现Deep Link的完整流程,涵盖配置、代码实现、安全验证及优化建议,帮助开发者高效集成深度链接功能。
Deep Link(深度链接)是指通过统一资源标识符(URI)直接跳转到应用内特定页面而非首页的技术。在Android生态中,其实现依赖于Intent Filter和URI模式匹配,与iOS的URL Scheme存在显著差异。React Native作为跨平台框架,在Android端实现Deep Link需特别注意原生模块的集成与权限配置。
Android系统处理Deep Link的核心机制是隐式Intent。当用户点击包含特定URI的链接时,系统会查询已安装应用中声明匹配Intent Filter的应用。例如,example://product/123这样的URI需要应用在Manifest中配置对应的<intent-filter>。React Native开发者需理解这一底层原理,才能正确实现跨平台一致的深度链接体验。
在android/app/src/main目录下的Manifest文件中,需为目标Activity添加Intent Filter。以下是一个电商应用商品详情页的配置示例:
<activity android:name=".MainActivity"><intent-filter><action android:name="android.intent.action.VIEW" /><category android:name="android.intent.category.DEFAULT" /><category android:name="android.intent.category.BROWSABLE" /><dataandroid:scheme="https"android:host="yourdomain.com"android:pathPrefix="/product/" /><dataandroid:scheme="example"android:host="product" /></intent-filter></activity>
关键配置点:
VIEW动作和BROWSABLE类别example://)pathPrefix用于匹配路径前缀,支持正则表达式在MainActivity.java中,需重写getIntent()方法获取URI数据:
@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);Intent intent = getIntent();Uri data = intent.getData();if (data != null) {String scheme = data.getScheme();String host = data.getHost();String path = data.getPath();// 将数据传递给React NativeWritableMap params = Arguments.createMap();params.putString("scheme", scheme);params.putString("host", host);params.putString("path", path);getReactInstanceManager().getCurrentReactContext().getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class).emit("DeepLinkReceived", params);}}
在JS层通过NativeEventEmitter监听原生事件:
import { NativeEventEmitter, NativeModules } from 'react-native';const DeepLinkModule = NativeModules.DeepLinkModule || {};const eventEmitter = new NativeEventEmitter(DeepLinkModule);// 组件挂载时添加监听useEffect(() => {const subscription = eventEmitter.addListener('DeepLinkReceived', (data) => {if (data.scheme === 'example' && data.host === 'product') {const productId = data.path.split('/')[1];navigateToProductDetail(productId);}});return () => subscription.remove();}, []);
建议采用中央路由表管理所有深度链接规则:
const DEEP_LINK_ROUTES = {'example://product/:id': (params) => `ProductDetail?id=${params.id}`,'https://yourdomain.com/product/:id': (params) => `ProductDetail?id=${params.id}`,'example://promotion/:code': (params) => `Promotion?code=${params.code}`};function parseDeepLink(uri) {const url = new URL(uri);for (const [pattern, handler] of Object.entries(DEEP_LINK_ROUTES)) {const regex = pathToRegexp(pattern);const match = regex.exec(url.pathname);if (match) {const params = {};Object.keys(match).slice(1).forEach((key, i) => {params[regex.keys[i].name] = match[key];});return handler(params);}}return null;}
当应用未运行时,需在MainActivity的onNewIntent中处理:
@Overrideprotected void onNewIntent(Intent intent) {super.onNewIntent(intent);setIntent(intent); // 必须重新设置Intent// 重复onCreate中的URI处理逻辑}
Intent.getPackage()是否来自可信应用
// 验证示例private boolean verifyDeepLink(Uri uri) {String expectedSignature = uri.getQueryParameter("sig");String dataToSign = uri.getScheme() + "://" + uri.getHost() + uri.getPath();String actualSignature = HMACUtils.computeHmac(dataToSign, SECRET_KEY);return Objects.equals(expectedSignature, actualSignature);}
// Jest测试示例test('parses product deep link correctly', () => {const uri = 'example://product/123';const result = parseDeepLink(uri);expect(result).toBe('ProductDetail?id=123');});
android:exported="true"(针对Android 12+)<category android:name="android.intent.category.DEFAULT" />存在onCreate和onNewIntent中都要处理Intentintent.getDataString()作为备用获取方式com.yourcompany.example)Google推荐的App Links提供了更安全的深度链接方案,配置步骤:
assetlinks.json
<intent-filter android:autoVerify="true"><action android:name="android.intent.action.VIEW" /><category android:name="android.intent.category.DEFAULT" /><category android:name="android.intent.category.BROWSABLE" /><data android:scheme="https" android:host="yourdomain.com" /></intent-filter>
通过系统级验证,App Links可避免显示选择对话框,提供更流畅的用户体验。React Native开发者应逐步将深度链接方案迁移至App Links标准。
本文系统阐述了React Native在Android端实现Deep Link的全流程,从基础配置到安全优化,提供了可落地的解决方案。开发者可根据实际需求选择自定义Scheme或HTTP(S)方案,并逐步向更安全的App Links过渡。