0

目前我有database1一个地图元素(标记点、折线点和多边形点及其信息)的数据库(调用是),对于折线/多边形点,我将它们的点(纬度/经度)保存在一个单独的数据库中(称之为database2) 其中每个点都是一个单独的数据库项,由 的元素 id 引用database1

当 MapFragment 加载时,我从数据库中提取所有内容AsyncTask

c = getActivity().getContentResolver().query(MapElements.CONTENT_URI,new String[] { MapElements.ID,MapElements.LOCATION_STRING,MapElements.LAYER_ID,MapElements.NEW_OR_MOD}, null, null, null);

遍历光标,如果元素是折线或多边形,我会使用该id元素的所有点拉出所有点并创建一个列表,以便稍后用于创建线或多边形

Cursor c2 = context.getContentResolver().query(MapPoints.CONTENT_URI,new String[] { MapPoints.LAYER_ID, MapPoints.LATITUDE,MapPoints.LONGITUDE },
                        MapPoints.ELEMENT_ID + "=?",new String[] { String.valueOf(id) }, null);
    if (c2 != null && c2.moveToFirst()) {
        do {
            locationArray.add(new LatLng(c2.getFloat(1), c2.getFloat(2)));
        } while (c2.moveToNext());

    }
c2.close();

然后我用列表将它绘制到地图上

Polyline line = map.addPolyline(new PolylineOptions().addAll(mElement.getLocationArray()));

整个过程可能需要很长时间,例如使用250不同的元素大约需要 10-15 秒才能将它们全部加载,并且地图元素的数量可能或多或少,因此显然点越多所需的时间就越长。

看看谷歌地图应用程序,看起来他们所有的标记都加载得很快,有什么办法可以加快速度吗?

更新

我对从 traceview 中可以理解的内容进行了一些挖掘,它说Handler操作是运行时间第二和第三长的操作。所以我所做的是在我的异步任务中取出处理程序,我用来回调主线程以放入地图,并且该过程在 2 秒内完成......

我现在取出处理程序代码并将其放在自己的方法中,这就是方法

private void test(final MapElement mElement){
        if (mElement.getType() > 0) {
            try{
                Handler h = new Handler(getActivity().getMainLooper());
                if (mElement.getType() == 3) {
                    h.post(new Runnable(){

                        public void run() {
                            Polygon poly = map.addPolygon(new PolygonOptions()
                            .addAll(mElement.getLocationArray()));

                    String color = mElement.getFillColor();
                    String borderColor = mElement.getBorderCOlor();

                    poly.setFillColor(Color.parseColor("#"+color));
                    poly.setStrokeColor(Color.parseColor("#"+borderColor));
                    poly.setStrokeWidth(4);

                    poly.setVisible(false);

                    Marker m = map.addMarker(new MarkerOptions()
                    .position(mElement.getPoint())
                    .icon(BitmapDescriptorFactory.fromResource(mElement.getMarkerIcon())));

                    m.setVisible(false);
                    m.setSnippet(String.valueOf(mElement.getID()));
                    mElement.setMarker(m);

                    mElement.setPolygon(poly);
                        }

                    });
                    mapElements.put(mElement.getID(), mElement);
                } else if (mElement.getType() == 2) {
                    h.post(new Runnable(){

                        public void run() {
                            Polyline line = map
                                    .addPolyline(new PolylineOptions()
                                            .addAll(mElement.getLocationArray()));

                            String borderColor = mElement.getBorderCOlor();

                            if(borderColor == null){
                                line.setColor(Color.BLUE);
                            }else{
                                line.setColor(Color.parseColor("#"+borderColor));
                            }

                            line.setWidth(mElement.getThickness());
                            line.setVisible(false);

                            if(mElement.getLayerId() != 16){
                                Marker m = map.addMarker(new MarkerOptions()
                                .position(mElement.getPoint())
                                .icon(BitmapDescriptorFactory.fromResource(mElement.getMarkerIcon())));

                            m.setVisible(false);
                            m.setSnippet(String.valueOf(mElement.getID()));

                            mElement.setMarker(m);
                            }

                            mElement.setPolyLine(line);

                        }

                    });
                    mapElements.put(mElement.getID(), mElement);
                } else {
                    h.post(new Runnable(){

                        public void run() {
                            Marker m = map.addMarker(new MarkerOptions()
                            .position(mElement.getPoint()).icon(
                                    BitmapDescriptorFactory.fromResource(mElement.getMarkerIcon())));

                                m.setVisible(false);
                                m.setSnippet(String.valueOf(mElement.getID()));
                                mElement.setMarker(m);
                        }

                    });
                    mapElements.put(mElement.getID(), mElement);
                }
                ContentValues values = new ContentValues();
                values.put(MapElements.PLOTTED, 1);
                getActivity().getContentResolver().update(Uri.withAppendedPath(MapElements.CONTENT_ID_URI_BASE,String.valueOf(mElement.getID())), values, null, null);


            }catch(NullPointerException e){
                e.printStackTrace();
            }
        }
    }

即使取出处理程序并将test方法放入 onPostExecute 仍然会导致延迟。完成此方法需要0.058 seconds一次,因此乘以 250 得出15 seconds

所以这似乎是这里的问题,我应该以不同的方式处理对主线程的回调吗?

4

1 回答 1

0

遍历光标,如果元素是折线或多边形,我会拉出具有该元素 id 的所有点

这很可能是你的罪魁祸首。每个 Hibernate 用户都可以告诉你 N+1 个查询非常非常糟糕。删除循环,在一个查询中加载所有点并在代码中制作逻辑。

于 2013-06-26T18:16:27.503 回答