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的!这真的就涉及到我的知识盲区了。。

提供了一个“不知道原理”的解决方案,如果大神路过,还请指教。

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