Как использовать метод в AsyncTask в Android?

В моем приложении я использую JSON веб-сервис для получения данных Google Navigation api, Я использую код ниже. Я получил следующее исключение

android.os.NetworkOnMainThreadException,

Как использовать AsyncTask? вот мой код Спасибо. Открытый класс MainActivity расширяет 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;
}

} `

3 ответа

Решение

@imran khan Идея использования другого потока правильна. Начиная с HoneyComb и выше, вы не можете выполнять сетевые операции внутри потока пользовательского интерфейса. Поток пользовательского интерфейса является потоком, отвечающим за отображение представлений и получение сенсорных событий, и он должен быть свободен для этого, не блокироваться длительной операцией. (В противном случае вы получите ANR на Android).

Но на самом деле не очень хорошая идея использовать AsyncTask для длительных операций, таких как сетевой запрос. AsavcTask Javadocs даже заявляет, что они были разработаны для коротких операций...

Лучший подход - использовать для этого сервис. Я призываю вас прочитать эту инфографику из библиотеки RoboSpice и использовать RoboSpice, это упростит создание службы с сетевым подключением и упростит для вас анализ содержимого json с помощью Spring Android.

Вы можете поместить свой код для получения данных с помощью webservice в метод doInBackground() класса AsyncTask и вернуть этот результат из этой функции. Он попадет в метод onPostExecute() и там вы сможете анализировать и обновлять свой пользовательский интерфейс.

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)
    }
}

У вас должен быть такой же тип в AsyncTask(DoInBackground, Progress, OnPostExecute)

Измените ваш код, используя 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();       
      }

}

ПРИМЕЧАНИЕ: если вы передаете какое-либо значение из элементов пользовательского интерфейса в HTTP REQUEST, вы должны передать его в качестве параметров методу AsyncTask doInBackground. Вы можете увидеть, как мы передаем параметр в AsyncTask здесь:

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

Другие вопросы по тегам