问题描述
我有以下代码
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().需要吗?
That seems to work fine on a few test devices but I am seeing a lot of errors appearing on the dev console. I can't seem to work out why and where to put this Looper.prepare(). Is it needed?
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
As requested 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
的线程.
AsyncTask
internally uses a Handler
. A handler basically allows you to post Runnables
from another thread on the thread the handler was assigned to, which in the case of AsyncTask
is always the thread from which it is called. This only works for threads that have a Looper
prepared, though.
更多信息参见http://developer.android.com/reference/android/os/Handler.html
小故事:
只需将每个对 FinderMain$1.gotLocation
的调用或在其中创建的 AsyncTask
包装在 Runnable
中,然后将其发布到 FinderMain$1.gotLocation
code>Handler绑定到UI线程,像这样:
Simply wrap every call to FinderMain$1.gotLocation
or the creation of AsyncTask
within it in a Runnable
, and post it to a Handler
bound to the UI thread, like this:
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);
}
});
// ...
}
}
这篇关于AsyncTask 和 Looper.prepare() 错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!