Android折线绘制上的ArrayIndexOutOfBounds

时间:2016-07-08 07:34:37

标签: android google-maps google-maps-markers google-maps-android-api-2

我正在使用谷歌地图精简模式版本,其中我在联想K50a40上绘制多边形线和标记我收到以下错误

  **Non-fatal Exception: java.lang.ArrayIndexOutOfBoundsException: length=42; index=42**
   at maps.ah.k.a(Unknown Source:4000)
   at maps.ah.k.a(Unknown Source)
   at maps.ah.k.a(Unknown Source)
   at maps.ah.i.a(Unknown Source)
   at maps.ah.d.onDraw(Unknown Source)
   at android.view.View.draw(View.java:16457)
   at android.view.View.buildDrawingCacheImpl(View.java:15722)
   at android.view.View.buildDrawingCache(View.java:15576)
   at android.view.View.draw(View.java:16204)
   at android.view.ViewGroup.drawChild(ViewGroup.java:3746)
   at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3536)
   at android.view.View.updateDisplayListIfDirty(View.java:15402)
   at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:3730)
   at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:3710)
   at android.view.View.updateDisplayListIfDirty(View.java:15361)
   at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:3730)
   at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:3710)
   at android.view.View.updateDisplayListIfDirty(View.java:15361)
   at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:3730)
   at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:3710)
   at android.view.View.updateDisplayListIfDirty(View.java:15361)
   at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:3730)
   at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:3710)
   at android.view.View.updateDisplayListIfDirty(View.java:15361)
   at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:3730)
   at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:3710)
   at android.view.View.updateDisplayListIfDirty(View.java:15361)
   at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:3730)
   at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:3710)
   at android.view.View.updateDisplayListIfDirty(View.java:15361)
   at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:3730)
   at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:3710)
   at android.view.View.updateDisplayListIfDirty(View.java:15361)
   at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:3730)
   at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:3710)
   at android.view.View.updateDisplayListIfDirty(View.java:15361)
   at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:3730)
   at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:3710)
   at android.view.View.updateDisplayListIfDirty(View.java:15361)
   at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:3730)
   at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:3710)
   at android.view.View.updateDisplayListIfDirty(View.java:15361)
   at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:3730)
   at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:3710)
   at android.view.View.updateDisplayListIfDirty(View.java:15361)
   at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:3730)
   at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:3710)
   at android.view.View.updateDisplayListIfDirty(View.java:15361)
   at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:3730)
   at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:3710)
   at android.view.View.updateDisplayListIfDirty(View.java:15361)
   at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:3730)
   at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:3710)
   at android.view.View.updateDisplayListIfDirty(View.java:15361)
   at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:3730)
   at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:3710)
   at android.view.View.updateDisplayListIfDirty(View.java:15361)
   at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:3730)
   at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:3710)
   at android.view.View.updateDisplayListIfDirty(View.java:15361)
   at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:3730)
   at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:3710)
   at android.view.View.updateDisplayListIfDirty(View.java:15361)
   at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:3730)
   at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:3710)
   at android.view.View.updateDisplayListIfDirty(View.java:15361)
   at android.view.ThreadedRenderer.updateViewTreeDisplayList(ThreadedRenderer.java:286)
   at android.view.ThreadedRenderer.updateRootDisplayList(ThreadedRenderer.java:292)
   at android.view.ThreadedRenderer.draw(ThreadedRenderer.java:327)
   at android.view.ViewRootImpl.draw(ViewRootImpl.java:3024)
   at android.view.ViewRootImpl.performDraw(ViewRootImpl.java:2828)
   at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2440)
   at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1325)
   at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:6741)
   at android.view.Choreographer$CallbackRecord.run(Choreographer.java:912)
   at android.view.Choreographer.doCallbacks(Choreographer.java:714)
   at android.view.Choreographer.doFrame(Choreographer.java:649)
   at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:898)
   at android.os.Handler.handleCallback(Handler.java:815)
   at android.os.Handler.dispatchMessage(Handler.java:104)
   at android.os.Looper.loop(Looper.java:207)
   at android.app.ActivityThread.main(ActivityThread.java:5769)
   at java.lang.reflect.Method.invoke(Method.java)
   at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:789)
   at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:679)

