Android-雙網(wǎng)絡(luò)實(shí)現(xiàn)


原本很早就想把這些東西寫文章保留下來锦针,但是只怪自己真的太懶啦仁堪,2年后的今天才開始整理當(dāng)時(shí)工作時(shí)的思路

背景

  • 借助Android 4G 阶捆,WiFi 雙網(wǎng)絡(luò)模式可以互補(bǔ)倦卖,大大的提高應(yīng)用的穩(wěn)定性
  • 作為一款工具類產(chǎn)品鸠匀,WiFi蕉斜,4G流量,使我們的業(yè)務(wù)重心,如何將4G & WiFi
    徹底打通蛛勉,為用戶提供更沉浸式的服務(wù)體驗(yàn)鹿寻,使我們一直以來的最求

思路

  • 非常感謝國外的一款產(chǎn)品,在實(shí)現(xiàn)上為我們提供了一個入門的思路 speedify

no bb show my code
如果有人感興趣這個實(shí)現(xiàn)過程诽凌,可以單獨(dú)來交流

具體實(shí)現(xiàn)方案

  • 準(zhǔn)備工作:
    1. 此方案借助了VPN來實(shí)現(xiàn)本地流量的劫持毡熏,并控制發(fā)送網(wǎng)絡(luò)通道
    2. 因?yàn)锳ndroid版本的差異性,實(shí)現(xiàn)方案也將按照高低不同版本來設(shè)計(jì)
    3. 因?yàn)楝F(xiàn)在手上已經(jīng)沒有那么多資源侣诵,所以更多的是代碼和思路講解痢法,如果你感興趣可能需要自己做一部分前置工作
      eg: VPN 搭建,后臺配套服務(wù)

基本實(shí)現(xiàn)思路

API < 6.0

  1. 啟動Android手機(jī)高速網(wǎng)卡杜顺,在啟動成功后將高速網(wǎng)卡 和 VPN出口IP綁定
  public class SetupHIPRIEnableTask extends TimerTask {

    private static final String TAG = "SetupHIPRIEnableTask\t";

    private Context mContext;

    public SetupHIPRIEnableTask(Context context) {
        mContext = context;
    }

    @Override
    public void run() {
        try {
            DLog.i(TAG + "Polling mobile network to make sure it stays up");
            ConnectivityManager connectivityManager = (ConnectivityManager) mContext
                    .getSystemService(CONNECTIVITY_SERVICE);
            if (connectivityManager == null) {
                Log.e(TAG, "ConnectivityManager is null, cannot try to force a mobile connection");
            } else if (connectivityManager.getNetworkInfo(5) == null) {
                Log.e(TAG, "Mobile Interface Not Found.");
            } else {
                int startUsingNetworkFeature = connectivityManager.startUsingNetworkFeature(0, "enableHIPRI");
                Log.d(TAG, "startUsingNetworkFeature for enableHIPRI result: " + startUsingNetworkFeature);
                if (-1 == startUsingNetworkFeature) {
                    Log.e(TAG, "Wrong result of startUsingNetworkFeature, maybe problems");
                }
                if (connectivityManager.getNetworkInfo(5).getState().compareTo(NetworkInfo.State.CONNECTED) == 0) {
                    Log.d(TAG, "Mobile network is connected");
                } else {
                    Log.d(TAG, "Mobile network is not connected");
                }
            }
            requestRouteToHost();
        } catch (Exception e) {
            Log.e(TAG, "Hit error in KeepMobileAliveTask ", e);
        }
    }

    /**
     * 等待 : TYPE_MOBILE_HIPRI類型的網(wǎng)絡(luò)建立連接后
     * <p/>
     * deliver traffic to the specified host via the specified network interface
     */
    private void requestRouteToHost() {
        String ip = AuthDataManager.getInstance().getAuthData().getIp();
        int i = AppUtil.convertIpToInt(ip);
        ConnectivityManager connectivityManager = (ConnectivityManager) mContext.getSystemService(CONNECTIVITY_SERVICE);
        if (connectivityManager == null) {
            DLog.i(TAG + "ConnectivityManager is null, cannot try to force a mobile connection");
        } else if (connectivityManager.getNetworkInfo(5) == null) {
            DLog.i(TAG + "Mobile Interface Not Found.");
        } else {
            int i2 = 0;
            while (i2 < 20) {
                try {
                    if (connectivityManager.getNetworkInfo(5).getState().compareTo(NetworkInfo.State.CONNECTED) == 0) {
                        break;
                    }
                    Thread.sleep(1000);
                    i2++;
                } catch (InterruptedException ignored) {
                }
            }
            DLog.i(TAG + "requestRouteToHost result: " + connectivityManager.requestRouteToHost(5, i));
        }
    }

}

