1

アクティビティから呼び出されたAsynctaskを介してREMOTEandroidサービスにアクセスしようとしています。

スレッドが再利用されていることが原因だと思う問題が発生しています。AsyncTaskでLopperを使用していますが、リモートサービスへの以前の呼び出しによって既に割り当てられているスレッドを取得すると、スレッドごとに許可されるルーパーが1つだけであるというエラーが発生します。間違ったスレッドでUIにアクセスしようとしているので、これはないと思います。

非常に単純なコードで問題を模倣できます。アクティビティにボタンを作成し、それを6回押すだけです。うまくいけば、誰かがこれを回避する方法を私にアドバイスすることができます。ルーパーがnullでないことを確認しようとしましたが、それは別の問題につながるだけなので、これを解決してみたいと思います。

これが私の活動です

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
4

1 に答える 1

0

私のコメントによると、URL code.google.com/p/android/issues/detail?id=20915 を見てください。本当の問題は AsyncTask スレッドプールではなく、一度作成したルーパーを削除したり、新しいものと交換したりできないようです。

于 2012-10-20T07:36:02.443 に答える