Android UI界面刷新与交互

一、数据请求与UI界面更新事项

1.1 UI线程

Android在启动应用程序的时候,会为应用创建一个Main线程,这个线程负责将事件分派给相应用户接口的widget,其中包括drawing事件。除了事件分派之外,Main线程还负责应用与Android UI组件(例如, android.widget 和android.view 包)进行交互,因此Main 线程有时候也被称为UI线程。

1.2 ANR

Application Not Response简称ANR,程序无响应。

Android不会为每个组件实例创建单独的线程。运行于同一进程的所有组件均在 UI 线程(Main)中实例化,并且对每个组件的系统调用均由该线程进行分派。这样一来,响应系统回调的方法(例如生命周期回调方法)始终在进程的UI线程中运行。

如果应用在响应用户的操作的时候,在UI线程中执行了大量的耗时操作,比方说网络访问或数据库查询。这样做的后果势必会阻塞整个UI。一旦UI线程被阻塞,将无法分派任何事件,包括绘图事件。

如果UI线程被阻塞超过一定时间(目前 5 秒钟),就会出现我们常说的ANR。

1.3 如何在子线程中访问UI资源

既然ANR是由于在UI线程中执行大量耗时的操作引起的,那么我们在主线程中新建一个worker线程问题不就解决了么?事实上,这种方式的确能够解决一些问题,但是对于UI来说就不是那么灵光了,因为Android UI 线程并不是线程安全的。

1.3.1 线程安全问题

当程序中存在多个线程,如果多个线程都要访问相同的公共的数据或者资源,就会产生线程安全为题。如果不解决线程安全问题,公共数据或者资源就会变得紊乱,影响正常的业务逻辑开发。

1.3.2 线程安全的解决方法

要解决多线程访问共享资源的安全问题,可以通过加锁机制进行解决。常见的加锁机制有:互斥锁,读写锁等方式。加锁后解决了线程安全问题,但是因为涉及到上锁,释放锁的操作,消耗资源,因此加锁会降低程序的运行效率。

综上,当遇到多线程执行时:不加锁,会存在线程安全问题;加了所,解决线程安全问题,影响效率。

1.3.3 Android系统的方案

因为线程安全性能较差,线程不安全性能较好,Android中为了提高UI的绘制效率,保证渲染效果,选择了线程不安全。因为线程不安全带来的问题就是“不安全”,所以Android设计主线程为单线程模型,只能在UI线程中操作UI界面。

二、UI界面刷新方法和注意事项

在Android开发过程中需要注意两点:

  • 1.不要阻塞主线程
  • 2.不要在其他线程调用UI操作方法

如果子线程需要来修改用户界面,就必须先通知主线程,主线程来帮助完成 。

针对不能再线程中更新UI的问题,Android提供了三种在线程中更新UI的方式来解决这一问题:

  • Activity.runOnUiThread(Runnable):activity中存在的方法。
  • View.post(Runnable):view基类存在的方法。
  • View.postDelayed(Runnable, long):view基类包含的方法,与post相似,多一个long参数。