前言
项目遇到的需求:已有一个动态增长的图片列表,需要实现加载这个列表中的图片到手机屏幕.
难点在于:图片列表是动态增长的,所以需要我们有一个线程能够一直监听这个列表的变化,得到图片列表新增加了哪些图片,
然后再把新增加的图片加载到页面上.
这里就涉及到子线程中更改UI的问题,当然子线程是不能更改UI元素的,所以需要配合Handler.
其实也可以使用AsyncTask
或者RxJava
,AsyncTask
我之前总结过一篇博客,有兴趣的朋友可以看一看Service后台服务-AsyncTask.
子线程+Handler更新UI
这里我们先看一下每秒更新一下文本的demo,
Activity的代码:
public class HandlerActivity extends AppCompatActivity {
private TextView dateView;//显示日期
@SuppressLint("HandlerLeak")
private Handler updateDateHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
//获取日期,显示
Bundle bundle = msg.getData();
String date = bundle.getString("value");
dateView.setText(date);
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_handler);
dateView = (TextView) findViewById(R.id.dateView);
//启动线程,向UI线程发送日期消息
new UpdateDateThd(updateDateHandler).start();
}
//发送消息给UI线程的子线程.
class UpdateDateThd extends Thread{
private Handler handler;
public UpdateDateThd(Handler handler) {
this.handler = handler;
}
@Override
public void run () {
while (true) {
try {
//每秒向主线程发送一次消息
TimeUnit.MILLISECONDS.sleep(1000);
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String date = sdf.format(new Date());
sendMessage(date);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
private void sendMessage(String msg){
Bundle data = new Bundle();
data.putString("value", msg);
Message message = new Message();
message.setData(data);
this.handler.sendMessage(message);
}
}
}
在这里,有一个线程类,一个Handler,然后我们做了以下几件事:
- 将在主线程创建的Handler作为参数,传给线程的构造方法.
- 子线程内部通过 获得的 Hanlder发送message,而Handler的handleMessage()这时处理发送过来的message.
- 那么主线程和子线程之间通过将Bundle 放入 Message中,这样主线程就知道了我们想更新什么信息.
子线程中 包装要发送的信息 放入Message中
Bundle data = new Bundle();
data.putString("value", msg);
Message message = new Message();
message.setData(data);
- 在Handler的handleMessage中,
获取子线程发送来的消息.做出UI更新.
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
//获取日期,显示
Bundle bundle = msg.getData();
String date = bundle.getString("value");
dateView.setText(date);
}
子线程+Handler 更新adapter
相信大家看完上面的例子已经知道怎么更新adapter了,其实只需要,在线程的run方法中:
- 通过while(true) 让线程一直运行
- 在run()里获得动态图片列表 新增加的部分(可以一个一个的获得).
- 然后通过将获得的图片对象(路径)通过 bundle 包装到 Message中. 也就是
@Overide
public void run() {
while(true) {
1,获得最新的数据 data
2,sendMessage (data)
}
}
- 主线程的Handler获得 新增加的图片对象(路径),
- adapter的数据list添加 新增加的图片对象(路径). 也就是
private Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {
1,通过message获得子线程发送过来的新数据
2.adatper.add(data)
3.adapter.notify....等等
}
最终动态更新图片 adapter的效果
(完~)