Android更新UI的2种方法
来源:互联网 发布:僵尸新娘 配乐 知乎 编辑:程序博客网 时间:2024/04/27 14:54
1、引言
在Android开发过程中,我们常常需要对UI进行更新。而对UI的更新,我们主要是在主线程进行的。常常我们会遇到这样的异常信息:
android.view.ViewRoot$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
这是什么意思呢?翻译过来其实就是说“只有原始创建这个视图层次(view hierachy)的线程才能修改它的视图(view)”,简单的说就是我们在主线程以外的线程进行了UI更新的操作才导致了这个异常。
既然知道了产生的原因,那有什么办法来进行UI更新呢?
2、更新UI两种方法
2.1、方法简介
目前更新UI的方法主要有2种,主要用到的是Handle类和runOnUiThread方法。
2.2 Handler
该方法通常实在Activity的ovnCreate()中创建一个Handler实例,而后在其实例中使用Message类在handleMessage回调函数中对界面UI进行更新。但这样容易引起内存溢出,因而比较好的做法是自定义一个静态私有的Handler类,配合弱引用来避免内存溢出。
示例代码如下:
/** * 初始化控件 */private void initView() { // TODO Auto-generated method stub Button btn = (Button) findViewById(R.id.main_btn); btn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { // TODO Auto-generated method stub Message msg = new Message(); msg.what = 1; msg.obj = getData(); handler.sendMessage(msg); } }); Button btnHide = (Button) findViewById(R.id.main_btn_hide); btnHide.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { // TODO Auto-generated method stub Message msg = new Message(); // msg.what=2; handler.sendEmptyMessage(2); } }); lv = (ListView) findViewById(R.id.main_lv);}/** * 自定义Handler类进行优化 */private static class MyHandler extends Handler {//静态、私有 private WeakReference<MainActivity> mActivity;//弱引用 public MyHandler(MainActivity pActivity) { mActivity = new WeakReference<MainActivity>(pActivity); } @SuppressWarnings("unchecked") @Override public void handleMessage(Message msg) { // TODO Auto-generated method stub MainActivity activity = mActivity.get(); if (null != activity && 1 == msg.what) {//activity是否为空 List<String> list = (List<String>) (msg.obj); lv.setAdapter(new ArrayAdapter<String>(MainActivity.this, android.R.layout.simple_list_item_1, list)); } else if (null != activity && 2 == msg.what) { lv.setAdapter(null); } lv.setOnItemClickListener(new OnItemClickListener() { @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { // TODO Auto-generated method stub Toast.makeText(MainActivity.this, "Click the item:" + (position + 1), 2).show(); showDialog(); } }); }}private MyHandler handler = new MyHandler(this);//实例化
2.3 runOnUiThread
该方法是Activity类的方法,实现的原理其实就是把更新界面UI的过程写在Runnable中,而在需要更新的时候将该Runnable对象传给Activity.runOnUiThread(Runnable)。如果当前线程是UI线程,那么行动是立即执行。如果当前线程不是UI线程,操作是发布到事件队列的UI线程。(该方法用的较少,还不知道有什么可以优化的,若可优化,希望大家留言)
先看下源码:
public final void runOnUiThread(Runnable action) { if (Thread.currentThread() != mUiThread) { mHandler.post(action);//将Runnable Post到消息队列,由内部的mHandler来处理,实际上也是Handler的处理方式 } else { action.run();//已经在UI线程,直接运行。 } }
示例代码如下:
void test(){ runOnUiThread(new MyRunnable());}class MyRunnable implements Runnable{ @Override public void run() { // TODO Auto-generated method stub Toast t=Toast.makeText(LoginActivity.this, "Just A Test", Toast.LENGTH_SHORT); t.show(); }}
2.4 Handler和runOnUiThread的区别
个人的理解就是前者是一个新的子线程,而后者是UI线程(仅仅一个,故而界面是同步)。
具体可以参阅下面的博客。
http://http://blog.csdn.net/id19870510/article/details/6680900
- Android更新UI的2种方法
- Android UI更新的两种方法
- Android 更新UI的两种方法
- android更新UI的几种方法
- android更新UI的几种方法
- Android更新UI的几种方法
- android更新UI的几种方法
- android四种更新UI的方法
- Android更新UI的两种方法
- android 更新UI的两种方法
- Android更新UI的四种方法
- android更新UI的几种方法
- Android 更新UI的几种方法
- Android更新UI的方法
- android更新UI的方法
- Android更新ui的方法
- Android更新UI界面的几种方法的使用
- 探讨android更新UI的几种方法
- HUST 1372 marshmallow
- VFW 介绍
- 【CSS3】:enabled选择器
- js 删除append标签添加的元素
- 易联云打印资料整理
- Android更新UI的2种方法
- 【LEETCODE】148- Sort List [Python]
- 海思3520D芯片硬盘和SD卡挂载说明
- 浅谈 Excel 对象模型
- Unity3D学习笔记(十)物理引擎:碰撞器
- 也议MySQL中隐式转换
- 【CSS3】:disabled选择器
- web Service入门实例
- 关于ARP的那些事儿