easytier-contrib/easytier-android-jni/README.md
这是 EasyTier 的 Android JNI 绑定库,允许 Android 应用程序调用 EasyTier 的网络功能。
arm64-v8a (aarch64-linux-android)armeabi-v7a (armv7-linux-androideabi)x86 (i686-linux-android)x86_64 (x86_64-linux-android)安装 Rust
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
source ~/.cargo/env
安装 Android NDK
export ANDROID_NDK_ROOT=/path/to/android-ndk
添加 Android 目标
rustup target add aarch64-linux-android
rustup target add armv7-linux-androideabi
rustup target add i686-linux-android
rustup target add x86_64-linux-android
克隆项目并进入目录
cd /path/to/EasyTier/easytier-contrib/easytier-android-jni
运行构建脚本
./build.sh
构建完成后,库文件将生成在 target/android/ 目录下
target/android/
├── arm64-v8a/
│ └── libeasytier_android_jni.so
├── armeabi-v7a/
│ └── libeasytier_android_jni.so
├── x86/
│ └── libeasytier_android_jni.so
└── x86_64/
└── libeasytier_android_jni.so
将生成的 .so 文件复制到您的 Android 项目中:
your-android-project/
└── src/main/
├── jniLibs/
│ ├── arm64-v8a/
│ │ └── libeasytier_android_jni.so
│ ├── armeabi-v7a/
│ │ └── libeasytier_android_jni.so
│ ├── x86/
│ │ └── libeasytier_android_jni.so
│ └── x86_64/
│ └── libeasytier_android_jni.so
└── java/
└── com/easytier/jni/
└── EasyTierJNI.java
将 java/com/easytier/jni/EasyTierJNI.java 复制到您的 Android 项目的相应包路径下。
在 AndroidManifest.xml 中添加必要的权限:
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
import com.easytier.jni.EasyTierJNI;
import java.util.Map;
public class EasyTierManager {
// 初始化网络实例
public void startNetwork() {
String config = """
inst_name = "my_instance"
network = "my_network"
""";
try {
// 解析配置
int result = EasyTierJNI.parseConfig(config);
if (result != 0) {
String error = EasyTierJNI.getLastError();
throw new RuntimeException("配置解析失败: " + error);
}
// 启动网络实例
result = EasyTierJNI.runNetworkInstance(config);
if (result != 0) {
String error = EasyTierJNI.getLastError();
throw new RuntimeException("网络实例启动失败: " + error);
}
System.out.println("EasyTier 网络实例启动成功");
} catch (RuntimeException e) {
System.err.println("启动失败: " + e.getMessage());
}
}
// 获取网络信息
public void getNetworkInfo() {
try {
Map<String, String> infos = EasyTierJNI.collectNetworkInfosAsMap(10);
for (Map.Entry<String, String> entry : infos.entrySet()) {
System.out.println(entry.getKey() + ": " + entry.getValue());
}
} catch (RuntimeException e) {
System.err.println("获取网络信息失败: " + e.getMessage());
}
}
// 停止所有实例
public void stopNetwork() {
try {
int result = EasyTierJNI.stopAllInstances();
if (result == 0) {
System.out.println("所有网络实例已停止");
}
} catch (RuntimeException e) {
System.err.println("停止网络失败: " + e.getMessage());
}
}
}
如果您要在 Android VPN 服务中使用:
public class EasyTierVpnService extends VpnService {
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
// 建立 VPN 连接
ParcelFileDescriptor vpnInterface = establishVpnInterface();
if (vpnInterface != null) {
int fd = vpnInterface.getFd();
// 设置 TUN 文件描述符
try {
EasyTierJNI.setTunFd("my_instance", fd);
} catch (RuntimeException e) {
Log.e("EasyTier", "设置 TUN FD 失败", e);
}
}
return START_STICKY;
}
private ParcelFileDescriptor establishVpnInterface() {
Builder builder = new Builder();
builder.setMtu(1500);
builder.addAddress("10.0.0.2", 24);
builder.addRoute("0.0.0.0", 0);
builder.setSession("EasyTier VPN");
return builder.establish();
}
}
| 方法 | 描述 | 参数 | 返回值 |
|---|---|---|---|
parseConfig(String config) | 解析 TOML 配置 | config: 配置字符串 | 0=成功, -1=失败 |
runNetworkInstance(String config) | 启动网络实例 | config: 配置字符串 | 0=成功, -1=失败 |
setTunFd(String instanceName, int fd) | 设置 TUN 文件描述符 | instanceName: 实例名, fd: 文件描述符 | 0=成功, -1=失败 |
retainNetworkInstance(String[] names) | 保留指定实例 | names: 实例名数组 | 0=成功, -1=失败 |
collectNetworkInfos(int maxLength) | 收集网络信息 | maxLength: 最大条目数 | 信息字符串数组 |
collectNetworkInfosAsMap(int maxLength) | 收集网络信息为 Map | maxLength: 最大条目数 | Map<String, String> |
getLastError() | 获取最后错误 | 无 | 错误消息字符串 |
stopAllInstances() | 停止所有实例 | 无 | 0=成功, -1=失败 |
retainSingleInstance(String name) | 保留单个实例 | name: 实例名 | 0=成功, -1=失败 |
构建失败: "Android NDK not found"
ANDROID_NDK_ROOT 环境变量运行时错误: "java.lang.UnsatisfiedLinkError"
.so 文件放在正确的 jniLibs 目录下配置解析失败
getLastError() 获取详细错误信息adb logcat -s EasyTier-JNI 查看相关日志getLastError() 返回的错误信息本项目遵循与 EasyTier 主项目相同的许可证。
欢迎提交 Issue 和 Pull Request 来改进这个项目。