AsynchTask:每个线程只能创建一个Looper

时间:2013-10-14 08:18:50

标签: 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/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();         

    }           

}  }

我也尝试在onstop方法中退出循环。但没有帮助。我知道在Asynch任务中使用looper很奇怪,但在Asynch Task的doInBackground方法中是否还有其他方法可以使用位置监听器。

请告诉我为什么我收到此错误。

1 个答案:

答案 0 :(得分:0)

它崩溃了,因为AsyncTask的线程被用作ThreadPool(这意味着它使用了相同的4或5个线程并重新使用。说答案的第一部分是:

没有!您不能在AsyncTask中使用Looper,因为Only one Looper may be created per thread

第二个想法,你为什么还要使用这个Looper?它没有在您的代码中执行任何操作。如果你因为它而相信会在后台线程中调用Listener,那我就有坏消息。它不是!将在任何想要调用的线程中调用侦听器,通常是UI-Thread。如果要避免UI线程中长时间运行的进程(例如网络),则应从public void onLocationChanged(Location)方法启动新线程(或新的AsyncTask)。将监听器代码放在protected Location doInBackground(Void... arg0)中只会使您的代码非常混乱而无法在实际执行中进行读取。

我希望它有所帮助。

修改

在Android 4.0(或3.0,不确定)中,它是一个SingleThreadPool,这使得Loopers的这个混乱更加紧张。