PlacePicker調用導致GooglePlayservier崩潰

今天收到一個Bug:Hangouts發送位置信息時提示google play services停止運行,異常的Log如下,

04-27 15:10:56.774 19455 19455 E AndroidRuntime: Process: com.google.android.gms.ui, PID: 19455
04-27 15:10:56.774 19455 19455 E AndroidRuntime: java.lang.RuntimeException: Unable to resume activity {com.google.android.gms/com.google.android.location.places.ui.placepicker.PlacePickerActivity}: java.lang.NullPointerException: Attempt to invoke interface method 'void com.google.maps.api.android.lib6.impl.bq.o()' on a null object reference
04-27 15:10:56.774 19455 19455 E AndroidRuntime:        at android.app.ActivityThread.performResumeActivity(ActivityThread.java:3109)
04-27 15:10:56.774 19455 19455 E AndroidRuntime:        at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:3140)
04-27 15:10:56.774 19455 19455 E AndroidRuntime:        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2481)
04-27 15:10:56.774 19455 19455 E AndroidRuntime:        at android.app.ActivityThread.access$900(ActivityThread.java:150)
04-27 15:10:56.774 19455 19455 E AndroidRuntime:        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1344)
04-27 15:10:56.774 19455 19455 E AndroidRuntime:        at android.os.Handler.dispatchMessage(Handler.java:102)
04-27 15:10:56.774 19455 19455 E AndroidRuntime:        at android.os.Looper.loop(Looper.java:148)
04-27 15:10:56.774 19455 19455 E AndroidRuntime:        at android.app.ActivityThread.main(ActivityThread.java:5423)
04-27 15:10:56.774 19455 19455 E AndroidRuntime:        at java.lang.reflect.Method.invoke(Native Method)
04-27 15:10:56.774 19455 19455 E AndroidRuntime:        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
04-27 15:10:56.774 19455 19455 E AndroidRuntime:        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
04-27 15:10:56.774 19455 19455 E AndroidRuntime: Caused by: java.lang.NullPointerException: Attempt to invoke interface method 'void com.google.maps.api.android.lib6.impl.bq.o()' on a null object reference
04-27 15:10:56.774 19455 19455 E AndroidRuntime:        at com.google.maps.api.android.lib6.impl.da.b(:com.google.android.gms.DynamiteModulesB:96)
04-27 15:10:56.774 19455 19455 E AndroidRuntime:        at com.google.android.gms.maps.internal.z.onTransact(:com.google.android.gms.DynamiteModulesB:73)
04-27 15:10:56.774 19455 19455 E AndroidRuntime:        at android.os.Binder.transact(Binder.java:387)
04-27 15:10:56.774 19455 19455 E AndroidRuntime:        at url.b(:com.google.android.gms:233)
04-27 15:10:56.774 19455 19455 E AndroidRuntime:        at upa.a(:com.google.android.gms:127)
04-27 15:10:56.774 19455 19455 E AndroidRuntime:        at omy.b(:com.google.android.gms:340)
04-27 15:10:56.774 19455 19455 E AndroidRuntime:        at omu.a(:com.google.android.gms:143)
04-27 15:10:56.774 19455 19455 E AndroidRuntime:        at com.google.android.gms.maps.MapView.a(:com.google.android.gms:7332)
04-27 15:10:56.774 19455 19455 E AndroidRuntime:        at amzd.onResume(:com.google.android.gms:92)
04-27 15:10:56.774 19455 19455 E AndroidRuntime:        at com.google.android.chimera.FragmentProxy.onResume(:com.google.android.gms:433)
04-27 15:10:56.774 19455 19455 E AndroidRuntime:        at gm.a(:com.google.android.gms:12120)
04-27 15:10:56.774 19455 19455 E AndroidRuntime:        at gm.a(:com.google.android.gms:1286)
04-27 15:10:56.774 19455 19455 E AndroidRuntime:        at gm.a(:com.google.android.gms:1268)
04-27 15:10:56.774 19455 19455 E AndroidRuntime:        at gm.p(:com.google.android.gms:2153)
04-27 15:10:56.774 19455 19455 E AndroidRuntime:        at gm.a(:com.google.android.gms:12126)
04-27 15:10:56.774 19455 19455 E AndroidRuntime:        at gm.a(:com.google.android.gms:1286)
04-27 15:10:56.774 19455 19455 E AndroidRuntime:        at gm.a(:com.google.android.gms:1268)
04-27 15:10:56.774 19455 19455 E AndroidRuntime:        at gm.p(:com.google.android.gms:2153)
04-27 15:10:56.774 19455 19455 E AndroidRuntime:        at gc.e(:com.google.android.gms:11223)
04-27 15:10:56.774 19455 19455 E AndroidRuntime:        at bxe.superOnResumeFragments(:com.google.android.gms:2406)
04-27 15:10:56.774 19455 19455 E AndroidRuntime:        at com.google.android.chimera.Activity.onResumeFragments(:com.google.android.gms:384)
04-27 15:10:56.774 19455 19455 E AndroidRuntime:        at com.google.android.chimera.Activity.publicOnResumeFragments(:com.google.android.gms:389)
04-27 15:10:56.774 19455 19455 E AndroidRuntime:        at bxe.e(:com.google.android.gms:469)
04-27 15:10:56.774 19455 19455 E AndroidRuntime:        at gc.onPostResume(:com.google.android.gms:511)
04-27 15:10:56.774 19455 19455 E AndroidRuntime:        at bxe.superOnPostResume(:com.google.android.gms:2401)
04-27 15:10:56.774 19455 19455 E AndroidRuntime:        at com.google.android.chimera.Activity.onPostResume(:com.google.android.gms:375)
04-27 15:10:56.774 19455 19455 E AndroidRuntime:        at bxc.onPostResume(:com.google.android.gms:183)
04-27 15:10:56.774 19455 19455 E AndroidRuntime:        at com.google.android.chimera.Activity.publicOnPostResume(:com.google.android.gms:380)
04-27 15:10:56.774 19455 19455 E AndroidRuntime:        at bxe.onPostResume(:com.google.android.gms:460)
04-27 15:10:56.774 19455 19455 E AndroidRuntime:        at android.app.Activity.performResume(Activity.java:6385)
04-27 15:10:56.774 19455 19455 E AndroidRuntime:        at android.app.ActivityThread.performResumeActivity(ActivityThread.java:3092)
04-27 15:10:56.774 19455 19455 E AndroidRuntime:        ... 10 more

