【问题标题】:How to update ui from asynctask如何从异步任务更新 ui
【发布时间】:2014-06-01 09:23:37
【问题描述】:

我已经看过很多如何做到这一点的例子,但我不知道如何在我的代码中实现它。

我正在使用这个code
我已经更新了 url,所以它会收到一个带有动态数据的 json。 我正在尝试使用此代码每 30 秒自动更新一次列表。

Handler handler = new Handler();
    Runnable refresh = new Runnable() {
        public void run() {
            new GetContacts().execute();
            handler.postDelayed(refresh, 30000); 
        }
    };

刷新,调用url获取数据,但UI没有更新。

感谢您为我指明正确方向的任何提示。

http://www.androidhive.info/2012/01/android-json-parsing-tutorial/

【问题讨论】:

  • GetContacts 的 postExecute() 正在更新 UI,如果是这样,它已经在 UI 线程上运行并且应该可以工作。尝试提供更多代码
  • 我的意思是问,第一句话是一个问题.. ',' -> '?'
  • 听起来您正在尝试更新 ListView。如果这是正确的,您应该更新您的数据结构并使用如下方法将其传递给您的适配器:public synchronized void refreshAdapter(List<SomeClass> itemList) { this.itemList = itemList; notifyDataSetChanged(); }
  • 你每 30 秒更新一次 url 还是每次都点击相同的 url?

标签: android android-asynctask android-handler android-json


【解决方案1】:

AsyncTask 中有三个受保护的方法可以与 UI 交互。

  • onPreExecute()
    • 运行之前 doInBackground()
  • onPostExecute()
    • doInBackground() 完成后运行
  • onProgressUpdate()
    • 这仅在doInBackground() 使用publishProgress() 调用它时运行

如果在您的情况下,任务运行的时间比您想要刷新的 30 秒长得多,您可能需要使用 onProgressUpdate()publishProgress()。否则onPostExecute() 应该可以解决问题。

请参阅official documentation 了解如何实现它。

【讨论】:

    【解决方案2】:

    您可以使用AsycTask 并在onPostExecute 内完成的任务上更新list ui

        new AsyncTask<String, String, String>() {
            /**
             * Before starting background do some work.
             * */
            @Override
            protected void onPreExecute() {
            }
    
            @Override
            protected String doInBackground(String... params) {
                // TODO fetch url data do bg process.
                return null;
            }
    
            /**
             * Update list ui after process finished.
             */
            protected void onPostExecute(String result) {
                   // NO NEED to use activity.runOnUiThread(), code execute here under UI thread. 
    
                     // Updating parsed JSON data into ListView
                     final List data = new Gson().fromJson(result);
                    // updating listview
                    ((ListActivity) activity).updateUI(data);
            }
    
        };
    }
    

    更新 无需在onPostExecute 中使用runOnUiThread,因为它已经被调用并且它的主体在UIThread 下执行。

    【讨论】:

    • 您不需要在onPostExecute() 中使用runOnUiThread()。已经可以了。
    【解决方案3】:

    第一件事是使用 postdelayed() 不会重复运行您的代码如果您想以重复模式运行代码,请使用此代码。这将在每 5 秒后运行一次

      ScheduledExecutorService scheduleTaskExecutor = Executors.newScheduledThreadPool(5);
    
        /*This schedules a runnable task every second*/
        scheduleTaskExecutor.scheduleAtFixedRate(new Runnable() {
          public void run() 
          {
            runOnUiThread(new Runnable(){
    
                @Override
                public void run() {
                    // TODO Auto-generated method stub
                    new GetContacts().execute();
                }
    
            });
          }
        }, 0, 5, TimeUnit.SECONDS);
    

    您所遵循的代码每次都会在 postExecute() 中创建 SimpleAdapter 的新实例,因此您将一次又一次地看到相同的数据。因此,如果您想更新您的适配器,请创建 SimpleAdapter 实例作为类成员并用这个替换 postExecute()

    @Override
            protected void onPostExecute(Void result) {
                super.onPostExecute(result);
                // Dismiss the progress dialog
                if (pDialog.isShowing())
                    pDialog.dismiss();
                /**
                 * Updating parsed JSON data into ListView
                 * */
                if(adapter == null)
                {
                    adapter = new SimpleAdapter(
                        MainActivity.this, contactList,
                        R.layout.list_item, new String[] { TAG_NAME, TAG_EMAIL,
                                TAG_PHONE_MOBILE }, new int[] { R.id.name,
                                R.id.email, R.id.mobile });
    
                                setListAdapter(adapter);
                }
                else
                {
                    adapter.notifyDataSetChanged();
                }
    
    
            }
    

    现在这将更新适配器,但会添加相同的联系人

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-11-13
      • 1970-01-01
      • 2016-01-25
      • 1970-01-01
      • 2013-10-08
      相关资源
      最近更新 更多