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
How to update ui from asynctask
提问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 before
doInBackground()
- runs before
onPostExecute()
- runs after
doInBackground()
completes
- runs after
onProgressUpdate()
- this only runs when
doInBackground()
calls it withpublishProgress()
- this only runs when
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 AsycTask
and update list ui
on task finished within onPostExecute
.
您可以使用AsycTask
和更新list ui
在onPostExecute
.
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 runOnUiThread
inside onPostExecute
, Because it's already called on and it's body executed under UIThread
.
更新不需要使用runOnUiThread
inside 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
现在这将更新适配器但会添加相同的联系人