Question

In my application I use JSON webservice to get data from Google Navigation api. I use the code is below. I got the following exception

android.os.NetworkOnMainThreadException.

How to use AsyncTask? here is my code. Thanks.`public class MainActivity extends MapActivity {

  MapView mapView ;

public void onCreate(Bundle savedInstanceState) {

    super.onCreate(savedInstanceState);

    System.out.println("*************1**************1");
    setContentView(R.layout.activity_main);
    System.out.println("*************2**************");
    mapView = (MapView) findViewById(R.id.mapv); 
    System.out.println("*************3**************");



                Route route = directions(new GeoPoint((int)(26.2*1E6),(int)(50.6*1E6)), new GeoPoint((int)(26.3*1E6),(int)(50.7*1E6)));

              RouteOverlay routeOverlay = new RouteOverlay(route, Color.BLUE);
              mapView.getOverlays().add(routeOverlay);
            mapView.invalidate();


    System.out.println("*************4**************");

}



@SuppressLint("ParserError")
private Route directions(final GeoPoint start, final GeoPoint dest) {



    //https://developers.google.com/maps/documentation/directions/#JSON <- get api
    String jsonURL = "http://maps.googleapis.com/maps/api/directions/json?";
    final StringBuffer sBuf = new StringBuffer(jsonURL);
    sBuf.append("origin=");
    sBuf.append(start.getLatitudeE6()/1E6);
    sBuf.append(',');
    sBuf.append(start.getLongitudeE6()/1E6);
    sBuf.append("&destination=");
    sBuf.append(dest.getLatitudeE6()/1E6);
    sBuf.append(',');
    sBuf.append(dest.getLongitudeE6()/1E6);
    sBuf.append("&sensor=true&mode=driving");

    Parser parser = new GoogleParser(sBuf.toString());
      Route   r =  parser.parse();
   System.out.println("********r in thread*****" +r);                  
            return r;
}



@Override
public boolean onCreateOptionsMenu(Menu menu) {
    getMenuInflater().inflate(R.menu.activity_main, menu);
    return true;
}
@Override
protected boolean isRouteDisplayed() {
    // TODO Auto-generated method stub
    return false;
}

} `

Was it helpful?

Solution

@imran khan idea of using another thread is the right one. From HoneyComb and above, you can't do any networking operation inside the UI Thread. The UI Thread is the thread responsible for displaying views and receiving touch events and it must be free for this, not blocked by a long running operation. (Otherwise you got an ANR on Android).

But it's actually not a very good idea to use an AsyncTask for long running operations like a network Request. The AsyncTask javadocs even states they have been designed for short runnning operations...

The best approach is to use a service for that. I encourage you to read this infographics from the RoboSpice library and use RoboSpice, it will ease creating a service with networking and will make it easier for your to parse your json content using Spring Android.

enter image description here

OTHER TIPS

You can put your code for getting the data using webservice in the doInBackground() method of AsyncTask class and return that result from that function. It will get in the onPostExecute() method and there you can parse and update your UI.

private class myasyncclass extends AsyncTask<String, Void, Route>{
    @Override
    protected Route doInBackground(String... params) {
        //Enter code for fetching data from remote server using webservice
        return yourRoutevalue;
    }
    @Override
    protected void onPostExecute(Route result) {   
        //Enter code for parsing and using the data(Update UI)
    }
}

You should have same type in AsyncTask(DoInBackground, Progress, OnPostExecute)

Change your Code as using AsyncTask:

public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
//Your Code here
new LongOperation().execute("");

System.out.println("*************4**************");

}

private class LongOperation extends AsyncTask<String, Void, String> {

      @Override
      protected Route  doInBackground(String... params) {
         Route route;
        try {
            route = directions(new GeoPoint((int)(26.2*1E6),
               (int)(50.6*1E6)), new GeoPoint((int)(26.3*1E6),(int)(50.7*1E6)));

        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
            return Route ;
      }      

      @Override
      protected void onPostExecute(Route  route) {    
        // Update Ui here    
           RouteOverlay routeOverlay = new RouteOverlay(route, Color.BLUE);
           mapView.getOverlays().add(routeOverlay);
           mapView.invalidate();       
      }

}

NOTE : if you are passing any value from UI elements to HTTP REQUEST then you must pass it as parameters to AsyncTask's doInBackground method. you can see how we pass parameter to AsyncTask here:

http://developer.android.com/reference/android/os/AsyncTask.html

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top