Android中更新UI的几种方式
2015-12-30 22:10
453 查看
一、 runOnUiThread
先判断当前线程是否是UI线程,在默认情况下activity有个自己的handler,通过handler会发送一个runnable。public class five extends AppCompatActivity { private TextView textView; private Handler handler = new Handler(){ @Override public void handleMessage(Message msg) { }; }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_five); textView = (TextView) findViewById(R.id.textview); //一般情况下都在子线程中更新UI new Thread(){ @Override public void run() { textView.setText("OK"); try { Thread.sleep(2000); //在Runnable中更新UI handler.post(new Runnable() { @Override public void run() { textView.setText("ok"); } }); } catch (InterruptedException e) { e.printStackTrace(); } } }.start(); } }
二、 handler post
通过post发送一个runnable的象,在内部封装成一个message,先调用一个getPostMessage方法。与本质发送message没有什么区别。public class five extends AppCompatActivity { private TextView textView; private Handler handler = new Handler(){ @Override public void handleMessage(Message msg) { textView.setText("ok2"); }; }; //直接在一个子线程中给handler发送信息 private void handler2(){ handler.sendEmptyMessage(1); } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_five); textView = (TextView) findViewById(R.id.textview); //一般情况下都在子线程中更新UI new Thread(){ @Override public void run() { textView.setText("OK"); try { Thread.sleep(5000); //在Runnable中更新UI handler2(); } catch (InterruptedException e) { e.printStackTrace(); } } }.start(); } }
三、 handler sendMessage
public class five extends AppCompatActivity { private TextView textView; private Handler handler = new Handler(){ @Override public void handleMessage(Message msg) { }; }; //直接在子线程中更新UI private void updataUI(){ runOnUiThread(new Runnable() { @Override public void run() { textView.setText("ok3"); } }); } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_five); textView = (TextView) findViewById(R.id.textview); //一般情况下都在子线程中更新UI new Thread(){ @Override public void run() { textView.setText("OK"); try { Thread.sleep(5000); //在Runnable中更新UI updataUI(); } catch (InterruptedException e) { e.printStackTrace(); } } }.start(); } }
四、 view post
先判断一个AttachInfo,若不为空,通过AttachInfo得到一个handler去发送一个runnable,若为空则通过ViewRootImpl去更新UI。public class five extends AppCompatActivity { private TextView textView; private Handler handler = new Handler(){ @Override public void handleMessage(Message msg) { textView.setText("ok2"); 4000 }; }; //通过view自己发送Runnable private void viewUI(){ textView.post(new Runnable() { @Override public void run() { textView.setText("OK4"); } }); } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_five); textView = (TextView) findViewById(R.id.textview); //一般情况下都在子线程中更新UI new Thread(){ @Override public void run() { textView.setText("OK"); try { Thread.sleep(5000); //在Runnable中更新UI viewUI(); } catch (InterruptedException e) { e.printStackTrace(); } } }.start(); } }
总结:本质都是通过handler去更新UI,只是在内部有一些代码上的差异。
五、非UI线程真的不能更新UI么
1)如下程序可以执行new Thread(){ @Override public void run(){ textView.setText("OK"); } }.start();
2)如下程序会报错
new Thread(){ @Override public void run() { try { Thread.sleep(5000); textView.setText("OK"); } catch (InterruptedException e) { e.printStackTrace(); } } }.start();
原因:
所有更新UI的操作都会调用View的invalidate()方法,在我们调用textView.setText()方法后,内部会调用invalidate()方法。其内部,主要用于判断当前线程是否在UI线程更新的操作在ViewParent类中(有一个checkThread()//用于检查当前更新操作是都在主线程中,当前线程是否和UI线程相等)。
然而(1)中因为onResume方法在onCreate方法之前,所以还未能检查。但是不建议以这种方式更新UI。
六、使用handler时所遇到的问题
1、两个异常1)错误:Only the original thread that created a view hierarchy can touch its views
原因:mThread是在UI线程(activityThread)中创建,若更新UI操作在子线程中,则会抛出异常。
2)错误:Can’t create handler inside thread that has not called Looper.prepare()
原因:在用到handler时必须指定一个looper对象 相关
相关文章推荐
- 使用C++实现JNI接口需要注意的事项
- Android IPC进程间通讯机制
- Android Manifest 用法
- [转载]Activity中ConfigChanges属性的用法
- Android之获取手机上的图片和视频缩略图thumbnails
- Android之使用Http协议实现文件上传功能
- Android学习笔记(二九):嵌入浏览器
- android string.xml文件中的整型和string型代替
- i-jetty环境搭配与编译
- android之定时器AlarmManager
- android wifi 无线调试
- Android Native 绘图方法
- Android java 与 javascript互访(相互调用)的方法例子
- android 代码实现控件之间的间距
- android FragmentPagerAdapter的“标准”配置
- Android"解决"onTouch和onClick的冲突问题
- android:installLocation简析
- android searchView的关闭事件
- SourceProvider.getJniDirectories