API >= 6.0

  1. 通過Android標(biāo)準(zhǔn)API在WiFi連接的情況下财搁,請求4G網(wǎng)絡(luò)通道,
  2. 當(dāng)4G網(wǎng)絡(luò)通道成功后躬络,Android會回調(diào)一個networkId 尖奔,
  3. 通過NDK將此networkId與VPN的上網(wǎng)了進(jìn)程綁定,從而實(shí)現(xiàn)走VPN的數(shù)據(jù)流量都通過4G 網(wǎng)絡(luò)
public void requestWorkNetForHigh(Context context) {
        ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
        if (cm == null) {
            DLog.i("ConnectivityManager is null, cannot try to force a mobile connection");
            return;
        }
        DLog.i("post50MobileEnable, requesting Cellular network");
        NetworkRequest.Builder builder = new NetworkRequest.Builder();
        builder.addTransportType(0);
        builder.addCapability(12);
        NetworkRequest build = builder.build();
        unregisterNetworkCallback();
        try {
            if (mNetWorkCallBack == null) {
                mNetWorkCallBack = new MNetWorkCallBack();
            }
            DLog.i("Requesting Connectivity Manager");
            cm.requestNetwork(build, mNetWorkCallBack);
        } catch (SecurityException e) {
            DLog.i("com.speedify.speedifyAndroid.MobileController Cannot write settings. Requesting Permission");

        } catch (Exception e2) {
            DLog.e("Unknown Exception", e2);
            e2.printStackTrace();
        }
    }

  private class MNetWorkCallBack extends ConnectivityManager.NetworkCallback {

        @Override
        public void onAvailable(Network network) {
            DLog.i(TAG + "NetWorkCallBack " + network);
            super.onAvailable(network);
        }
    }

POC當(dāng)時(shí)的技術(shù)結(jié)論:

技術(shù)POC測試結(jié)論

--未完待補(bǔ)充

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末穷当,一起剝皮案震驚了整個濱河市提茁,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌馁菜,老刑警劉巖茴扁,帶你破解...
    沈念sama閱讀 216,692評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異汪疮,居然都是意外死亡峭火,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,482評論 3 392
  • 文/潘曉璐 我一進(jìn)店門智嚷,熙熙樓的掌柜王于貴愁眉苦臉地迎上來卖丸,“玉大人,你說我怎么就攤上這事盏道∨髌唬” “怎么了?”我有些...
    開封第一講書人閱讀 162,995評論 0 353
  • 文/不壞的土叔 我叫張陵摇天,是天一觀的道長。 經(jīng)常有香客問我恐仑,道長泉坐,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,223評論 1 292
  • 正文 為了忘掉前任裳仆,我火速辦了婚禮腕让,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己纯丸,他們只是感情好偏形,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,245評論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著觉鼻,像睡著了一般俊扭。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上坠陈,一...
    開封第一講書人閱讀 51,208評論 1 299
  • 那天萨惑,我揣著相機(jī)與錄音,去河邊找鬼仇矾。 笑死庸蔼,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的贮匕。 我是一名探鬼主播姐仅,決...
    沈念sama閱讀 40,091評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼刻盐!你這毒婦竟也來了掏膏?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,929評論 0 274
  • 序言:老撾萬榮一對情侶失蹤隙疚,失蹤者是張志新(化名)和其女友劉穎壤追,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體供屉,經(jīng)...
    沈念sama閱讀 45,346評論 1 311
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡行冰,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,570評論 2 333
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了伶丐。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片悼做。...
    茶點(diǎn)故事閱讀 39,739評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖哗魂,靈堂內(nèi)的尸體忽然破棺而出肛走,到底是詐尸還是另有隱情,我是刑警寧澤录别,帶...
    沈念sama閱讀 35,437評論 5 344
  • 正文 年R本政府宣布朽色,位于F島的核電站,受9級特大地震影響组题,放射性物質(zhì)發(fā)生泄漏葫男。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,037評論 3 326
  • 文/蒙蒙 一崔列、第九天 我趴在偏房一處隱蔽的房頂上張望梢褐。 院中可真熱鬧,春花似錦、人聲如沸盈咳。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,677評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽鱼响。三九已至鸣剪,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間热押,已是汗流浹背西傀。 一陣腳步聲響...
    開封第一講書人閱讀 32,833評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留桶癣,地道東北人拥褂。 一個月前我還...
    沈念sama閱讀 47,760評論 2 369
  • 正文 我出身青樓,卻偏偏與公主長得像牙寞,于是被迫代替她去往敵國和親饺鹃。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,647評論 2 354