及以下是我在谷歌地图上绘制路线的逻辑

 public static void drawRouteIntoMap(List<? extends MapHelper> position, final GoogleMap googleMap , final boolean removeMarker) {
        /*List<MapHelper> position = new ArrayList<MapHelper>();
        for (int i = lastPosition; i < maps.size(); i++) {
            position.add(maps.get(i));
        }*/
        if (position.size() > 0 && Validator.isNotNull(googleMap)) {
           // googleMap.clear();
            final List<? extends MapHelper> tempList=new ArrayList<>(position);
            if(tempList.size()!=pointList.size()) {
                tempList.removeAll(pointList);
            }

            List<PolylineOptions> polylineOptionses = new ArrayList<PolylineOptions>();
            PolylineOptions option = null;
            Boolean lastPause = null;
            for (MapHelper map : tempList) {
                if (map.isPause()) {
                    if (Validator.isNull(lastPause) || !lastPause) {
                        option = new PolylineOptions().width(5).color(Color.rgb(255, 0, 155)).geodesic(true);
                        polylineOptionses.add(option);
                    }
                    option.add(new LatLng(map.getLatitude(), map.getLongitude()));
                } else {
                    if (Validator.isNull(lastPause) || lastPause) {
                        option = new PolylineOptions().width(5).color(Color.rgb(0, 179, 253)).geodesic(true);
                        polylineOptionses.add(option);
                    }
                    option.add(new LatLng(map.getLatitude(), map.getLongitude()));
                }
                lastPause = map.isPause();
            }
            for (PolylineOptions options : polylineOptionses) {
                googleMap.addPolyline(options);
            }
            if(Validator.isNotNull(option)) {
                List<LatLng> points = option.getPoints();
                final LatLngBounds.Builder mapBounds = new LatLngBounds.Builder();
                for (LatLng latLng : points) {
                    mapBounds.include(latLng);
                }

                googleMap.setOnMapLoadedCallback(new GoogleMap.OnMapLoadedCallback() {
                    @Override
                    public void onMapLoaded() {
                        if(removeMarker) {
                            if (Validator.isNotNull(endMarker)) {
                                startMarker.remove();
                                endMarker.remove();
                            }
                        }
                        LatLng startPoint = new LatLng(tempList.get(0).getLatitude(), tempList.get(0).getLongitude());
                        Marker marker1=googleMap.addMarker(new MarkerOptions().position(startPoint).title("start").icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_GREEN)));
                        LatLng endPoint = new LatLng(tempList.get(tempList.size() - 1).getLatitude(), tempList.get(tempList.size() - 1).getLongitude());
                        Marker marker2=googleMap.addMarker(new MarkerOptions().position(endPoint).title("finish").icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_RED)));
                        googleMap.moveCamera(CameraUpdateFactory.newLatLngBounds(mapBounds.build(), 10));
                        googleMap.animateCamera(CameraUpdateFactory.newLatLngBounds(mapBounds.build(), 10));
                        googleMap.moveCamera(CameraUpdateFactory.zoomOut());
                        startMarker=marker1;
                        endMarker=marker2;

                    }
                });

                pointList = position;

            }

        }
    }

我在其中进行测试的设备只发生在lenovo k50a40型号中我无法弄清楚实际原因是否有任何帮助。

1 个答案:

答案 0 :(得分:3)

为什么会崩溃?

通过查看异常,一切都表明您正在错误地遍历数组(或列表)。

检查主要信息

  

java.lang.ArrayIndexOutOfBoundsException:length = 42;指数= 42

弄清楚接下来会发生什么,这更加棘手,主要是因为我们没有任何关于代码的信息:

   at maps.ah.k.a(Unknown Source:4000)
   at maps.ah.k.a(Unknown Source)
   at maps.ah.k.a(Unknown Source)
   at maps.ah.i.a(Unknown Source)

为什么它可以在其他一些设备上运行?

不同的Android设备具有不同的软件基础和硬件基础(取决于制造它们的公司),因此可以预期在某些点上会看到不同的行为。

因此,即使其他设备可以处理非致命异常,联想K50a40似乎也无法做到。或者它甚至可能是联想系统设计不正确,没有办法知道。

我该怎么办?

你几乎无能为力。 我的解决方案是帮助您找到路径:

  1. 随时随地放置控制台日志。
  2. 删除尽可能多的逻辑并逐渐添加,直到找到破坏它的东西。
  3. 删除java中的forEach并强制执行常规for (int i = 0; i < maps.size(); i++)循环,并监控i的值。
  4. 代码评估

    这就是说,有一些我不能从你的代码中得到的东西。

    if (map.isPause()) {
        if (Validator.isNull(lastPause) || !lastPause) {
            option = new PolylineOptions().width(5).color(Color.rgb(255, 0, 155)).geodesic(true);
            polylineOptionses.add(option);
        }
        option.add(new LatLng(map.getLatitude(), map.getLongitude()));
    } else {
        if (Validator.isNull(lastPause) || lastPause) {
            option = new PolylineOptions().width(5).color(Color.rgb(0, 179, 253)).geodesic(true);
            polylineOptionses.add(option);
        }
        option.add(new LatLng(map.getLatitude(), map.getLongitude()));
    }
    

    如果map.isPause()返回true并且Validator.isNull(lastPause) || !lastPause返回false,会发生什么?

    如果我理解正确,您将在空对象上运行option.add(new LatLng(map.getLatitude(), map.getLongitude()));

    这将导致Null异常。

    你能给出一些不是pointList变量的上下文吗?

    我知道这可能不是你所希望的,但我仍然希望它会有所帮助。