項目中用到了多個第三方的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
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便可。
項目中,每每都會有意無心中使用到多進程,尤爲對應AndroidManifest中配置的多進程,是每每容易被忽略的。多進程在初始化時,會分別執行各自的Application實例的初始化。而Application初始化中,通常都會進行其餘各組件等初始化。此時,須要確認清組件與進程之間的依賴關係。若有必要,組件初始化時須要進行進程判斷。特別須要注意的是,在多進程場景下的組件間的依賴關係,以及對應的初始化前後順序等。
國內的手機廠商,針對App中非主進程的崩潰,每每用戶層面是沒法感知的。但對應的功能依然會受到影響。所以,涉及到此類多進程時,須要格外當心。
end~