1

これが私のサンプルコードです。

public class test extends Activity {
  private TextView tv;

  public class Blap extends AsyncTask<String,String,Boolean>{
    private test parent;
    @Override
    protected Boolean doInBackground(String... options) {
        this.auth(options[0],options[1]);
        parent.aresponse(res);
        return true;
    }
    public Blap(test a){
        this.parent = a;
    }
    public auth(String login, String password){
        //process auth
    }
}

@Override
public void onCreate(Bundle savedInstanceState) {
    //work...
}

public void buttonclick(View v){
    tv = new TextView(this);
    new Blap(this).execute(editText1.getText().toString(),editText2.getText().toString());
    setContentView(tv);
}
public void aresponse(String rs){
    tv.setText(rs);
}
}

しかし、response が呼び出されると、例外が発生しました。ビュー階層を作成した元のスレッドだけがそのビューにアクセスできます。非同期操作の完了を正しく待ち、必要な操作の処理を続行するにはどうすればよいですか?

4

3 に答える 3

1

AsyncTaskUI を更新するための 2 つの可能性を提供します。

で実行されたタスクと並行して UI を更新する場合doInBackground()(たとえば、 a を更新する場合)、メソッド内でProgressBar呼び出す必要があります。次に、メソッドで UI を更新する必要があります。publishProgress()doInBackground()onProgressUpdate()

タスクが完了したときに UI を更新する場合は、onPostExecute()メソッドで行う必要があります。

/** This method runs on another thread than the UI thread */
@Override
protected String doInBackground(String... _params) {
    for (int progressValue = 0; progressValue  < 100; progressValue++) {
        publishProgress(progressValue);
    }
}

/** This method runs on the UI thread */
@Override
protected void onProgressUpdate(Integer... progressValue) {
    // TODO Update your ProgressBar here
}

/**
 * Called after doInBackground() method
 * This method runs on the UI thread
 */
@Override
protected void onPostExecute(Boolean _result) {
   // TODO Update the UI thread with the final result
}

あなたの場合、文字列を返すAsyncTask<String, String, String>必要があるため、を使用する必要があります。doInBackground()次に、結果を次のように処理する必要がありますonPostExecute()

public class test extends Activity {
    private TextView tv;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        //work...
    }

    public void buttonclick(View v){
        tv = new TextView(this);
        new Blap().execute(editText1.getText().toString(), editText2.getText().toString());
        setContentView(tv);
    }

    public class Blap extends AsyncTask<String, String, String> {
        private test parent;

        @Override
        protected String doInBackground(String... options) {
            this.auth(options[0], options[1]);
            String result = "my result";
            return result;
        }

        public auth(String login, String password){
            //process auth
        }

        @Override
        protected void onPostExecute(String _result) {
           tv.setText(_result);
        }
    }
}
于 2012-04-25T18:11:31.827 に答える
1

aresponse以下のようにメソッドを変更するだけです。

public void aresponse(String rs){
    runOnUiThread(new Runnable() {
        @Override
        public void run() {
            tv.setText(rs);             
        }
    });
}

このようにして、いつでもどこからでもこのメソッドを呼び出すと、UI スレッドで TextView が更新されます。

さらに、問題なく実行される AsyncTask の onPostExecute メソッドからこのメソッドを呼び出すことも検討できますが、それはあなたの選択です:)

于 2012-04-25T13:10:49.107 に答える
0

AsyncTaskUI スレッドで自動的に呼び出されるメソッドがいくつかあります。そこからオーバーライドonPostExecute()して呼び出しますaresponse()。詳細はこちら: http://developer.android.com/reference/android/os/AsyncTask.html

于 2012-04-25T13:13:52.493 に答える