Android之解決開啓熱點後跳轉頁面不穩定問題

1 問題

在Android8.0版本以後,開啓熱點我們採用的下面這種方式,但是跳轉頁面後熱點會斷開,手機不能互相傳文件了

權限說明:Android8.0需要位置權限和GPS權限,同時手機熱點還不能是開啓狀態。

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            try {
                mWifiManager.startLocalOnlyHotspot(new WifiManager.LocalOnlyHotspotCallback() {
                    @Override
                    public void onFailed(int reason) {
                        super.onFailed(reason);
                        Log.i(TAG, "onFailed start");
                    }

                    @Override
                    public void onStarted(WifiManager.LocalOnlyHotspotReservation reservation) {
                        super.onStarted(reservation);
                        Log.i(TAG, "onStarted start");
                        mReservation = reservation;
                        WifiConfiguration wifiConfiguration = reservation.getWifiConfiguration();
                        String ssid = wifiConfiguration.SSID;
                        String pwd = wifiConfiguration.preSharedKey;
                        Log.i(TAG, "ssid is:" + ssid);
                        Log.i(TAG, "pwd is:" + pwd);
                    }

                    @Override
                    public void onStopped() {
                        super.onStopped();
                        sendBroadcast(STOP_STATE, "", "");
                    }
                }, new Handler());
            } catch (Exception e) {
                e.printStackTrace();
                Log.e(TAG, "startLocalOnlyHotspot error");
            }
    }

 

 

 

 

 

 

 

2 思考

1)全局靜態保存mReservation變量,跳頁面的時候不執行close方法。

我們看到上面的代碼

mReservation = reservation;

我們關閉,是這樣關閉的

 if (mReservation != null) {
     mReservation.close();
     mReservation = null;
 }

爲了防止熱點關閉,我們一開始對mReservation變量做了全局靜態的保存,但是依然存在開啓熱點後,熱點會斷的問題。

 

 

2)反編譯"茄子快傳"代碼,分析別人的產品

"茄子快傳" 這個app也是熱點生成後多個手機連接,然後進行文件的發送,我們反編譯“茄子快傳”代碼

搜索關鍵字startLocalOnlyHotspot,如下圖

 

這裏看起來像用了反射,我們點擊進去看這個函數

 

的確用了反射,明明有API爲啥用反射呢?現在也搞不懂,到底有沒有蹊蹺現在也不知,然後我再看下在哪裏調用這個函數

很明顯這裏開啓了一個服務,然後在onStartCommand函數裏面傳遞了一個攜帶參數的intent過來,如果是0就是執行關閉函數,如果是1的話就執行開啓熱點函數,然後它也重寫了這個回調LocalOnlyHotspotCallback

 把LOHSService作爲構造函數參數傳遞進去,然後開啓熱點成功後,執行this.a.a(1, str, wifiConfiguration.preSharedKey);
這個函數,也就是發送攜帶用戶名和密碼的廣播到其它頁面

然後我也這樣模仿開啓一個服務,在服務裏面開啓熱點去測試,配置如下

        <service android:name="**********.LocalHotService" android:exported="false">
            <intent-filter>
                <action android:name="**********.LocalHotService"/>
            </intent-filter>
        </service>

發現依然不穩定,只不過我開啓的時候是用API來開啓的,不是用的反射,然後我就採用它的代碼,用反射進行開啓,效果依然不穩定,說明這裏沒區別,由於第一次開啓熱點,非常穩定,第二次開啓熱點會很不穩定,所以思考是不是由於關閉熱點出了問題

 if (mReservation != null) {
     mReservation.close();
     mReservation = null;
 }

然後我嘗試,不採用中間變量mReservation保存,用反射進行關閉

    @TargetApi(Build.VERSION_CODES.M)
    public void stopHotPoint(Context context) {
        try {
            ConnectivityManager manager = (ConnectivityManager) context.getApplicationContext().getSystemService(ConnectivityManager.class);
            Method method = manager.getClass().getDeclaredMethod("stopTethering", int.class);
            if (method == null) {

            } else {
                method.invoke(manager, 0);
            }
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        } catch (Exception e){
            e.printStackTrace();
        }
    }

這樣掉,還需要申請一個修改系統設置的權限,需要通過startActivity去申請,當然

android.permission.WRITE_SETTINGS

當然在AndroidManifest.xml裏面也要配置好

    <uses-permission
        android:name="android.permission.WRITE_SETTINGS"

        tools:ignore="ProtectedPermissions" />

 這樣程序纔不會奔潰

 

然後我們再分析下源碼,這裏系統會調用finalize方法,內存不夠就可能執行,然後裏面回調用close方法,然後close裏面會調用stopLocalOnlyHotspot()方法,這裏就會關閉熱點
可能由於內存不夠導致不穩定,然後既然開啓了熱點服務,我們爲什麼不能在開闢一個進程呢?
然後把服務放在另外一個進程裏面,另外一個進程沒有太多其它操作,內存一般不會執行Java垃圾回收

然後在單獨一個進程開啓服務,測試這個熱點就非常穩定了,問題也解決了

 

 

 

 

3 解決辦法

再開闢一個新的進程裏面開啓熱點服務

  <service android:name="*****.LocalHotService" android:exported="false"
            android:process=":aptest">
            <intent-filter>
                <action android:name="*****.LocalHotService"/>
            </intent-filter>
        </service>

 

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章