You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.13 19:15:59