Android 5.x:导致 'Application Not Responding' 崩溃的无法定义的 IllegalArgumentException(使用 GoogleMap)

Android 5.x: Undefinable IllegalArgumentException (with GoogleMap) which causes 'Application Not Responding' crash

我遇到了 Android 5.x 版本的问题。它在 Android 4.x 中运行良好。

崩溃的视图在 ScrollView 中包含一个 GoogleMap。如果我不初始化地图,一切正常。如果我初始化,有时应用程序会崩溃或冻结,并且会出现以下错误(曲棍球中的多个设备出现相同的错误,Android 5.0 - Androdi 5.1.1):

java.lang.IllegalArgumentException
    at android.os.Parcel.nativeAppendFrom(Native Method)
    at android.os.Parcel.appendFrom(Parcel.java:446)
    at android.os.BaseBundle.writeToParcelInner(BaseBundle.java:1300)
    at android.os.Bundle.writeToParcel(Bundle.java:1034)
    at android.os.Parcel.writeBundle(Parcel.java:669)
    at android.location.Location.writeToParcel(Location.java:912)
    at android.os.Parcel.writeParcelable(Parcel.java:1363)
    at android.os.Parcel.writeValue(Parcel.java:1268)
    at android.os.Parcel.writeArrayMapInternal(Parcel.java:644)
    at android.os.BaseBundle.writeToParcelInner(BaseBundle.java:1313)
    at android.os.Bundle.writeToParcel(Bundle.java:1034)
    at android.os.Parcel.writeBundle(Parcel.java:669)
    at android.app.ActivityManagerProxy.activityStopped(ActivityManagerNative.java:2919)
    at android.app.ActivityThread$StopInfo.run(ActivityThread.java:3296)
    at android.os.Handler.handleCallback(Handler.java:739)
    at android.os.Handler.dispatchMessage(Handler.java:95)
    at android.os.Looper.loop(Looper.java:135)
    at android.app.ActivityThread.main(ActivityThread.java:5254)
    at java.lang.reflect.Method.invoke(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:372)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698)

地图的初始化应该不是问题,但如果我不调用"draw route on map"函数也不会出现问题。顺序如下

  1. 启动Activity并初始化地图
  2. 在地图上放置自定义标记
  3. 获取从用户位置到出口的路线 //<--CRASH
  4. 缩放地图以显示用户位置路线和出口

    private void initializeMap() {
        if (googleMap == null) {
    
            scrollableMapFragment = ((ScrollableMapFragment) getSupportFragmentManager()
                    .findFragmentById(R.id.retailer_detail_map));
    
            googleMap = scrollableMapFragment.getMap();
    
            // check if map is created successfully or not
            if (googleMap == null) {
                //show error
            } else {
    
                scrollableMapFragment
                        .setListener(new ScrollableMapFragment.OnTouchListener() {
                            @Override
                            public void onTouch() {
                                parallaxScrollView
                                        .requestDisallowInterceptTouchEvent(true);
                            }
                        });
    
                googleMap.getUiSettings().setMyLocationButtonEnabled(false);
                googleMap.setLocationSource(this); //This is required for balancing power and (low) battery usage!!!
                googleMap.setMyLocationEnabled(true);
                googleMap.getUiSettings().setZoomControlsEnabled(false);
                googleMap.getUiSettings().setZoomGesturesEnabled(true);
                googleMap.getUiSettings().setCompassEnabled(true);
                googleMap.getUiSettings().setRotateGesturesEnabled(false);
                googleMap.getUiSettings().setTiltGesturesEnabled(false);
                googleMap.getUiSettings().setScrollGesturesEnabled(true);
                googleMap.getUiSettings().setMapToolbarEnabled(false);
    
                placeOneMapMarker(customType);
            }
        }
    }
    
      private void placeOneMapMarker(CustomType marker) {
        LatLng latLng = null;
        GeoCoordinate geoCoordinate;
        MarkerOptions marker = null;
        geoCoordinate = marker.getGeoCoordinate();
        latLng = new LatLng(geoCoordinate.getLatitude(),
                geoCoordinate.getLongitude());
    
    
        marker = new MarkerOptions().position(latLng);
        // some more custom configurations...
    
        BitmapDescriptor icon = null;
        icon = iconManager.getShrinkedMapMarker(nRKER);
    
        marker.icon(icon);
        // adding marker
        googleMap.addMarker(marker);
    
        //CRASH!!!! if we uncomment this, everything works as expected
        showRoute();
    
    }
    
    
    private void showRoute(){
      new Thread(new Runnable() {
        @Override
        public void run() {
    
            try {
                routeFromPosition = new LatLng(locationDao.getCurrentLocation().getLatitude(), locationDao.getCurrentLocation().getLongitude());
                routeToPosition = new LatLng(outlet.getAddress().getGeoCoordinate().getLatitude(),
                        outlet.getAddress().getGeoCoordinate().getLongitude());
    
                GoogleMapRoute googleMapRoute = new GoogleMapRoute();
    
                Document doc = googleMapRoute.getDocument(routeFromPosition, routeToPosition, GoogleMapRoute.MODE_DRIVING);
                directionPoint = googleMapRoute.getDirection(doc);
    
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        if (directionPoint != null && directionPoint.size() > 0) {
                            showRoute();
                        } else {
                            zoomToOutletPosition();
                        }
                    }
                });
            } catch (Exception e) {
                //handle error
            }
        }
    }).start();
    

    }

