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

但是当调用 aresponse 时,我遇到了一个异常:只有创建视图层次结构的原始线程才能触摸它的视图。如何正确等待异步操作完成并继续处理所需的操作?

4

3 回答 3

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 回答
1

AsyncTask为您提供两种更新 UI 的可能性:

如果您想在执行任务的同时更新 UI doInBackground()(例如更新 a ProgressBar),您必须publishProgress()在方法内部调用doInBackground()。然后你必须在onProgressUpdate()方法中更新 UI。

如果要在任务完成时更新 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
}

在您的情况下,您应该使用 anAsyncTask<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 回答
0

AsyncTask有一些在 UI 线程上自动调用的方法。覆盖onPostExecute()aresponse()从那里调用。更多信息在这里:http: //developer.android.com/reference/android/os/AsyncTask.html

于 2012-04-25T13:13:52.493 回答