Android AsynchTask:每个线程只能创建一个循环器
我的应用程序每4-5次呼叫就会崩溃。它显示了以下异常Android AsynchTask:每个线程只能创建一个循环器,android,android-asynctask,looper,Android,Android Asynctask,Looper,我的应用程序每4-5次呼叫就会崩溃。它显示了以下异常 10-14 14:00:30.651: E/AndroidRuntime(25035): FATAL EXCEPTION: AsyncTask #1 10-14 14:00:30.651: E/AndroidRuntime(25035): java.lang.RuntimeException: An error occured while executing doInBackground() 10-14 14:00:30.651: E/And
10-14 14:00:30.651: E/AndroidRuntime(25035): FATAL EXCEPTION: AsyncTask #1
10-14 14:00:30.651: E/AndroidRuntime(25035): java.lang.RuntimeException: An error occured while executing doInBackground()
10-14 14:00:30.651: E/AndroidRuntime(25035): at android.os.AsyncTask$3.done(AsyncTask.java:299)
10-14 14:00:30.651: E/AndroidRuntime(25035): at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:352)
10-14 14:00:30.651: E/AndroidRuntime(25035): at java.util.concurrent.FutureTask.setException(FutureTask.java:219)
10-14 14:00:30.651: E/AndroidRuntime(25035): at java.util.concurrent.FutureTask.run(FutureTask.java:239)
10-14 14:00:30.651: E/AndroidRuntime(25035): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1080)
10-14 14:00:30.651: E/AndroidRuntime(25035): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:573)
10-14 14:00:30.651: E/AndroidRuntime(25035): at java.lang.Thread.run(Thread.java:838)
10-14 14:00:30.651: E/AndroidRuntime(25035): Caused by: java.lang.RuntimeException: Only one Looper may be created per thread
10-14 14:00:30.651: E/AndroidRuntime(25035): at android.os.Looper.prepare(Looper.java:80)
10-14 14:00:30.651: E/AndroidRuntime(25035): at android.os.Looper.prepare(Looper.java:75)
10-14 14:00:30.651: E/AndroidRuntime(25035): at com..SplashActivity$LocationUpdator.doInBackground(SplashActivity.java:118)
10-14 14:00:30.651: E/AndroidRuntime(25035): at com..SplashActivity$LocationUpdator.doInBackground(SplashActivity.java:1)
10-14 14:00:30.651: E/AndroidRuntime(25035): at android.os.AsyncTask$2.call(AsyncTask.java:287)
10-14 14:00:30.651: E/AndroidRuntime(25035): at java.util.concurrent.FutureTask.run(FutureTask.java:234)
这是我的密码
public class LocationUpdator extends AsyncTask<Void, Void, Location> {
Location location123 = null;
@Override
protected Location doInBackground(Void... arg0) {
Looper.prepare();
mThreadLooper = Looper.myLooper();
locationListener = new LocationListener()
{
private String subLocality;
@Override
public void onLocationChanged(Location location1) {
if(mThreadLooper != null)
mThreadLooper.quit();
//Stopping Request for Location
if(manager!=null)
manager.removeUpdates(locationListener);
}
String status="success";
if (!manager.isProviderEnabled(LocationManager.GPS_PROVIDER)) {
// if GPS provider is not enable then popup alertbox
buildAlertMessageNoGps();
} else {
// if gps is one then start searching
status = "networkandgps";
manager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 10000,1000, locationListener);
}
}
manager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
Log.i("TEST","Starting Network Provider");
manager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 5000, 10,locationListener);
if (!manager.isProviderEnabled(LocationManager.GPS_PROVIDER)) {
//buildAlertMessageNoGps();
;
} else {
manager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 100000,100000,locationListener);
}
} else {
manager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 5000, 10,locationListener);
}
Looper.loop();
return location123;
}
@Override
protected void onPostExecute(Location result) {
//progressDialog.dismiss();
if(result!=null)
{
Log.i("TESTING SPLASH","Lat3 "+userLocationLat);
Log.i("TESTING SPLASH ","Long3 "+userLocationlong);
startApplication();
}
公共类LocationUpdater扩展异步任务{
位置123=空;
@凌驾
受保护的位置doInBackground(无效…arg0){
Looper.prepare();
mThreadLooper=Looper.myLooper();
locationListener=新locationListener()
{
私有字符串次局部性;
@凌驾
位置已更改(位置1){
if(mThreadLooper!=null)
mThreadLooper.quit();
//停止位置请求
if(manager!=null)
manager.RemoveUpdate(locationListener);
}
字符串status=“success”;
如果(!manager.isProviderEnabled(LocationManager.GPS\U提供程序)){
//如果GPS提供程序未启用,则弹出警报框
buildAlertMessageNoGps();
}否则{
//如果gps为1,则开始搜索
status=“networkandgps”;
manager.RequestLocationUpdate(LocationManager.GPS_提供程序,100001000,locationListener);
}
}
manager=(LocationManager)getSystemService(Context.LOCATION\u服务);
Log.i(“测试”,“启动网络提供商”);
manager.RequestLocationUpdate(LocationManager.NETWORK_提供程序,5000,10,locationListener);
如果(!manager.isProviderEnabled(LocationManager.GPS\U提供程序)){
//buildAlertMessageNoGps();
;
}否则{
manager.RequestLocationUpdate(LocationManager.GPS_提供程序,100001000000,locationListener);
}
}否则{
manager.RequestLocationUpdate(LocationManager.NETWORK_提供程序,5000,10,locationListener);
}
loop.loop();
返回位置123;
}
@凌驾
受保护的void onPostExecute(位置结果){
//progressDialog.disclose();
如果(结果!=null)
{
Log.i(“测试飞溅”,“Lat3”+用户位置LAT);
Log.i(“测试飞溅”、“长3”+用户位置长);
startApplication();
}
}
}
我还尝试退出onstop方法中的循环。但是没有帮助。我知道在异步任务中使用looper很奇怪,但在异步任务的doInBackground方法中是否有其他方法可以使用位置侦听器
请给我一个提示,为什么我会出现这个错误 它崩溃是因为AsyncTask的线程被用作线程池(这意味着使用和重复使用了相同的4或5个线程。回答的第一部分是: 不!不能在异步任务中使用循环器,因为每个线程只能创建一个循环器 仔细想想,你为什么要使用这个循环器?它在你的代码中没有做任何事情。如果你认为因为它,监听器在后台线程中被调用,我有一个坏消息。不是!监听器将在它想要调用的任何线程中被调用,通常是UI线程。如果你想避免长时间运行UI线程中的进程(如网络),您应该从
public void onLocationChanged(Location)
方法启动新线程(或新异步任务)。将侦听器代码放入受保护的位置doInBackground(void…arg0)
只会让您的代码读起来非常混乱,实际执行过程中没有任何差异
我希望有帮助
编辑:
在安卓4.0(或3.0,不确定)中上面是一个SingleThreadPool,这使得循环器的设计更为紧凑。从逻辑上讲,你不应该在
异步任务
的后台使用循环器
。如果你这样做了,那么你真的需要重新考虑异步任务
的设计。否则,它就扼杀了使用这个复杂任务的目的班级。