还有一些 logcat 看起来像内存泄漏?

07-29 17:41:02.016      892-892/? D/CrashAnrDetector﹕ Build: samsung/kltexx/klte:5.0/LRX21T/G900FXXU1BOE5:user/release-keys
    Hardware: MSM8974
    Revision: 14
    Bootloader: G900FXXU1BOE5
    Radio: unknown
    Kernel: Linux version 3.4.0-4920185 (dpi@SWDD6122) (gcc version 4.8 (GCC) ) #1 SMP PREEMPT Fri May 15 16:40:14 KST 2015
    *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
    Build fingerprint: 'samsung/kltexx/klte:5.0/LRX21T/G900FXXU1BOE5:user/release-keys'
    Revision: '14'
    ABI: 'arm'
    pid: 30354, tid: 30371, name: FinalizerDaemon  >>> app.package.name <<<
    signal 11 (SIGSEGV), code 2 (SEGV_ACCERR), fault addr 0x7b35f752
    r0 b40cc17c  r1 aeea30e0  r2 9ac4cbb0  r3 00000000
    r4 44726579  r5 9ac4cbb0  r6 b40cc17c  r7 6e616c2f
    r8 696c616e  r9 af3b8800  sl 00000000  fp b40cc208
    ip b6b77e14  sp b40cc178  lr b6b6473d  pc b6b6bae6  cpsr 200b0030
    d0  0000000000000000  d1  0000000000000000
    d2  0000000000000000  d3  0000000000000000
    d4  0000000000000000  d5  0000000100000004
    d6  0000000000000000  d7  0000147389caaf68
    d8  41dfffffffc00000  d9  c1e0000000000000
    d10 43e0000000000000  d11 c3e0000000000000
    d12 df0000005f000000  d13 0000000000000000
    d14 0000000000000000  d15 0000000000000000
    d16 ffffffff9ac4cbb0  d17 65522f6665722f67
    d18 0000000000000000  d19 0000000060000000
    d20 0000000060000000  d21 0000000000000004
    d22 9fde15409fde1400  d23 9fde17c09fde1680
    d24 0000000000000000  d25 0000000000000000
    d26 0001000100010001  d27 0002000200020001
    d28 0000000003205f58  d29 00000000007ffaf0
    d30 0800080008000800  d31 0800080008000800
    scr 80000011
    backtrace:
    #00 pc 0001fae6  /system/lib/libbinder.so (android::Parcel::releaseObjects()+29)
    #01 pc 0001fb19  /system/lib/libbinder.so (android::Parcel::freeDataNoInit()+26)
    #02 pc 0001fb3b  /system/lib/libbinder.so (android::Parcel::~Parcel()+4)
    #03 pc 00083267  /system/lib/libandroid_runtime.so
    #04 pc 00017451  /system/framework/arm/boot.oat
    stack:
    b40cc138  b40cc1a8  [stack:30371]
    b40cc13c  b4b85fb5  /system/lib/libart.so (art::JniMethodEnd(unsigned int, art::Thread*)+12)
    b40cc140  b40cc164  [stack:30371]
    b40cc144  9ac4cbb0
    b40cc148  b40cc17c  [stack:30371]
    b40cc14c  b40cc228  [stack:30371]
    b40cc150  b40cc240  [stack:30371]
    b40cc154  b6b6473d  /system/lib/libbinder.so
    b40cc158  b6b7807c  /system/lib/libbinder.so
    b40cc15c  b6b6d8db  /system/lib/libbinder.so (android::ProcessState::self()+94)
    b40cc160  b40cc17c  [stack:30371]
    b40cc164  b6b780d4  /system/lib/libbinder.so
    b40cc168  9ac4cbb0
    b40cc16c  9ac4cbb0
    b40cc170  b40cc17c  [stack:30371]
    b40cc174  b6b6bad7  /system/lib/libbinder.so (android::Parcel::releaseObjects()+14)
    #00  b40cc178  9ac4cbb0
    b40cc17c  aeec7100
    b40cc180  9ac4cbb0
    b40cc184  00000000
    b40cc188  b4dfd034
    b40cc18c  b40cc228  [stack:30371]
    b40cc190  b40cc240  [stack:30371]
    b40cc194  b6b6bb1d  /system/lib/libbinder.so (android::Parcel::freeDataNoInit()+30)
    #01  b40cc198  9ac4cbb0
    b40cc19c  b40cc1cc  [stack:30371]
    b40cc1a0  9ac4cbb0
    b40cc1a4  9ac4cbb0
    b40cc1a8  b40cc1f0  [stack:30371]
    b40cc1ac  b6b6bb3f  /system/lib/libbinder.so (android::Parcel::~Parcel()+8)
    #02  b40cc1b0  9ac4cbb0
    b40cc1b4  b6dca26b  /system/lib/libandroid_runtime.so
    #03  b40cc1b8  000003e8
    b40cc1bc  74916453  /system/framework/arm/boot.oat
    #04  b40cc1c0  70c9ff98  /data/dalvik-cache/arm/system@framework@boot.art
    b40cc1c4  b40cc340  [stack:30371]
    b40cc1c8  00000001
    b40cc1cc  70c9f630  /data/dalvik-cache/arm/system@framework@boot.art
    b40cc1d0  00000000
    b40cc1d4  b40cc1f0  [stack:30371]
    b40cc1d8  b4dfd034
    b40cc1dc  b40cc228  [stack:30371]
    b40cc1e0  b40cc240  [stack:30371]
    b40cc1e4  00000000
    b40cc1e8  b40cc208  [stack:30371
07-29 17:41:02.016      892-892/? D/CrashAnrDetector﹕ processName:app.package.name
07-29 17:41:02.016      892-892/? D/CrashAnrDetector﹕ broadcastEvent : app.package.name SYSTEM_TOMBSTONE
07-29 17:41:02.016      257-257/? I/SurfaceFlinger﹕ id=1053 createSurf (49x49),1 flag=4, Application Error: app.package.name

我们刚刚在 Android 的帮助下解决了我们的问题 StrictMode

将以下内容添加到您的 Activity onCreate() 可为您提供有关崩溃和违反政策的更多详细信息。其中一项违规是我们崩溃的关键,但这与我发布的代码无关(问题是作为副作用发生的)

 protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder()
                    .detectDiskReads()
                    .detectDiskWrites()
                    .detectNetwork()   // or .detectAll() for all detectable problems
                    .penaltyLog()
                    .build());
        StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder()
                    .detectLeakedSqlLiteObjects()
                    .detectLeakedClosableObjects()
                    .penaltyLog()
                    .penaltyDeath()
                    .build());
        //...
}

API-Link: http://developer.android.com/reference/android/os/StrictMode.html