Android 如何从 asynctask 更新 ui

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/23978400/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-20 07:40:25  来源:igfitidea点击:

How to update ui from asynctask

androidandroid-asynctaskandroid-handlerandroid-json

提问by Bjorn

I've seen many examples of how to do this, but I can't figure how to implement it in my code.

我已经看到了很多关于如何执行此操作的示例,但我无法弄清楚如何在我的代码中实现它。

I am using this code.
I have updated the url, so it will receive a json with dynamic data. What I'm trying to do is to automatically update the list every 30 secs with this code.

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

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

It refreshes, and calls the url and gets the data, but the UI does not get updated.

它会刷新并调用 url 并获取数据,但 UI 不会更新。

Thanks for any hints to point me in the right direction.

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

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

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

回答by indivisible

You have three protected methods in an AsyncTask that can interact with the UI.

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

  • onPreExecute()
    • runs beforedoInBackground()
  • onPostExecute()
    • runs afterdoInBackground()completes
  • onProgressUpdate()
    • this only runs when doInBackground()calls it with publishProgress()
  • onPreExecute()
    • 之前运行doInBackground()
  • onPostExecute()
    • 完成运行doInBackground()
  • onProgressUpdate()
    • 这仅在doInBackground()调用它时运行publishProgress()

If in your case the Task runs for a lot longer than the 30 seconds you want to refresh you would want to make use of onProgressUpdate()and publishProgress(). Otherwise onPostExecute()should do the trick.

如果在您的情况下,任务运行的时间比您想要刷新的 30 秒长很多,您将需要使用onProgressUpdate()publishProgress()。否则onPostExecute()应该做的伎俩。

See the official documentationfor how to implement it.

有关如何实现它,请参阅官方文档

回答by Khaled Lela

You can use AsycTaskand update list uion task finished within onPostExecute.

您可以使用AsycTask和更新list uionPostExecute.

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

    };
}

UpdateNo need to use runOnUiThreadinside onPostExecute, Because it's already called on and it's body executed under UIThread.

更新不需要使用runOnUiThreadinside onPostExecute,因为它已经被调用了并且它的主体在UIThread.

回答by umerk44

The first thing is using postdelayed() will not run your code in repetition If you want to run code in repetitive pattern use this code. This will run after every 5 sec

第一件事是使用 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);

The code you are following is creating new instance of SimpleAdapter in postExecute() each time so you will see the same data again and again. So if you want to update your adapter create SimpleAdapter instance as class member and replace the postExecute() by this

您所遵循的代码每次都在 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();
            }


        }

Now this will update adapter but will add same contact

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