從Log中看到是應用調用PlacePickerActivity時的空指針異常,一看就感覺這可能不是單個應用Bug。於是跑到Google Play上下載了會調用PlacePicker的其他應用:Google Keep,測試發現果然也是一樣的問題。這就說明Google Map API提供的PlacePicker這個功能就完全沒法用了!這就嚴重了。

在Google上搜了一下,發現還不少人遇到這個問題,在Google issue tracker上還有一條記錄:https://issuetracker.google.com/issues/37127543。大神們的大多在討論應用開發時遇到這個問題怎麼解決。零星幾條是手機原廠的留言,而且並未給出解決辦法。

只能自己看Log分析了,從StactTrace中看到最終空指針發生的地方是在ResolutionOverride.java這個類中:

/** @hide */
    public ResolutionOverride(SurfaceView view) {
        boolean enable = (view.getContext().getApplicationInfo().canOverrideRes() == 1);
        int orientation = view.getResources().getConfiguration().orientation;

        if(enable && (orientation == Configuration.ORIENTATION_PORTRAIT ||
                orientation == Configuration.ORIENTATION_LANDSCAPE)) {
            String resStr = SystemProperties.get(RES_OVERRIDE, null);

具體是在view.getResources().getConfiguration().orientation這一行,應該是view.getResources()獲取的是空,然後我就不知道咋整了,圖樣啊。。。和同事討論下,建議我先catch試試,抱着死馬當活馬醫的心態試了一下,竟然都正常了。。。。我表示很無奈啊。

想着catch都行,那試試更好看點的,改爲:
view.getContext().getResources().getConfiguration().orientation,我感覺自己都在自欺欺人,沒想到也可以!嚇得我趕緊在看了下View的源碼:

public View(Context context) {
        mContext = context;
        mResources = context != null ? context.getResources() : null;
        mViewFlags = SOUND_EFFECTS_ENABLED | HAPTIC_FEEDBACK_ENABLED;
        // Set some flags defaults
        mPrivateFlags2 =

從這構造函數來看,mResources爲null,不就是約等於context也爲null麼?而且View中的mResources是定義爲final的!這真的就涉及到我的知識盲區了。。

提供了一個“不知道原理”的解決方案,如果大神路過,還請指教。

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