Android 如何从asynctask更新ui
我已经看过很多这样做的例子,但是我不知道如何在我的代码中实现它 我正在用这个。Android 如何从asynctask更新ui,android,android-asynctask,android-handler,android-json,Android,Android Asynctask,Android Handler,Android Json,我已经看过很多这样做的例子,但是我不知道如何在我的代码中实现它 我正在用这个。 我已经更新了url,因此它将收到一个包含动态数据的json。 我要做的是用这段代码每隔30秒自动更新一次列表 Handler handler = new Handler(); Runnable refresh = new Runnable() { public void run() { new GetContacts().execute(); h
我已经更新了url,因此它将收到一个包含动态数据的json。 我要做的是用这段代码每隔30秒自动更新一次列表
Handler handler = new Handler();
Runnable refresh = new Runnable() {
public void run() {
new GetContacts().execute();
handler.postDelayed(refresh, 30000);
}
};
它刷新、调用url并获取数据,但UI不会更新
谢谢你给我指点方向
您可以使用
AsycTask
并在onPostExecute
内完成的任务上更新列表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);
}
};
}
newasynctask(){
/**
*在开始做背景工作之前。
* */
@凌驾
受保护的void onPreExecute(){
}
@凌驾
受保护的字符串doInBackground(字符串…参数){
//TODO获取url数据执行bg进程。
返回null;
}
/**
*流程完成后更新列表ui。
*/
受保护的void onPostExecute(字符串结果){
//无需使用activity.runOnUiThread(),代码在UI线程下执行。
//将解析的JSON数据更新到ListView中
最终列表数据=new Gson().fromJson(结果);
//更新列表视图
((ListActivity)活动)。更新(data);
}
};
}
更新
无需在
onPostExecute
内部使用runOnUiThread
,因为它已经被调用,并且它的主体在UIThread下执行。异步任务中有三个受保护的方法,可以与UI交互
onPreExecute()
- 在
doInBackground()之前运行
onPostExecute()
- 在
doInBackground()完成后运行
onProgressUpdate()
- 这仅在
doInBackground()
使用publishProgress()调用它时运行
如果在您的情况下,任务的运行时间远远超过您要刷新的30秒,则您需要使用onProgressUpdate()
和publishProgress()
。否则,onPostExecute()
请参阅以了解如何实现它。第一件事是使用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()替换为
现在,这将更新适配器,但将添加相同的联系人GetContacts的postExecute()正在更新UI,如果是这样,它已经在UI线程上运行,应该可以工作。试着提供更多的代码我想问的是,第一句话是一个问题…“,”->“?”听起来好像您正在尝试更新ListView。如果这是正确的,您应该更新数据结构,并使用如下方法将其传递给适配器:public synchronized void refreshAdapter(List itemList){this.itemList=itemList;notifyDataSetChanged();}
R您是每30秒更新一次url还是每次都点击相同的url?您不需要在onPostExecute()中使用runOnUiThread()
。已经有了。
@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();
}
}