我有以下代码
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;
}
}
这似乎在一些测试设备上运行良好,但我看到开发控制台上出现了很多错误。我似乎无法弄清楚为什么以及在哪里放置这个 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);
}
}
最佳答案
长篇大论:
AsyncTask
在内部使用 Handler
。处理程序基本上允许您在分配处理程序的线程上从另一个线程发布 Runnables
,在 AsyncTask
的情况下,它始终是调用它的线程。不过,这只适用于准备了 Looper
的线程。
有关详细信息,请参阅 http://developer.android.com/reference/android/os/Handler.html
短篇小说:
只需将每个对 FinderMain$1.gotLocation
的调用或在其中创建的 AsyncTask
包装在 Runnable
中,然后将其发布到 Handler
绑定(bind)到UI线程,像这样:
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);
}
});
// ...
}
}
关于android - AsyncTask 和 Looper.prepare() 错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4187960/