2012-04-25 55 views
1

这是我的示例代码。如何从AsyncTask中的回调函数访问父类视图?

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时,我得到一个异常:只有创建视图层次结构的原始线程可以触及其视图。 如何正确等待异步操作完成并继续处理所需的操作?

回答

1

AsyncTask提供两种posibilites更新UI:如果您想更新与doInBackground()执行任务并行的UI(例如更新ProgressBar

,你会必须在doInBackground()方法内调用publishProgress()。然后,您必须更新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 
} 

在你的情况,因为你需要doInBackground()返回一个字符串你应该使用一个AsyncTask<String, String, String>。那么你只需要把结果在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); 
     } 
    } 
} 
1

只需更改如下你的方法aresponse

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

这样,当曾经和你在哪里都调用这个方法,它会更新你的UI线程的TextView。

此外,你也可以考虑来调用的AsyncTask的onPostExecute方法,这种方法将运行没有任何问题,但后来它的您的选择:)

+0

谢谢。但在这个问题上,我更喜欢使用onPostExecute,我知道它在UI线程中运行。 – uzer 2012-04-26 06:04:26

+0

其您的选择。我的目的是告诉你,你不能更新非UI线程的意见,这就是全部:) – waqaslam 2012-04-26 07:14:42

相关问题