一、开发环境要求
·Android Studio 2.0+
·Android 7.0(SDK API 24)及以上系统
二、SDK 引用及依赖配置
1. Maven 引入。
2. AAR 包引入。
注意:说明:
注意:使用 Maven 引入可忽略此步骤。
·将 AAR 文件复制到工程目录下(例如:app / libs)。
·在 Gradle 文件中增加依赖配置。
dependencies {//添加 SDK 依赖implementation fileTree(dir: 'libs', include: ['*.aar']) //添加gson依赖implementation 'com.google.code.gson:gson:2.8.9'}
三、VPN 模式
MpAccClient 初始化
注意:说明:
注意:SDK 认证也可按应用接入,调用接口 MpAccClient.setSign("appid","*****"),设备接入和应用接入只需设置其一即可。
注意:sign 生成方式可参见 设备管理(动态设备/应用)。
private void initMpAcc() { //腾讯云申请的datakey需传入(此处使用按设备接入) MpAccClient.setDataKey("test-123456", "*"); mpAccClient = MpAccClient.getInstance(this); }
发起加速
private void startAcc() { try { mpAccClient.registerAccCallback(accCallback); //vpn加速需要用户授权 Intent vpnIntent = MpAccClient.prepare(this); if (vpnIntent != null) { startActivityForResult(vpnIntent, VPN_REQUEST_CODE); } else { onActivityResult(VPN_REQUEST_CODE, RESULT_OK, null); } } catch (MpAccSDKException e) { e.printStackTrace(); } } @Override protected void onActivityResult(int requestCode, int resultCode, @Nullable Intentdata) { super.onActivityResult(requestCode, resultCode, data); if (requestCode == VPN_REQUEST_CODE && resultCode == RESULT_OK) { try { AccConfig accConfig = new AccConfig(); ArrayList<String> list = new ArrayList<>(); accConfig.setAccMode(AccConfig.ACC_MOD_BONDING); //设置加速模式 accConfig.setRoute("0.0.0.0", 0); //加速ip列表 //list.add("air.tv.douyu.android"); //传入需要加速的包名,不传默认对所有应用加速 accConfig.setWhiteList(list, 0); mpAccClient.startAcc(accConfig); } catch (MpAccSDKException e) { e.printStackTrace(); } } }
资源释放
//在退出时释放资源,比如Activity的onDestroy方法中调用 private void stopAcc() { try { mpAccClient.unregisterAccCallback(accCallback); mpAccClient.stopAcc(); } catch (MpAccSDKException e) { e.printStackTrace(); } }
四、SOCKS 模式
注意:SOCKS 接入不需要 VPN 权限。用户可在 App 目录下的清单文件中做如下配置删除掉权限声明,避免 App 上架审核被拒
<manifest xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools"> <!– 不需要前台服务 connectedDevice 类型时移除 –> <uses-permission android:name="android.permission.FOREGROUND_SERVICE_CONNECTED_DEVICE" tools:node="remove" /> <application> <service android:name="com.android.linkboost.multi.acc.service.LinkBoostService" tools:remove="android:permission" /> </application></manifest>
注意:说明:
注意:SOCKS 模式加速无需用户授权,MpAcc 初始化鉴权逻辑和状态监听与 VPN 模式一致。
private void initMpAcc() { MpAccClient.setDataKey("test-123456", "*"); mpAccClient = MpAccClient.getInstance(this); } //发起加速(socks模式) private void startSocksAcc() { AccConfig accConfig = new AccConfig(); accConfig.setAccMode(AccConfig.ACC_MOD_BONDING) .setPingInterval(3) .setEnableSocks(true) //Socks模式需要设置为true .setSocksPort(1080);//设置代理端口 try { //监听加速状态回调 mpAccClient.registerAccCallback(accCallback); mpAccClient.startAcc(accConfig); } catch (MpAccSDKException e) { e.printStackTrace(); } } private void stopSocksAcc() { try { mpAccClient.unregisterAccCallback(accCallback); mpAccClient.stopAcc(); } catch (MpAccSDKException e) { e.printStackTrace(); } }
注意:SOCKS 模式发起加速成功后(接收到 onAccSuccess 回调),业务需将网络库接口通过 SOCKS 协议封装发送,代理 IP 为本地 IP,代理端口和发起加速时 setSocksPort 设置的端口保持一致,流量才会进入加速隧道。
以下是常见的网络库切换 SOCKS5 示例:
//UDP使用socks5发包示例 private void testUdpSocks() { try { Log.i(TAG, "start testUdp"); //1、端口需和发起加速设置的setSocksPort保持一致 SocksProxy socksProxy = new Socks5(new InetSocketAddress("localhost", 1080)); //2、将socksProxy设置给DatagramSocket DatagramSocket clientSocket = new Socks5Datagram(socksProxy); //3、后续进行正常的发包业务 String message = "Hi, I am UDP client"; byte[] sendBuffer = message.getBytes(); DatagramPacket packet = new DatagramPacket(sendBuffer, sendBuffer.length, new InetSocketAddress("106.55.119.181", 8888)); clientSocket.send(packet); //Received response message from UDP server. } catch (IOException e) { e.printStackTrace(); } } //HttpURLConnection使用socks代理 private void testHttpSocks() { BufferedReader buff = null; HttpURLConnection urlConnection = null; try { //创建proxy代理 Proxy socksProxy = new Proxy(Proxy.Type.SOCKS, new InetSocketAddress("127.0.0.1", 1080)); URL url = new URL("url"); //Proxy添加给HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection(socksProxy); //后续进行正常的发包业务 } catch (Exception e) { e.printStackTrace(); } } //OKHttp使用socks代理 private void testOkHttpSocks(){ //创建proxy代理 Proxy socksProxy =new Proxy(Proxy.Type.SOCKS, new InetSocketAddress("127.0.0.1", 1080)); //Proxy添加给OkHttpClient OkHttpClient client = new OkHttpClient.Builder().proxy(socksProxy).build(); //后续进行正常的发包业务 } //TCP Socket使socks用代理 private void testSocketSocks() { Proxy socksProxy =new Proxy(Proxy.Type.SOCKS, new InetSocketAddress("127.0.0.1", 1080)); Socket socket = new Socket(socksProxy); //… }
五、C++ SOCKS 模式
TCP 和 UDP 接入 SOCKS 参考 文档。
六、常见问题解答
1. 使用 SDK VPN 模式加速,如果其他三方 App 也打开了 VPN 功能,加速是否生效?
答:不生效,Android 系统默认同一时间只能打开一个 VPN 服务,如果其他应用程序也打开了 VPN,当前加速 VPN 服务会被释放,onAccFail 回调错误码 -5,加速停止。
2. 如何使用 SOCKS 模式进行加速?
答:使用 SOCKS 模式进行加速,除了通过调用 startAcc 方法配置加速模式和 SOCKS 端口,还需要将业务相关的网络接口封装成 SOCKS5 代理发送,封装示例请参考 SOCKS 模式代码示例,代理 IP 默认为本机 IP,端口需要与发起加速时传入的保持一致。
3. SOCKS 模式和 VPN 模式加速有什么区别?
答:两种模式都是为了获取业务数据流来进行加速转发,VPN 模式加速需要用户同意鉴权弹窗,并且系统 UI 上会出现小钥匙图标,使用 VPN 模式可以对当前手机上的任何三方应用进行加速。SOCKS 模式不需要用户进行鉴权,但需要用户改造业务网络数据发送接口,通过 SOCKS 代理发送。
4. 能否使用双 Wi-Fi,或者使用自定义 USB 网卡进行多网加速?
答:目前云聚通 Android SDK 支持 Wi-Fi、MOBILE、ETH 等3种类型的网卡进行加速,可通过调用 setAccLinks 方法来添加用户想进行加速的网卡。如果想添加 SDK 不支持的网卡类型,可通过 addNetworkPlugin 函数添加网卡插件来动态添加自定义网卡,参考插件网卡加速。
5. MeasureCallback 接口中 onStopMpAcc 和 onAccException 两个回调函数有什么区别?
答:SDK 回调 onStopMpAcc,是提醒用户关闭加速,主要终端在单网卡环境、默认路由网络已恢复正常或者长时间没有明显加速效果的时候触发,是否最终关闭加速(stopAcc)的决定权取决于用户自己。
SDK 回调 onAccException,是表明当前加速出现了重大异常,如加速后出现断网,时延过大,加速负优化或加速效果远不及预期,SDK 会主动关闭加速和测速,让业务流量回源,防止因加速异常影响业务正常使用。
6. 如何获取一次加速使用的总流量,以及加速过程中各个链路的带宽速率?
答:AccCallback 中提供了 onAccDataUpdate 回调函数,携带的参数包含了加速上行、下行总流量以及各个链路的详细信息(PathDetail)。
7. 云聚通 SDK minSdkVersion 为24,大于业务自身设置的 minSdkVersion,打包编译报错,如何解决?
答:在清单文件中添加以下配置,并在代码中动态判断,如果当前系统版本小于24,不要调用云聚通 SDK 接口。
<uses-sdk tools:overrideLibrary="com.android.linkboost.multi,androidx.security"/>
8. 发起加速后,没有进行实际的业务请求,onAccDataUpdate 也会回调加速流量,这个是什么原因?
答:SDK 内部协商握手、协议探测等流程会产生流量,这些流量很小可以忽略不计,且不会计入加速计费。
9. libc++_shared.so 冲突如何解决?
答:MNA SDK 使用 c++_shared 方式链接 STL,因此 SDK 的 AAR 中会携带一份 libc++_shared.so。若你的 App 或其依赖的其它 SDK(如 xlog / mars、自研 native 库等)也携带了该文件,需做如下配置:
android { packaging { jniLibs { // 多个 aar 携带 libc++_shared.so 时,只保留一份 pickFirsts += ['**/libc++_shared.so'] } }}