HarmonyOS鸿蒙Next中应用切换到后台后VPN功能异常如何解决
HarmonyOS鸿蒙Next中应用切换到后台后VPN功能异常如何解决
【问题现象】
应用集成了VPN功能,且已申请后台长时任务,但是在转入后台运行时,VPN引流功能失效,进而导致需要依赖VPN通道访问的业务异常。
【背景知识】
【定位思路】
从问题现象可以看到,主要原因是没有对VPN隧道进行保护。可以参考第2节中 “VPN连接”,对VPN隧道进行保护。
【解决方案】
1. 方案说明:
参照第2节中VPNExtension参考知识和VPN连接,对以下几个文件中的代码进行改造:
- MyVpnExtAbility.ts
- Index.ets
- build-profile.json5
2. 具体代码如下:
(1)MyVpnExtAbility.ts
导入相关模块:
import Want from '@ohos.app.ability.Want';
import VpnExtensionAbility from '@ohos.app.ability.VpnExtensionAbility';
import vpn_client from 'libvpn_client.so';
import vpnExt from '@ohos.net.vpnExtension';
import hilog from '@ohos.hilog';
import common from '@ohos.app.ability.common';
定义TAG和全局变量:
const TAG: string = "[MyVpnExtAbility]";
let g_tunFd = -1;
let g_tunnelFd = -1;
MyVpnExtAbility类主体:
export default class MyVpnExtAbility extends VpnExtensionAbility {
private VpnConnection: vpnExt.VpnConnectionExt
private vpnServerIp: string = '192.168.85.185';
private tunIp: string = '10.0.0.8';
private blockedAppName: string = 'com.example.testvpn';
onCreate(want: Want) {
console.info(TAG, `xdw onCreate, want: ${want.abilityName}`);
this.VpnConnection = vpnExt.createVpnConnection(this.context);
console.info("wmw createVpnConnection success")
this.CreateTunnel();
this.Protect();
console.info("xdw step4");
}
onRequest(want: Want, startId: number) {
console.info(TAG, `xdw onRequest, want: ${want.abilityName}`);
}
onConnect(want: Want) {
console.info(TAG, `xdw onConnect, want: ${want.abilityName}`);
let abilityName: string = want.parameters.abilityName.toString();
let bundleName: string = want.parameters.bundleName.toString();
return null;
}
onDisconnect(want: Want) {
console.info(TAG, `xdw onDisconnect, want: ${want.abilityName}`);
}
onDestroy() {
console.info(TAG, `xdw onDestroy`);
this.Destroy();
}
Destroy() {
hilog.info(0x0000, 'developTag', '%{public}s', 'vpn Destroy');
vpn_client.stopVpn(g_tunnelFd);
this.VpnConnection.destroy().then(() => {
hilog.info(0x0000, 'developTag', '%{public}s', 'vpn Destroy Success');
}).catch((err: Error) => {
hilog.error(0x0000, 'developTag', 'vpn Destroy Failed: %{public}s', JSON.stringify(err) ?? '');
})
}
CreateTunnel() {
console.info("xdw step1")
g_tunnelFd = vpn_client.tcpConnect(this.vpnServerIp, 8888);
}
Protect() {
console.info("xdw step2")
hilog.info(0x0000, 'developTag', '%{public}s', 'vpn Protect');
this.VpnConnection.protect(g_tunnelFd).then(() => {
hilog.info(0x0000, 'developTag', '%{public}s', 'vpn Protect Success');
this.SetupVpn();
}).catch((err: Error) => {
hilog.error(0x0000, 'developTag', 'vpn Protect Failed %{public}s', JSON.stringify(err) ?? '');
})
}
SetupVpn() {
console.info("xdw step3")
hilog.info(0x0000, 'developTag', '%{public}s', 'vpn SetupVpn');
class Address {
address: string;
family: number;
constructor(address: string, family: number) {
this.address = address;
this.family = family;
}
}
class AddressWithPrefix {...}
class Config {...}
let config = new Config(this.tunIp, this.blockedAppName);
try {
this.VpnConnection.create(config, (error, data) => {
g_tunFd = data;
hilog.error(0x0000, 'developTag', 'tunfd: %{public}s', JSON.stringify(data) ?? '');
vpn_client.startVpn(g_tunFd, g_tunnelFd);
})
} catch (error) {
hilog.error(0x0000, 'developTag', 'vpn setUp fail: %{public}s', JSON.stringify(error) ?? '');
}
}
}
AddressWithPrefix部分定义:
class AddressWithPrefix {
address: Address;
prefixLength: number;
constructor(address: Address, prefixLength: number) {
this.address = address;
this.prefixLength = prefixLength;
}
}
Config部分定义:
class Config {
addresses: AddressWithPrefix[];
mtu: number;
dnsAddresses: string[];
trustedApplications: string[];
blockedApplications: string[];
constructor(tunIp: string, blockedAppName: string) {
this.addresses = [new AddressWithPrefix(new Address(tunIp, 1), 24)];
this.dnsAddresses = ["114.114.114.114"];
this.trustedApplications = [];
this.blockedApplications = [];
}
}
(2)Index.ets
import common from '@ohos.app.ability.common'
import Want from '@ohos.app.ability.Want';
import vpnext from '@ohos.net.vpnExtension';
let context = getContext(this) as common.VpnExtensionContext;
let want: Want = {
deviceId: "",
bundleName: "com.example.testvpn",
abilityName: "MyVpnExtAbility",
};
@Entry
@Component
struct Index {
@State message: string = 'Hello World'
build() {
Row() {
Column() {
Text(this.message)
.fontSize(50)
.fontWeight(FontWeight.Bold).onClick(() => {
console.info("xdw btn click")
})
Button('Start Extension').onClick(() => {
console.info("xdw btn start")
vpnext.startVpnExtensionAbility(want)
}).width('70%').fontSize(45).margin(16)
Button('Stop Extension').onClick(() => {
console.info("xdw btn end")
vpnext.stopVpnExtensionAbility(want)
}).width('70%').fontSize(45).margin(16)
}.width('100%')
}.height('100%')
}
}
(3)build-profile.json5
{
"apiType": 'stageMode',
"buildOption": {
"externalNativeOptions": {
"path": "./src/main/cpp/CMakeLists.txt",
"arguments": "",
"cppFlags": "",
"abiFilters": ["arm64-v8a", "x86_64"]
}
},
"targets": [
{
"name": "default",
"runtimeOS": "HarmonyOS"
},
{
"name": "ohosTest",
}
]
}
【总结】
对集成了VPN功能的应用而言,如果其VPN功能不稳定,就尤其需要注意对VPN隧道的保护。可以考虑使用系统提供的VPN增强功能,详情可参考相关官方文档以及上述样例代码实现,避免VPN功能失效等异常情况的发生。
更多关于HarmonyOS鸿蒙Next中应用切换到后台后VPN功能异常如何解决的实战教程也可以访问 https://www.itying.com/category-93-b0.html
更多关于HarmonyOS鸿蒙Next中应用切换到后台后VPN功能异常如何解决的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html
在HarmonyOS鸿蒙Next中,应用切换到后台后VPN功能异常
在HarmonyOS鸿蒙Next中,应用切换到后台后VPN功能异常,可能是由于系统对后台应用的资源管理策略导致的。鸿蒙系统为了优化性能和电池续航,可能会限制后台应用的网络访问权限,从而影响VPN功能的正常运行。
要解决这个问题,可以尝试以下方法:
-
检查应用的后台权限:确保应用在后台运行时具有必要的网络访问权限。可以在“设置” -> “应用管理”中找到相关应用,检查其后台权限设置。
-
启用后台运行白名单:将VPN应用添加到系统的后台运行白名单中,以防止系统在应用切换到后台时限制其网络访问。可以在“设置” -> “电池” -> “应用启动管理”中进行配置。
-
更新系统和应用:确保系统和VPN应用都更新到最新版本,以获取最新的功能优化和问题修复。
-
检查VPN配置:确认VPN配置是否正确,包括服务器地址、认证信息等。错误的配置可能导致VPN在后台无法正常工作。
-
重启设备:有时简单的重启操作可以解决临时的系统或应用问题。
如果以上方法无法解决问题,可能需要进一步分析日志或联系应用开发者进行排查。