怎么解决“线程内不能更新UI”的问题? 线程UI更新 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 更新ui要放在ui线程中,你可以在非ui线程中使用handler发消息给ui线程中的 Message去处理消息。使用曲线救国:handler+Message,机制实现在非ui线程中更新ui的目的。 我是楼主。。我再发个mp3_item的布局文件代码吧,希望各位能帮我看看!<?xml version="1.0" encoding="utf-8" ?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="horizontal" android:paddingLeft="10dp" android:paddingRight="10dp" android:paddingTop="1dp" android:paddingBottom="1dp" tools:context=".Mp3ListActivity" > <TextView android:id="@+id/mp3_name" android:layout_width="180dp" android:layout_height="30dp" android:textSize="10pt"/> <TextView android:id="@+id/mp3_size" android:layout_width="180dp" android:layout_height="30dp" android:textSize="10pt"/></LinearLayout> 额,没仔细看你的问题,你用下astytask也可以,你在哪里更新list列表了,你只是加载了一次adapter runOnUiThread(new Runnable() { @Override public void run() { // TODO Auto-generated method stub final List<HashMap<String, String>> list = new ArrayList<HashMap<String, String>>(); for (Iterator iterator = mp3s.iterator(); iterator .hasNext();) { Mp3 mp3 = (Mp3) iterator.next(); HashMap<String, String> map = new HashMap<String, String>(); map.put("mp3_name", mp3.getMp3Name()); map.put("mp3_size", mp3.getMp3Size()); list.add(map); } SimpleAdapter simpleadapter = new SimpleAdapter( MyMp3ListActivity.this, list, R.layout.mp3_item, new String[] { "mp3_name", "mp3_size" }, new int[] { R.id.mp3_name, R.id.mp3_size }); setListAdapter(simpleadapter); simpleadapter.notifyDataSetChanged(); } });注意到没 simpleadapter.notifyDataSetChanged(); 这句 他这里不是第一次加载一个新的simpleadapter,为啥还simpleadapter.notifyDataSetChanged() 一个是初始化activity的时候set,一个是初始化之后set,这应该有区别的吧,还是得notify下 如果再初始化activity的时候就set了一个adapter,那后面就不用在new一个adapter了,只用修改里面的arrylist内容就行了,然后adapter.notifyDataSetChanged() 额,AIDL,严重了吧,AIDL 是接口描述语言,用来做进程间通信的,就像Window 中的管道等样。在非UI线程更新UI,Google 其实是提供了多种方法的:一:Android中最经典的 “消息机制” 就是 Handler+Message的方式,就拿你上面的代码例子来说,private class MP3{ String name; int size;} private List<MP3> mList = new ArrayList<MP3>(); private Thread mThread = new Thread(){ public void run() { Message msg = new Message(); msg.obj = mList; mHandler.sendMessage(msg); };};假如mThread 就是你用来请求或者下载数据的线程,那么,在mList数据得到之后,把它赋给msg.obj,然后,在主线程中接收数据,private Handler mHandler = new Handler(){ public void handleMessage(Message msg) { List<MP3> myData = (List<MP3>)msg.obj; //做你的UI更新,比如List更新 };};二:第二种方法就是用异步请求的方式请求数据,然后直接把List或者其他组件的更新放在请求结束之后,其实本质上还是要把消息传送到主线程的。 2345678910111213private class MP3{ String name; int size;} private List<MP3> mList = new ArrayList<MP3>(); private Thread mThread = new Thread(){ public void run() { Message msg = new Message(); msg.obj = mList; mHandler.sendMessage(msg); };};private Handler mHandler = new Handler(){ public void handleMessage(Message msg) { List<MP3> myData = (List<MP3>)msg.obj; //做你的UI更新,比如List更新 };};线程+handler,,,通过handler在主线中更新ui 一楼的对,使用handler+Message可以解决 处理使用handler+Message,也可以使用BroadcastReceiver Message msg = new Message(); msg.obj = mList; mHandler.sendMessage(msg);这么写其实不是很好Message msg = mHandler.obtainMessage();msg.obj = mList;msg.sendToTarget();比较好obtainMessage()是从global message pool里取, new是创建新对象, 所以new的效率低 你可以用一个异步任务类:AsyncTask<Params, Progress, Result>,来更新ui,参考地址http://blog.csdn.net/dabizime/article/details/6695705 AsyncTasknet部分放到 onPostExecute操作UI部分放到 doInBackground 这个我还没学过,我回头看看相关资料吧~主要是,因为现在还是把xml的解析放在了线程里,你觉得应不应该把xml的解析也放到主线程来执行呢? 这样写的话,Handler里边是不是也要用一个变量来接收msg.obj?? 你的布局文件应该有个这个listview<ListView android:id="@id/android:list" android:layout_width="match_parent" android:layout_height="match_parent" /> new Thread(r).start(); h.post(r); //这个好像没啥用? 不知道这个是做什么用。 和Handler没什么关系, 就是创建message方法不同 发消息呗 Handler 和 Message 解决 我的MainActivity的布局文件就是这个了。。SimpleAdapter里边用到的那个item.xml是上边我说到的那个,有问题么? 可以了解下AsyncTask,可以解决你的问题,onProgress可以更新主线程视图 菜鸟求助 EditText获取空值 xmpp 如何监听好友的在线状态 很简单的问题 这个值怎么传过来? 如何优化安卓中删除联系人的速度 Java 解压缩 APK 并重新局部替换文件后打包 怎么弄啊? 请教,谁可以推荐本android的好书,可以配合源码学习的书 源代码下载 图片在放大过程中如何裁剪? 关于ListView异步加载数据(不是图片) 安卓如何对获取新闻数据进行区别 android应用添加微信分享。 如何监听菜单键
使用曲线救国:
handler+Message,机制实现在非ui线程中更新ui的目的。
<?xml version="1.0" encoding="utf-8" ?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal"
android:paddingLeft="10dp"
android:paddingRight="10dp"
android:paddingTop="1dp"
android:paddingBottom="1dp"
tools:context=".Mp3ListActivity" >
<TextView
android:id="@+id/mp3_name"
android:layout_width="180dp"
android:layout_height="30dp"
android:textSize="10pt"/>
<TextView
android:id="@+id/mp3_size"
android:layout_width="180dp"
android:layout_height="30dp"
android:textSize="10pt"/></LinearLayout>
@Override
public void run() {
// TODO Auto-generated method stub
final List<HashMap<String, String>> list = new ArrayList<HashMap<String, String>>();
for (Iterator iterator = mp3s.iterator(); iterator
.hasNext();) {
Mp3 mp3 = (Mp3) iterator.next();
HashMap<String, String> map = new HashMap<String, String>();
map.put("mp3_name", mp3.getMp3Name());
map.put("mp3_size", mp3.getMp3Size());
list.add(map);
}
SimpleAdapter simpleadapter = new SimpleAdapter(
MyMp3ListActivity.this, list,
R.layout.mp3_item, new String[] {
"mp3_name", "mp3_size" },
new int[] { R.id.mp3_name, R.id.mp3_size });
setListAdapter(simpleadapter);
simpleadapter.notifyDataSetChanged();
}
});注意到没 simpleadapter.notifyDataSetChanged(); 这句
一个是初始化activity的时候set,一个是初始化之后set,这应该有区别的吧,还是得notify下
一:Android中最经典的 “消息机制” 就是 Handler+Message的方式,就拿你上面的代码例子来说,
private class MP3{
String name;
int size;
}
private List<MP3> mList = new ArrayList<MP3>();
private Thread mThread = new Thread(){
public void run() {
Message msg = new Message();
msg.obj = mList;
mHandler.sendMessage(msg);
};
};
假如mThread 就是你用来请求或者下载数据的线程,那么,在mList数据得到之后,把它赋给msg.obj,然后,在主线程中接收数据,
private Handler mHandler = new Handler(){
public void handleMessage(Message msg) {
List<MP3> myData = (List<MP3>)msg.obj;
//做你的UI更新,比如List更新
};
};二:第二种方法就是用异步请求的方式请求数据,然后直接把List或者其他组件的更新放在请求结束之后,其实本质上还是要把消息传送到主线程的。
2
3
4
5
6
7
8
9
10
11
12
13
private class MP3{
String name;
int size;
}
private List<MP3> mList = new ArrayList<MP3>();
private Thread mThread = new Thread(){
public void run() {
Message msg = new Message();
msg.obj = mList;
mHandler.sendMessage(msg);
};
};private Handler mHandler = new Handler(){
public void handleMessage(Message msg) {
List<MP3> myData = (List<MP3>)msg.obj;
//做你的UI更新,比如List更新
};
};线程+handler,,,通过handler在主线中更新ui
msg.obj = mList;
mHandler.sendMessage(msg);这么写其实不是很好Message msg = mHandler.obtainMessage();
msg.obj = mList;
msg.sendToTarget();
比较好obtainMessage()是从global message pool里取, new是创建新对象, 所以new的效率低
net部分放到 onPostExecute
操作UI部分放到 doInBackground
android:id="@id/android:list"
android:layout_width="match_parent"
android:layout_height="match_parent"
/> new Thread(r).start();
h.post(r); //这个好像没啥用? 不知道这个是做什么用。
和Handler没什么关系, 就是创建message方法不同