使用ASYNC任务加载地图引脚

时间:2011-12-23 17:05:13

标签: android

我已经成功地将地图引脚添加到我的地图叠加层,但它加载缓慢并且在地图上移动是缓慢的。我在想它是从服务器下载地图引脚的时候。这些引脚的尺寸仅为20-30 kb,但有时可能需要添加25个引脚。我已经尝试在后台添加引脚但它会破坏应用程序。如何在不影响性能的情况下在背景中添加引脚?

当用户触摸地图并执行此ASYNC任务时,我从地图获取位置。

    private class mapStations extends AsyncTask<Void, Void, JSONObject> {

    @Override
    protected JSONObject doInBackground(Void... arg0) {

        JSONObject obj = null;
        try {
            obj = new JSONObject(API.nearByStations(pxLat, pxLng, 0));

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

        return obj;
    }

    @Override
    protected void onPostExecute(JSONObject details) {
        String tag = "mapStations";
        JSONArray stations;
        Drawable d = null;
        try {
            mapOverlays = mapView.getOverlays();
            mapOverlays.clear();
            stations = details.getJSONArray("stations");

            for (int j = 0; j < stations.length(); j++) {
                JSONObject jsonObject = stations.getJSONObject(j);
                Log.i(tag, "url: " + jsonObject.getString("logo"));
                try {

                    Bitmap staticImage = BitmapFactory
                            .decodeStream((InputStream) new URL(jsonObject.getString("logo"))
                                    .getContent());
                    d = new BitmapDrawable(staticImage);

                } catch (MalformedURLException e) {
                    Log.e(tag, e.toString());
                    e.printStackTrace();
                } catch (IOException e) {
                    Log.e(tag, e.toString());
                    e.printStackTrace();
                }
                add(jsonObject.getDouble("lat"),
                        jsonObject.getDouble("lng"), d);
            }

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

    }
}

public void add(double lat, double lng, Drawable d) {

    mapOverlays = mapView.getOverlays();
    if(d.equals(null)){
        Log.i(tag, "d was null");
        d = this.getResources().getDrawable(R.drawable.androidmarker);
    }

    itemizedOverlay = new MapsOverlay(d);

    GeoPoint point = new GeoPoint((int) (lat * 1e6), (int) (lng * 1e6));
    OverlayItem overlayitem = new OverlayItem(point, "", "");

    itemizedOverlay.addOverlay(overlayitem);
    mapOverlays.add(itemizedOverlay);
}

这是在doinbackground中添加点的logcat。它不是每次都会发生,但它确实发生了。当它发生时我似乎无法重现。有时当我缩小时会发生这种情况,有时候当我在地图上移动时会发生这种情况。我在这里有类似的问题Android MapView JSON Array Adding Array of points,但我最终将其移至post执行。就像我之前提到的,加载引脚需要一段时间。我现在有点不知所措。我一整天都在努力。

    [12-23 13:46:27.246: E/AndroidRuntime(1359): Uncaught handler: thread main exiting due to uncaught exception
12-23 13:46:27.286: E/AndroidRuntime(1359): java.util.ConcurrentModificationException
12-23 13:46:27.286: E/AndroidRuntime(1359):     at java.util.AbstractList$SimpleListIterator.next(AbstractList.java:64)
12-23 13:46:27.286: E/AndroidRuntime(1359):     at com.google.android.maps.OverlayBundle.draw(OverlayBundle.java:41)
12-23 13:46:27.286: E/AndroidRuntime(1359):     at com.google.android.maps.MapView.onDraw(MapView.java:476)
12-23 13:46:27.286: E/AndroidRuntime(1359):     at android.view.View.draw(View.java:6535)
12-23 13:46:27.286: E/AndroidRuntime(1359):     at android.view.ViewGroup.drawChild(ViewGroup.java:1531)
12-23 13:46:27.286: E/AndroidRuntime(1359):     at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1258)
12-23 13:46:27.286: E/AndroidRuntime(1359):     at android.view.ViewGroup.drawChild(ViewGroup.java:1529)
12-23 13:46:27.286: E/AndroidRuntime(1359):     at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1258)
12-23 13:46:27.286: E/AndroidRuntime(1359):     at android.view.View.draw(View.java:6538)
12-23 13:46:27.286: E/AndroidRuntime(1359):     at android.widget.FrameLayout.draw(FrameLayout.java:352)
12-23 13:46:27.286: E/AndroidRuntime(1359):     at android.view.ViewGroup.drawChild(ViewGroup.java:1531)
12-23 13:46:27.286: E/AndroidRuntime(1359):     at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1258)
12-23 13:46:27.286: E/AndroidRuntime(1359):     at android.view.ViewGroup.drawChild(ViewGroup.java:1529)
12-23 13:46:27.286: E/AndroidRuntime(1359):     at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1258)
12-23 13:46:27.286: E/AndroidRuntime(1359):     at android.view.ViewGroup.drawChild(ViewGroup.java:1529)
12-23 13:46:27.286: E/AndroidRuntime(1359):     at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1258)
12-23 13:46:27.286: E/AndroidRuntime(1359):     at android.view.ViewGroup.drawChild(ViewGroup.java:1529)
12-23 13:46:27.286: E/AndroidRuntime(1359):     at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1258)
12-23 13:46:27.286: E/AndroidRuntime(1359):     at android.view.ViewGroup.drawChild(ViewGroup.java:1529)
12-23 13:46:27.286: E/AndroidRuntime(1359):     at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1258)
12-23 13:46:27.286: E/AndroidRuntime(1359):     at android.view.View.draw(View.java:6538)
12-23 13:46:27.286: E/AndroidRuntime(1359):     at android.widget.FrameLayout.draw(FrameLayout.java:352)][1]
12-23 13:46:27.286: E/AndroidRuntime(1359):     at android.view.ViewGroup.drawChild(ViewGroup.java:1531)
12-23 13:46:27.286: E/AndroidRuntime(1359):     at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1258)
12-23 13:46:27.286: E/AndroidRuntime(1359):     at android.view.ViewGroup.drawChild(ViewGroup.java:1529)
12-23 13:46:27.286: E/AndroidRuntime(1359):     at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1258)
12-23 13:46:27.286: E/AndroidRuntime(1359):     at android.view.View.draw(View.java:6538)
12-23 13:46:27.286: E/AndroidRuntime(1359):     at android.widget.FrameLayout.draw(FrameLayout.java:352)
12-23 13:46:27.286: E/AndroidRuntime(1359):     at com.android.internal.policy.impl.PhoneWindow$DecorView.draw(PhoneWindow.java:1830)
12-23 13:46:27.286: E/AndroidRuntime(1359):     at android.view.ViewRoot.draw(ViewRoot.java:1349)
12-23 13:46:27.286: E/AndroidRuntime(1359):     at android.view.ViewRoot.performTraversals(ViewRoot.java:1114)
12-23 13:46:27.286: E/AndroidRuntime(1359):     at android.view.ViewRoot.handleMessage(ViewRoot.java:1633)
12-23 13:46:27.286: E/AndroidRuntime(1359):     at android.os.Handler.dispatchMessage(Handler.java:99)
12-23 13:46:27.286: E/AndroidRuntime(1359):     at android.os.Looper.loop(Looper.java:123)
12-23 13:46:27.286: E/AndroidRuntime(1359):     at android.app.ActivityThread.main(ActivityThread.java:4363)
12-23 13:46:27.286: E/AndroidRuntime(1359):     at java.lang.reflect.Method.invokeNative(Native Method)
12-23 13:46:27.286: E/AndroidRuntime(1359):     at java.lang.reflect.Method.invoke(Method.java:521)
12-23 13:46:27.286: E/AndroidRuntime(1359):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:860)
12-23 13:46:27.286: E/AndroidRuntime(1359):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:618)
12-23 13:46:27.286: E/AndroidRuntime(1359):     at dalvik.system.NativeStart.main(Native Method)

