2012-10-18 30 views
1

我試圖通過從Activity調用的Asynctask訪問REMOTE android服務。Android AsyncTask使用舊數據回收的線程

我有一個問題,我認爲是線程被重用造成的。我在AsyncTask中使用了一個Lopper,當它得到一個線程時,它已經被一個早期的遠程服務調用分配了,我得到一個關於每個線程只允許有一個循環的錯誤。我不認爲這是因爲我試圖在錯誤的線程上訪問UI。

我可以用一些非常簡單的代碼來模仿這個問題。我在一個活動上創建了一個按鈕,只需按下它6次。希望有人可以告訴我如何解決這個問題。我試過檢查活套不是空的,但是這隻會導致我另一個問題,所以我想嘗試解決這個問題。

這裏是我的活動

public class MainActivity extends Activity { 

@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_main); 
} 



public void buttonClick(View view) 
{ 

    MyAsychTask myAsychTask = new MyAsychTask() ; 

    myAsychTask.execute() ; 

}} 

的的AsyncTask

public class MyAsychTask extends AsyncTask<Void, Void, Void>{ 
    @Override 
    protected Void doInBackground(Void... params) { 
     Log.wtf("Thead details", Thread.currentThread().getName() + " : " + Thread.currentThread().getState().toString() + " : Looper def: " + ((Looper.myLooper()==null) ? "none" : "looper")) ; 

     Looper.prepare(); 

     Handler myHandler = new Handler() { 
       public void handleMessage(Message msg) { 
        // in real app process incoming messages here then quit looper 
        Log.wtf("executing message", " ") ; 
       this.getLooper().quit() ; 
       } 
      }; 

     new simulateREMOTEservice(myHandler) ; 

     Looper.loop() ; 

     Log.wtf("exited looper", " ") ; 

     return null ; 
}} 

class simulateREMOTEservice{ 
public simulateREMOTEservice(Handler myHandler) 
{ 
    Log.wtf("simulating REMOTE service", " ") ; 
    myHandler.sendEmptyMessage(0) ; 

}} 

日誌文件是

10-18 19:00:12.420: A/Thead details(3081): AsyncTask #1 : RUNNABLE : Looper def: none 
10-18 19:00:12.420: A/simulating REMOTE service(3081): 
10-18 19:00:12.420: A/executing message(3081): 
10-18 19:00:12.420: A/exited looper(3081): 
10-18 19:00:14.280: A/Thead details(3081): AsyncTask #2 : RUNNABLE : Looper def: none 
10-18 19:00:14.290: A/simulating REMOTE service(3081): 
10-18 19:00:14.290: A/executing message(3081): 
10-18 19:00:14.300: A/exited looper(3081): 
10-18 19:00:16.140: A/Thead details(3081): AsyncTask #3 : RUNNABLE : Looper def: none 
10-18 19:00:16.150: A/simulating REMOTE service(3081): 
10-18 19:00:16.150: A/executing message(3081): 
10-18 19:00:16.150: A/exited looper(3081): 
10-18 19:00:17.830: A/Thead details(3081): AsyncTask #4 : RUNNABLE : Looper def: none 
10-18 19:00:17.840: A/simulating REMOTE service(3081): 
10-18 19:00:17.840: A/executing message(3081): 
10-18 19:00:17.840: A/exited looper(3081): 
10-18 19:00:19.480: A/Thead details(3081): AsyncTask #5 : RUNNABLE : Looper def: none 
10-18 19:00:19.480: A/simulating REMOTE service(3081): 
10-18 19:00:19.490: A/executing message(3081): 
10-18 19:00:19.490: A/exited looper(3081): 
10-18 19:00:21.810: A/Thead details(3081): AsyncTask #1 : RUNNABLE : Looper def: looper 
10-18 19:00:21.820: E/AndroidRuntime(3081): FATAL EXCEPTION: AsyncTask #1 
10-18 19:00:21.820: E/AndroidRuntime(3081): java.lang.RuntimeException: An error occured while executing doInBackground() 
10-18 19:00:21.820: E/AndroidRuntime(3081):  at android.os.AsyncTask$3.done(AsyncTask.java:266) 
10-18 19:00:21.820: E/AndroidRuntime(3081):  at java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:273) 
10-18 19:00:21.820: E/AndroidRuntime(3081):  at java.util.concurrent.FutureTask.setException(FutureTask.java:124) 
10-18 19:00:21.820: E/AndroidRuntime(3081):  at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:307) 
10-18 19:00:21.820: E/AndroidRuntime(3081):  at java.util.concurrent.FutureTask.run(FutureTask.java:137) 
10-18 19:00:21.820: E/AndroidRuntime(3081):  at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1081) 
10-18 19:00:21.820: E/AndroidRuntime(3081):  at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:574) 
10-18 19:00:21.820: E/AndroidRuntime(3081):  at java.lang.Thread.run(Thread.java:1020) 
10-18 19:00:21.820: E/AndroidRuntime(3081): Caused by: java.lang.RuntimeException: Only one Looper may be created per thread 
10-18 19:00:21.820: E/AndroidRuntime(3081):  at android.os.Looper.prepare(Looper.java:76) 
10-18 19:00:21.820: E/AndroidRuntime(3081):  at com.example.testlooper.MyAsychTask.doInBackground(MyAsychTask.java:15) 
10-18 19:00:21.820: E/AndroidRuntime(3081):  at com.example.testlooper.MyAsychTask.doInBackground(MyAsychTask.java:1) 
10-18 19:00:21.820: E/AndroidRuntime(3081):  at android.os.AsyncTask$2.call(AsyncTask.java:252) 
10-18 19:00:21.820: E/AndroidRuntime(3081):  at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305) 
10-18 19:00:21.820: E/AndroidRuntime(3081):  ... 4 more 
+0

顯然我無法自己關閉它,但看起來我在遇到與以下鏈接中的註釋16相同的問題http://code.google.com/p/android/issues/detail?id= 20915 基本上他們說你不應該在AsynchTask中使用Handler,所以看起來我必須找到不同的機制來從我的遠程服務中返回數據。 – user1757196

回答

0

按我的意見看看網址code.google.com/ p/android/issues/detail?id = 20915,儘管我懷疑真正的問題不在於AsyncTask線程池,但事實是,一旦你創建了一個Looper,您似乎無法將其移除或替換爲新的Looper。