Flutter使用app_links包时,运行中传递Deep Link参数失败问题
Flutter app_links无法获取Deep Link排查方案
1. 先检查平台配置是否完整
Deep Link的生效依赖Android/iOS的系统配置,这是最容易忽略的环节:
Android端配置
在android/app/src/main/AndroidManifest.xml的<activity>标签内添加对应的intent-filter(替换成你的自定义scheme和包名):
<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" /> <!-- 自定义Scheme,比如myapp://xxx --> <data android:scheme="myapp" android:host="yourhost" /> </intent-filter>
- 若使用http/https的Universal Link,还需在网站根目录的
.well-known文件夹放置assetlinks.json文件,配置包名和签名指纹;测试阶段可暂时去掉android:autoVerify="true"简化流程。
iOS端配置
在ios/Runner/Info.plist中添加URL Schemes配置:
<key>CFBundleURLTypes</key> <array> <dict> <key>CFBundleURLSchemes</key> <array> <string>myapp</string> <!-- 自定义Scheme --> </array> </dict> </array>
- 若使用Universal Link,需在Xcode中开启"Associated Domains",添加对应的域名(如
applinks:yourdomain.com)。
2. 验证Deep Link本身的有效性
先跳过NFC,直接用系统命令测试Deep Link是否能触发应用:
- Android:执行adb命令(替换成你的包名和Link)
adb shell am start -W -a android.intent.action.VIEW -d "myapp://yourhost/test?id=123" com.your.package.name - iOS:针对模拟器执行
xcrun simctl openurl booted myapp://yourhost/test?id=123
如果命令能唤起应用并捕获到Link,说明代码和配置没问题,再排查NFC标签的写入内容是否正确(标签需写入标准URI格式,如myapp://yourhost/test?param=xxx)。
3. 代码优化建议
完善Stream订阅的生命周期管理
当前代码未取消Stream订阅,可能导致内存泄漏,同时确保初始化时机正确:
import 'package:flutter/material.dart'; import 'package:app_links/app_links.dart'; class TestView extends StatefulWidget { @override State<TestView> createState() => _TestViewState(); } class _TestViewState extends State<TestView> { final AppLinks _appLinks = AppLinks(); String uri = ''; StreamSubscription? _linkSubscription; // 新增订阅对象 @override void initState() { super.initState(); _handleDeepLinks(); } void _handleDeepLinks() async { // 处理冷启动的初始Link final Uri? initialLink = await _appLinks.getInitialLink(); if (initialLink != null) { _navigateToScreen(initialLink); } // 订阅后台唤起的Link流 _linkSubscription = _appLinks.uriLinkStream.listen((Uri? uri) { if (uri != null) { _navigateToScreen(uri); } }, onError: (err) { print("Deep link error: $err"); }); } void _navigateToScreen(Uri uri) { print("Navigating to: ${uri.toString()}"); setState(() { this.uri = uri.toString(); }); } @override void dispose() { _linkSubscription?.cancel(); // 页面销毁时取消订阅 super.dispose(); } @override Widget build(BuildContext context) { return MaterialApp( title: 'Deep Linking Demo', home: Scaffold( appBar: AppBar(title: Text("Deep Linking Example")), body: Center( child: Text('uri = $uri'), ), ), ); } }
全局初始化(可选)
若应用冷启动时需要更早获取初始Link,可将AppLinks初始化放到main函数中:
void main() async { WidgetsFlutterBinding.ensureInitialized(); final AppLinks appLinks = AppLinks(); final Uri? initialLink = await appLinks.getInitialLink(); runApp(MyApp(initialDeepLink: initialLink)); }
4. 测试场景覆盖
- 冷启动测试:完全杀掉应用,触发Deep Link(NFC扫描/系统命令),验证
getInitialLink()是否返回正确结果 - 热启动测试:应用处于后台,触发Deep Link,验证
uriLinkStream是否能收到回调
内容的提问来源于stack exchange,提问作者Preem Palver2
相关产品推荐
相关产品推荐

