記一次App中多進程初始化致使百度定位失效問題

1、背景

項目中用到了多個第三方的SDK,其中有些外部服務是須要在AndroidManifest中配置的,而且經過形如android:process=":remote"配置單獨的進程。如百度定位,對應service配置以下:android

<service
    android:name="com.baidu.location.f"
    android:enabled="true"
    android:exported="false"
    android:process=":remote" />
複製代碼

應用寶最近升級了App的信息安全政策,對於App中有訪問過國外IP的行爲,都會予以臨時下架。項目中須要針對應用寶包渠道做特殊處理,將用到的國外第三方SDK去除。安全

爲了項目總體維護方便,採用方案Android Gradle基於參數化配置實現差別化構建,配置完成並構建。bash

即,以應用寶渠道去掉Flurry爲例,經過Gradle設置參數標識後,Flurry初始化等各相關調用方法中,採用了mock方式的空方法實現,並不依賴Flurry SDK。工具

構建完成後,接到線上用戶反饋百度定位功能失效。post


2、排查與解決

Android Gradle基於參數化配置實現差別化構建,方案自己已經比較成熟,項目中多處針對差別化的構建場景下都有所使用。構建完成後的安裝包,也分別反編譯並覈驗過最終的mock效果。優化

經調試發現,針對去掉Flurry的構建,在百度定位時不能如期取得定位結果,定位功能直接失效。spa

經排查,具體緣由以下:調試

對於AndroidManifest中配置了多進程的service,App啓動時會同時會啓動對應進程,也就是說,此時除了App主進程外,還會對應有其餘配置了的進程。而且,對自定義的Application而言,會分別屢次實例化。Application的每次實例化,因爲實在不一樣的進程中,相互之間是不要緊的。日誌

項目中針對不一樣的組件,如日誌組件、Flurry等,在Application中初始化時,有着各自對進程的判斷信息,如日誌組件僅是針對App主進程中才初始化(作了專門的進程判斷),Flurry則是針對全部進程都會初始化(沒有作進程判斷,至於爲何不作主進程判斷,有其餘方面考慮)。且Flurry的初始化是封裝在特定的FlurryHelper類中,對上述的mock寫法,FlurryHelper中爲了輸出對應日誌,又用到了日誌組件。code

/**
 * mock Flurry工具類
 *
 */
public final class FlurryHelper {
    public static final String TAG = "FlurryUtil";

    public synchronized static void initFlurry(Context context, boolean innerProcess) {
        CLog.d(TAG, "flurry init...mock");
    }

    public static void onStart(Context context){
        CLog.d(TAG, "flurry onStart...mock");
    }

    public static void onEndSession(Context context){
        CLog.d(TAG, "flurry onEndSession...mock");
    }
}
複製代碼

因而,問題產生了,對於百度定位進程而言,不管是App一開始啓動時,仍是後續進行定位服務時,啓動的百度定位進程,在執行Application初始化時,最終都調用到了mock寫法中的FlurryHelper對應方法,而其中,日誌組件是並未初始化的,致使百度定位進程事實上的運行時異常而終止。

Android官方的系統中,App中只要有進程發生未捕獲異常,都會有運行時異常終止彈窗。固然了,對於集成第三方SDK的進程,雖然在當前App中有進程異常終止彈窗,但force stopping確認後,但並不影響對App中與此第三方SDK無關的功能使用。只是會讓用戶感受有所困惑。

國內App手機廠商,通常都對此作了進一步優化。如集成第三方SDK的進程崩潰,每每都直接沒有異常終止彈窗提示到用戶。此時,對用戶而言,App中非主進程的崩潰是無感知的。固然了,對應的功能仍是會受到影響。

這也就解釋了,App沒有任何崩潰感知的狀況下,百度定位功能卻莫名失效了。


解決:

知道問題緣由後,其實解決起來很是容易,直接將mock的FlurryHelper中的日誌組件替換成Android原生日誌類Log便可。


3、結語

項目中,每每都會有意無心中使用到多進程,尤爲對應AndroidManifest中配置的多進程,是每每容易被忽略的。多進程在初始化時,會分別執行各自的Application實例的初始化。而Application初始化中,通常都會進行其餘各組件等初始化。此時,須要確認清組件與進程之間的依賴關係。若有必要,組件初始化時須要進行進程判斷。特別須要注意的是,在多進程場景下的組件間的依賴關係,以及對應的初始化前後順序等。

國內的手機廠商,針對App中非主進程的崩潰,每每用戶層面是沒法感知的。但對應的功能依然會受到影響。所以,涉及到此類多進程時,須要格外當心。

end~

相關文章
相關標籤/搜索