Skip to content

Android 集成指南

核心库引入 (AAR)

SDK 的核心网络引擎以 AAR 形式提供。如果您是纯原生 Android 项目(非 Flutter),请按照以下步骤操作:

  1. tunnel_core.aar 放入项目的 app/libs 目录下。
  2. app/build.gradle 中添加依赖:
gradle
dependencies {
    implementation fileTree(dir: 'libs', include: ['*.aar'])
    // Xray 核心依赖(如果 AAR 未内置)
    implementation 'io.netty:netty-all:4.1.68.Final' 
}

权限配置

请确保您的 AndroidManifest.xml 中已申请必要的权限:

xml
<!-- 基础网络权限 -->
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

<!-- 前台服务权限 (Android 9+) -->
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<!-- 数据同步类型 (Android 14+) -->
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_DATA_SYNC" />

现代 Android (AGP 8.0+) 集成注意事项

在新版 Android Gradle Plugin (AGP) 环境下,请注意以下配置变动:

1. Namespace 配置

不要在 AndroidManifest.xml 中使用 package 属性定义包名,应在 app/build.gradle 中指定:

gradle
android {
    namespace = "your.package.name"
    // ...
}

2. 编译 SDK 版本

为了兼容最新的 Android 特性和 Flutter 核心插件,建议将 compileSdktargetSdk 设置为 36

安全与隐私

User-Agent 伪装

为了防止网络层通过 User-Agent 特征拦截 SDK 的配置获取请求,SDK 内置了自动伪装机制:

  • 自动移除:请求中不会包含 DartFlutter 或项目特定的标识。
  • 动态模拟:根据运行平台,自动模拟通用的 Android Chrome 或 iOS Safari 浏览器 UA。
  • 覆盖范围:涵盖了 API 请求和 DoH (DNS over HTTPS) 查询全流程。

常见问题 (FAQ)

1. AAR 版本选择

  • tunnel_core.aar (推荐):包含完整的 Go 运行时支持,适用于大多数独立项目。
  • tunnel_core_stripped.aar:剥离了公共运行时类,专门用于解决与 OpenIM 等其他 Gomobile 库的 go.Seq 冲突。

2. 64位与32位架构支持

我们的 AAR 默认支持 arm64-v8aarmeabi-v7a

3. 与 OpenIM 等 Gomobile 库冲突

如果您同时集成了其他基于 Go 编写的库,可能会遇到 Duplicate class go.Seq 错误。

解决方案:剥离版 AAR 引入

为了彻底解决冲突,我们建议使用 剥离版 AAR (tunnel_core_stripped.aar)。

app/build.gradle 中,请使用以下稳健的方式引入依赖:

gradle
repositories {
    flatDir {
        // 确保能找到 AAR 所在的目录
        dirs 'libs' 
    }
}

dependencies {
    // 使用 name/ext 方式引入,这比直接 files 引用在多模块项目中更稳定
    implementation(name: 'tunnel_core_stripped', ext: 'aar')
}

并在项目的 build.gradle.kts (如果使用 Kotlin DSL) 中添加仓库路径解析:

kotlin
allprojects {
    repositories {
        google()
        mavenCentral()
        flatDir {
            // 指向插件或库内部的 libs 目录
            dirs(project(":dynamic_domain").projectDir.resolve("libs"))
        }
    }
}

4. PlatformException (channel-error) 错误

如果在启动时遇到 Unable to establish connection on channel 错误:

  1. 包名与路径对齐:确保您的 MainActivity.kt 物理路径与 build.gradle 中的 namespace 完全一致(例如:com.dynamic.domain.example 必须对应 src/main/kotlin/com/dynamic/domain/example/MainActivity.kt)。
  2. 执行清理:运行 flutter clean,并物理删除 android/.gradle 目录后重新编译。
  3. 检查真机:部分预览版模拟器(如 Android 16 API 36)对插件通道初始化支持不稳,建议优先使用 Android 14/15 或真机验证。

基于 MIT 许可发布