OSMBonuspack RoadManager NetworkOnMainThreadException

时间:2016-07-23 08:11:07

标签: java android android-asynctask osmdroid

我正在关注OSMBonuspack的教程:https://github.com/MKergall/osmbonuspack/wiki/Tutorial_1

当我运行应用程序时,我在MainActivity.java中获得第47行的NetworkOnMainThreadException,

Road road = roadManager.getRoad(waypoints);

如何为这个确切的块编写asyncTask?

MainActivity.java:

package com.osmbonuspack_tutorial;

import android.app.Activity;
import android.os.Bundle;

import org.osmdroid.api.IMapController;
import org.osmdroid.bonuspack.routing.OSRMRoadManager;
import org.osmdroid.bonuspack.routing.Road;
import org.osmdroid.bonuspack.routing.RoadManager;
import org.osmdroid.tileprovider.tilesource.TileSourceFactory;
import org.osmdroid.util.GeoPoint;
import org.osmdroid.views.MapView;
import org.osmdroid.views.overlay.Marker;
import org.osmdroid.views.overlay.Polyline;

import java.util.ArrayList;

public class MainActivity extends Activity {

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    MapView map = (MapView) findViewById(R.id.map);
    map.setTileSource(TileSourceFactory.MAPNIK);
    map.setBuiltInZoomControls(true);
    map.setMultiTouchControls(true);

    GeoPoint startPoint = new GeoPoint(48.13, -1.63);
    IMapController mapController = map.getController();
    mapController.setZoom(9);
    mapController.setCenter(startPoint);

    Marker startMarker = new Marker(map);
    startMarker.setPosition(startPoint);
    startMarker.setAnchor(Marker.ANCHOR_CENTER, Marker.ANCHOR_BOTTOM);
    map.getOverlays().add(startMarker);

    RoadManager roadManager = new OSRMRoadManager(this);

    ArrayList<GeoPoint> waypoints = new ArrayList<GeoPoint>();
    waypoints.add(startPoint);
    GeoPoint endPoint = new GeoPoint(48.4, -1.9);
    waypoints.add(endPoint);

    Road road = roadManager.getRoad(waypoints);

    Polyline roadOverlay = RoadManager.buildRoadOverlay(road, this);

    map.getOverlays().add(roadOverlay);
    }
}

2 个答案:

答案 0 :(得分:2)

Hello快速搜索教程后,我想出了以下解决方案。

在Mkergell教程中,他明确表示你必须在后台进行操作。你可以在OSMNavigator中参考。

经过几个小时的代码后,我想出了这个解决方案,希望这对你有帮助。

ArrayList<OverlayItem> overlayItemArray; 
overlayItemArray = new ArrayList<>(); 
GeoPoint startPoint = new GeoPoint(27.6803, 85.3303);
GeoPoint destinationPoint = new GeoPoint(27.6303, 85.3203); 

现在在overlayitem数组中添加geopoint

  overlayItemArray.add(new OverlayItem("Starting Point", "This is the starting point", startPoint)); 
  overlayItemArray.add(new OverlayItem("Destination", "This is the detination point", destinationPoint));
  getRoadAsync();

接下来让make方法从方法中调用异步。

public void getRoadAsync() {
        mRoads = null;
        GeoPoint roadStartPoint = null;
        if (startPoint != null) {
            roadStartPoint = startPoint;
        } else if (myLocationOverlay.isEnabled() && myLocationOverlay.getLocation() != null) {
            //use my current location as itinerary start point:
            roadStartPoint = myLocationOverlay.getLocation();
        }

        ArrayList<GeoPoint> waypoints = new ArrayList<GeoPoint>(2);
        waypoints.add(roadStartPoint);
        //add intermediate via points:
//        for (GeoPoint p:viaPoints){
//            waypoints.add(p);
//        }
        waypoints.add(destinationPoint);
        new UpdateRoadTask().execute(waypoints);
    }

下一步,让我们制作道路管理员异步类

 private class UpdateRoadTask extends AsyncTask<Object, Void, Road[]> {

        protected Road[] doInBackground(Object... params) {
            @SuppressWarnings("unchecked")
            ArrayList<GeoPoint> waypoints = (ArrayList<GeoPoint>) params[0];
            RoadManager roadManager = new OSRMRoadManager(getActivity());
            return roadManager.getRoads(waypoints);
        }

        @Override
        protected void onPostExecute(Road[] roads) {
            mRoads = roads;
            if (roads == null)
                return;
            if (roads[0].mStatus == Road.STATUS_TECHNICAL_ISSUE)
                Toast.makeText(map.getContext(), "Technical issue when getting the route", Toast.LENGTH_SHORT).show();
            else if (roads[0].mStatus > Road.STATUS_TECHNICAL_ISSUE) //functional issues
                Toast.makeText(map.getContext(), "No possible route here", Toast.LENGTH_SHORT).show();
              protected Polyline[] mRoadOverlays = new Polyline[roads.length];
            List<Overlay> mapOverlays = map.getOverlays();
            for (int i = 0; i < roads.length; i++) {
                Polyline roadPolyline = RoadManager.buildRoadOverlay(roads[i], getActivity());
                mRoadOverlays[i] = roadPolyline;
                String routeDesc = roads[i].getLengthDurationText(getActivity(), -1);
                roadPolyline.setTitle(getString(R.string.app_name) + " - " + routeDesc);
                roadPolyline.setInfoWindow(new BasicInfoWindow(org.osmdroid.bonuspack.R.layout.bonuspack_bubble, map));
                roadPolyline.setRelatedObject(i);
//                roadPolyline.setOnClickListener(new RoadOnClickListener());
                mapOverlays.add(1, roadPolyline);
                //selectRoad(0);
//                map.invalidate();
                //we insert the road overlays at the "bottom", just above the MapEventsOverlay,
                //to avoid covering the other overlays.
            }
        }
    }

多数,请更多请参考OSMNavigator并参考教程。

答案 1 :(得分:1)

您应该避免在UI线程上执行长时间运行的操作。这包括文件和网络访问。

StrictMode 允许在您的应用中设置策略,以避免做错误的事情。例如,如果应用程序违反了某些Android策略,则以下设置会使您的应用程序崩溃。 StrictMode只能在开发期间使用,而不能在实时应用程序中使用。

StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
    StrictMode.setThreadPolicy(policy);

将它放在OnCreate方法中。