Ошибка AsyncTask и Looper.prepare()
У меня есть следующий код
class OverlayTask extends AsyncTask<Void, Void, Void> {
@Override
public void onPreExecute() {
if (sites != null) {
myMapView.getOverlays().remove(sites);
myMapView.invalidate();
sites = null;
}
}
@Override
public Void doInBackground(Void... unused) {
grabShipsWithLocation();
return (null);
}
@Override
public void onPostExecute(Void unused) {
myMapView.getOverlays().add(sites);
myMapView.invalidate();
isLoading = false;
}
}
Кажется, что это хорошо работает на нескольких тестовых устройствах, но я вижу много ошибок, появляющихся на консоли dev. Кажется, я не могу понять, почему и где поставить этот Looper.prepare(). Это необходимо?
java.lang.ExceptionInInitializerError
at com.test.appname.FinderMain$1.gotLocation(FinderMain.java:286)
at com.test.appname.MyLocation$GetLastLocation.run(MyLocation.java:89)
at java.util.Timer$TimerImpl.run(Timer.java:289)
Caused by: java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
at android.os.Handler.<init>(Handler.java:121)
at android.os.AsyncTask$InternalHandler.<init>(AsyncTask.java:421)
at android.os.AsyncTask$InternalHandler.<init>(AsyncTask.java:421)
at android.os.AsyncTask.<clinit>(AsyncTask.java:152)
Как запрошено MyLocation.java
class GetLastLocation extends TimerTask {
@Override
public void run() {
lm.removeUpdates(locationListenerGps);
lm.removeUpdates(locationListenerNetwork);
Location net_loc=null, gps_loc=null;
if(gps_enabled)
gps_loc=lm.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
if(network_enabled)
net_loc=lm.getLastKnownLocation(LocationManager.GPS_PROVIDER);
//if there are both values use the latest one
if(gps_loc!=null && net_loc!=null){
if(gps_loc.getTime()>net_loc.getTime())
locationResult.gotLocation(gps_loc);
else
locationResult.gotLocation(net_loc);
return;
}
if(gps_loc!=null){
locationResult.gotLocation(gps_loc); //Line 89
return;
}
if(net_loc!=null){
locationResult.gotLocation(net_loc);
return;
}
locationResult.gotLocation(null);
}
}
Ответы
Ответ 1
Длинная история:
AsyncTask
внутренне использует Handler
. Обработчик в основном позволяет размещать Runnables
из другого потока в потоке, которому был назначен обработчик, который в случае AsyncTask
всегда является потоком, из которого он вызывается. Это работает только для потоков, которые имеют Looper
.
Подробнее см. http://developer.android.com/reference/android/os/Handler.html
Рассказ:
Просто завершите каждый вызов FinderMain$1.gotLocation
или создайте AsyncTask
внутри него в Runnable
и разместите его до Handler
, привязанного к потоку пользовательского интерфейса, например:
class GetLastLocation extends TimerTask {
private Handler mHandler = new Handler(Looper.getMainLooper());
@Override
public void run() {
// ...
mHandler.post(new Runnable() {
public void run() {
locationResult.gotLocation(null);
}
});
// ...
}
}
Ответ 2
Я пробовал это... Он работал, надеюсь, что это поможет вам.
protected class Asyctast extends AsyncTask<String, Integer, Integer>
{
@Override
protected Integer doInBackground(String... params) {
// TODO Auto-generated method stub
Log.d("Asynctask", ""+params);
Looper.prepare();
ImageThumbnailsActivity m = new ImageThumbnailsActivity();
Toast.makeText(ImageThumbnailsActivity.this,""+params ,Toast.LENGTH_SHORT).show();
final Dialog dialog_options = new Dialog(ImageThumbnailsActivity.this);
dialog_options.setContentView(R.layout.option);
dialog_options.show();
Looper.loop();
return null;
}
}