問題描述
按照友盟官方文檔集成了6.1.0的推送,可一直沒法接收到推送消息。android
問題分析
猜想應該是項目其餘代碼形成的。可是又沒有報錯信息。猜想在application中代碼有問題,在application中只保留關於推送的代碼,發現推送成功。而後放開一部分代碼再推送,找到了在application中有初始化webview的操做以後,推送失敗。爲何關於webview的初始化會引發推送失敗呢。原來是友盟開啓了一個新的進程,而在多進程的狀況下,每個進程都會執行一次application。application中初始化webview的代碼會執行不止一次。而在9.0以上的系統中,爲改善應用穩定性和數據完整性,應用沒法再讓多個進程共享一個 WebView 數據目錄。因此,友盟啓動的進程在執行初始化webview操做的時候致使這個進程崩潰,從而沒法接收到消息,又不影響主進程的運行,致使肉眼沒法觀測到。web
解決方案
因而可知,每一個進程都要執行一次application,那麼若是咱們不加判斷,全部的初始化都要執行屢次。因此咱們能夠經過獲取進程名稱的方式,判斷哪些應該初始化。數據庫
@Override public void onCreate() { super.onCreate(); String processName = getProcessName(this); if (processName != null) { if (processName.equals("進程名稱")) { //...須要在不一樣進程下運行的代碼 } } } //獲取進程名稱 private String getProcessName(Context context) { ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE); List<ActivityManager.RunningAppProcessInfo> runningApps = am.getRunningAppProcesses(); if (runningApps == null) { return null; } for (ActivityManager.RunningAppProcessInfo proInfo : runningApps) { if (proInfo.pid == android.os.Process.myPid()) { if (proInfo.processName != null) { return proInfo.processName; } } } return null; }
主進程的名稱是程序的包名,填寫包名便可。這樣咱們一些如用戶信息,數據庫等操做只在主進程下執行。優化了性能,也避免出現重複執行產生的問題。app
因爲友盟推送特殊指出了必須在自定義application的onCreate 方法中進行初始化,同時不能對初始化作進程判斷,尤爲是主進程和channel進程,不然會吐司提示「Toast提示mPushAgent.register should be called in both main process and channel process!」,因此推薦這樣進行Application的初始化:ide
@Override public void onCreate() { super.onCreate(); try { String processName = getProcessName(this); //判斷是當前APP進程 if ("主工程包名".equals(processName)) { //app其它資源的初始化 applicationInit(); } //初始化友盟推送、統計不區分進程 initPush(); } catch (Exception e) { e.printStackTrace(); } }
參考資料
https://www.jianshu.com/p/b154dcecd1fd性能
https://blog.csdn.net/Kebiiii/article/details/77938008優化
https://developer.umeng.com/docs/67966/detail/67140?spm=a311a.7996332.0.0.6caf3080fk4ltVthis