Loop循环、Handler以及UI——循环读取后台数据并显示在Activity页面上

bluehale 2017-10-09 07:30:36
先说一下需求:Android手机,页面上一个Listview,如果Sqlite数据有变化(有另外的线程专门读取数据库数据,同步到本地Sqlite数据库),就显示在ListView上。刚开始线程中使用While循环,后来发现一个问题——while循环虽然可以同步显示数据,
但是点击ListView无效(关于ListView无法点击的问题,Layout中只有几个TextView 和ImageView,为了安全,所有控件设置为
android:focusable="false"
android:focusableInTouchMode="false",设置了也不管用),代码大概如下:
Runnable getMessageTask = new Runnable() {
@Override
public void run() {
while (!stopThread) {
ArrayList<Map<String, String>> listMessages = getMessaageListToMap(messages); //得到数据信息
Message msg = Message.obtain();
msg.obj = listMessages; //通过While循环发送信息
}
}

又修改为Looper循环,依然无效,代码如下:
Runnable getMessageTask = new Runnable() {
@Override
public synchronized void run() {
Looper.prepare();
ArrayList<Map<String, String>> listMessages = getMessaageListToMap(messages); //读取数据信息
Message msg = Message.obtain();
msg.obj = listMessages;
getMessageHandler.sendMessageDelayed(msg, 1000); //发送数据信息
Looper.loop();
}
}

Handler放在Activity的Oncreate方法中,如下:
public class MainActivity extends AppCompatActivity {

。。。。。。

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

。。。。。。。
lvMessage = (ListView)findViewById(R.id.lv_message);
lvMessage.setClickable(true);
lvMessage.setFocusable(false);
lvMessage.setDescendantFocusability(ViewGroup.FOCUS_BEFORE_DESCENDANTS);
lvMessage.setChoiceMode(ListView.CHOICE_MODE_SINGLE);

new Thread(getMessageTask).start();
getMessageHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
try {
ArrayList<Map<String, String>> listMessages = (ArrayList<Map<String, String>>)msg.obj;
SimpleAdapter adapter = new SimpleAdapter(MainActivity.this, listMessages, R.layout.layout_invites,
new String[]{"mID", "creater", "mainContent", "deadLine", "mtype", "createrLogo"},
new int[]{R.id.tv_list_type, R.id.tv_list_name, R.id.tv_list_inviteword, R.id.tv_list_invitedate, R.id.tv_list_inviteid, R.id.iv_list_logo});
lvMessage.setAdapter(adapter);
}
};
。。。。。
也查找了一些资料,但是一直没有找到答案。1. 在循环中,While和Looper区别如何? 2. 如果是用Looper,是否还需要建一个单独的Looper loop = new Looper() 这样的? 3. 循环进行业务处理的代码块(比如本例子的循环查找sqlite数据查看数据变化)、以及消息处理更新UI的部分(handler, 本例子中是得到循环发送来的数据消息,并更新前台页面的listview)在Looper.prepare()和Looper.loop()之中,还是单独放置(我的消息处理Handler是放在Oncreate中,不在Runnable的Looper循环块下)?本人测试发现Looper实际就运行了一次,没有循环。4. 如果是循环,是否只能用Thread和Runnable中一种(本人都是用的Runnable)? 恳请各位高手解答一下
...全文
346 5 打赏 收藏 转发到动态 举报
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
bluehale 2017-10-10
  • 打赏
  • 举报
回复
原因找到了,原先对Looper的理解错误,以为Looper.prepare()和Looper.loop()之间的都是可循环,换言之,以为作用类似While这样,其实只是让信息可以重复而已,至于信息的重复还是要自己处理,在Looper.prepare()和Looper.loop()之间使用While循环重复发送信息,原先那个Activity的问题就好了。也谢谢各位帮助
Jing丶無雙 2017-10-09
  • 打赏
  • 举报
回复
可不可以这么理解,你现在是想解决点击ListView无效的问题。而你的代码中并没有给ListView设置点击回调的方法,比如:
	lvMessage.setOnItemClickListener(new OnItemClickListener() {

			@Override
			public void onItemClick(AdapterView<?> parent, View view,
					int position, long id) {
              //行点击事件处理
			}
		});
哎,真难 2017-10-09
  • 打赏
  • 举报
回复
Looper里面的算法就是while循环,但是Looper的用法是子线程推送主线程消息循环
bluehale 2017-10-09
  • 打赏
  • 举报
回复
接受信息的Handler代码不是放在Looper中间,而是在Oncreate中单独的Handler进行UI处理,是否有问题呢?
bluehale 2017-10-09
  • 打赏
  • 举报
回复
首先谢谢两位答复。回调的方法是有的,在我用Looper.prepare()和Looper.loop()的时候,只能执行一次,不知道为何不能循环执行。我把循环后台取数,发送消息等代码都放在Looper.prepare()和Looper.loop()之间,是否有问题呢?

80,349

社区成员

发帖
与我相关
我的任务
社区描述
移动平台 Android
androidandroid-studioandroidx 技术论坛(原bbs)
社区管理员
  • Android
  • yechaoa
  • 失落夏天
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