异步任务 - 执行后,如何更新视图?

11
在Activity的onCreate()事件中,我启动了一个AsyncTask来从数据库检索产品数据。当成功完成后,如何更新显示?
元代码:
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.venueviewbasic);
            (..)
    new GetProductDetails().execute();

class GetProductDetails extends AsyncTask<String, String, String> {

    protected String doInBackground(String... params) {

        // updating UI from Background Thread
        runOnUiThread(new Runnable() {
            public void run() {
                // Check for success tag
                int success;
                try {
                    // Building Parameters
                    List<NameValuePair> params = new ArrayList<NameValuePair>();
                    params.add(new BasicNameValuePair("id", vid));
        (.. retrieve and parse data and set new textview contents ..)

但是TextView等控件没有得到更新。

3个回答

18

如果您想要在异步完成后从 "then" 中更新视图,您可以使用

protected void onPostExecute(String result)
    {
        textView.setText(result);
    }

但如果您想在后台进程运行时更新数据,请使用以下方法。例如...

protected Long doInBackground(URL... urls) {
         int count = urls.length;
         long totalSize = 0;
         for (int i = 0; i < count; i++) {
             totalSize += Downloader.downloadFile(urls[i]);
             publishProgress((int) ((i / (float) count) * 100));<------
         }
         return totalSize;
     }

     protected void onProgressUpdate(Integer... progress) {  <-------
         setProgressPercent(progress[0]);
     }

更详细的信息请参见此链接

希望这能帮助你...!


太好了,我会考虑更新我的另一个相当长的列表视图,但现在第一部分已经解决了问题。谢谢! :) - richey
1
如果我尝试使用myTextView.setText(result);,则会出现“无法解析myTextView”的错误。如果我尝试加载UI,则会出现“找不到类型MyClass的findViewById(int)方法”的错误。 - Francisco Corrales Morales
我有一个RecyclerView适配器,其中存储了商店的点赞数。当用户点击任何商店时,调用异步任务进行网络服务,并获取更新后的点赞数并在视图上更新,请帮助我。 - Harsha

11

我猜测问题更多地是关于如何在异步任务在单独的文件中时获取UI视图。

在这种情况下,您需要将上下文传递给Async任务,并使用它来获取视图。

class MyAsyncTask extends AsyncTask<URL, Integer, Long> {

    Activity mActivity;

    public MyAsyncTask(Activity activity) {
       mActivity = ativity;
    }

然后在您的onPostExecute中使用

int id = mActivity.findViewById(...);

请记住,在“doInBackground”方法中,您无法更新视图,因为它不是UI线程。


5
在您的AsyncTask类中,添加一个onPostExecute方法。该方法在UI线程上执行,并且可以更新任何UI组件。
class GetProductDetails extends AsyncTask<...> 
{
    ...
    private TextView textView;
    ...
    protected void onPostExecute(String result)
    {
        textView.setText(result);
    }
}
result参数是您的类中doInBackground方法返回的值。)

没错,就是这个方法,谢谢!我必须在onPostExecute()方法中更新显示,而不是直接在线程中更新。 - richey
如果我尝试使用 myTextView.setText(result);,则会出现“无法解析myTextView”的错误。并且,如果我尝试加载界面,则会出现“findViewById(int)方法在MyClass类型中未定义”的错误。 - Francisco Corrales Morales
你搞清楚了吗,@FranciscoCorralesMorales?我也遇到了同样的问题。 - Yasha
@Yasha 请看下面Abhik的回答。在您的异步任务构造函数中,传入您想要的Activity实例(例如MainActivity mainActivity)。 - Kevin Lee

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接