Как использовать метод в 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