3 个答案:

答案 0 :(得分:2)

为了防止用户在编辑列表时无意中编辑列表。我决定在加载引脚时将对话框放在onPreExecute()中。这使得用户在添加新引脚时无法触摸地图。直到我能找到时间来提出如何防止这种情况发生的更好的想法,这将是必须的。

我在开始添加新引脚之前清除了地图中的叠加层,这是在onPreExecute()期间完成的。在onPostExecute()我关闭对话框并invalidate()地图。在将它们添加到列表后,这将在地图上绘制新的地图引脚。

@Override
    protected void onPreExecute() {
        Log.i(tag, "AsyncTask Started");
        dialog.show();
        mapOverlays = mapView.getOverlays();
        mapOverlays.clear();
    }

@Override
    protected void onPostExecute(Void args) {
        mapView.invalidate();
        dialog.dismiss();
        Log.i(tag, "AsyncTask Post");
    }

答案 1 :(得分:1)

当您尝试在迭代时修改列表时,通常会发生ConcurrentModificationException。要克服异常,您可以使用名为CopyOnWriteArrayList的特殊列表类型。它可以安全地让您在迭代期间添加和删除列表中的项目。希望这会有所帮助。

答案 2 :(得分:1)

您的应用程序移动缓慢,因为onPostExecute函数已在UI线程上完成。您在此处执行的位图解码会导致UI变慢,因为这是网络密集型的,您正在UI线程上执行此操作。我建议在doInBackground线程上获取所有位图,然后实际将它们添加到onPostExecute方法的地图上。你应该在UI线程上实际做的唯一事情是add方法。