2013-10-14 4 views
0

4-5 번째 호출마다 내 응용 프로그램이 충돌합니다. 그것은 예외적으로 나를 보여주고있다.AsynchTask : 스레드 당 하나의 루퍼 만 만들 수 있습니다.

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();   

    }   

} }

또한 이동 중지 방법에 루프를 종료하려고합니다. 그러나 도움이되지는 않습니다. 나는 Asynch 작업에서 looper를 사용하는 것이 이상하다는 것을 알고 있지만 Asynch Task의 doInBackground 메서드 내에서 위치 수신기를 사용하는 다른 방법이 있습니다.

이 오류가 발생하는 이유를 알려주십시오.

+0

논리적으로 당신은 당신의 AsyncTask의 ** doInBackground ** 안에'Loopers'를 사용하지 않아야합니다. 그리고 그렇게한다면, AsyncTask의 디자인을 다시 생각할 필요가 있습니다. 그렇지 않으면이 정교한 클래스 사용의 목적을 없애 버립니다. – waqaslam

답변

0

는 AsyncTask를의 스레드가 스레드 풀 (즉,이 같은 4 또는 5 스레드를 사용하고 재사용 대답의 첫 번째 부분은, 상기의 수단으로 사용되기 때문에 충돌은 다음과 같습니다.!

아니 당신은 할 수 없습니다 AsyncTask 내에서 루퍼를 사용하십시오. Only one Looper may be created per thread

두 번째 생각에 왜이 루퍼를 사용하고 있습니까? 코드에서 아무 것도하지 않습니다.이 때문에 리스너가 백그라운드 스레드에서 호출되고 있습니다. , 나쁜 소식이 있습니다! 리스너는 호출하고자하는 스레드 (일반적으로 UI 스레드)에서 호출 될 것입니다. t에서 긴 실행 프로세스 (예 : 네트워크)를 피하려면 그는 UI 스레드, public void onLocationChanged(Location) 메서드에서 새 스레드 (또는 새 AsyncTask) 시작해야합니다. 청취자 코드를 protected Location doInBackground(Void... arg0) 안에 넣으면 실제 실행에 차이가 없으므로 코드를 읽는 것이 매우 혼란 스럽습니다.

도움이되기를 바랍니다.

편집 : 안드로이드 4.0 (또는 확인 3.0,하지) 최대가 좀 더 꽉 루퍼로이 난장판을 만드는 SingleThreadPool가,의에

.