0

我的应用程序在每 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 方法中退出循环。但没有帮助。我知道在异步任务中使用 looper 很奇怪,但是还有其他方法可以在异步任务的 doInBackground 方法中使用位置侦听器。

请给我提示为什么我会收到此错误。

4

1 回答 1

0

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

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

再想一想,你为什么还要使用这个 Looper?它在您的代码中没有做任何事情。如果您认为因此在后台线程中调用了侦听器,那么我有一个坏消息。它不是!侦听器将在它想要调用的任何线程中被调用,通常是 UI 线程。如果要避免 UI 线程中长时间运行的进程(例如网络),则应从该public void onLocationChanged(Location)方法中启动一个新线程(或新的 AsyncTask)。将侦听器代码放入其中protected Location doInBackground(Void... arg0)只会使您的代码阅读起来非常混乱,而在实际执行中没有任何区别。

我希望它有所帮助。

编辑:

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

于 2013-10-14T08:28:22.183 回答