因为Android在开发中规定不能直接在子线程(非UI线程或非main线程)中更新UI,所以需要考虑如果在子线程中更新界面时,如何进行UI的刷新显示操作,下面根据开发的经历,总结一下几种在子线程中如何进行UI的更新操作。
先分析android系统不允许直接在子线程中进行UI操作的原因吧:
在多线程的程序中,对CPU的资源具有抢占性,也就是多个线程并发的运行时,多线程操作处理不当可能会导致数据的不一致,而界面是数据的直接反映,所以这个规定主要是避免多线程的并发可能引起的更新界面错乱的问题。Android开发很多地方用到多线程的机制,如果在一个Activity中存在多个线程更新UI,而此时Activity中没有使用一种”加锁”机制,那么就可能会产生更新时界面错乱的问题。
下面是Android开发中几种常见的子线程中更新UI的方式,当然这里说的在子线程中更新ui本质上还是从子线程中转到主线程中执行更新UI的操作,所以这个问题本质上也就是在多线程编程时,怎么实现线程的切换操作,只是这个问题更加具体化,只是从子线程向主线程中切换。
一,Handler机制
Handler的作用
handler是Android提供的用来更新UI的一套机制,也是一套消息处理机制,可以发送消息,也可以通过特定的方法接受并处理消息,handler封装了一套消息处理机制。
Android在设计的时候就封装了一套消息机制,包括消息创建、传递、处理机制,凭借这个机制就能很通过很简单的编码实现消息的处理机制。
几个常用的handler发送消息的方法:
//发送消息
public final boolean sendEmptyMessage(int what)
public final boolean sendMessage(Message msg)
public final boolean sendMessageDelayed(Message msg, long delayMillis)
//发送任务
public final boolean post(Runnable r)
public final boolean postDelayed(Runnable r, long delayMillis)12345671234567
实现图图片轮播效果的代码示例:
public class MainActivity extends Activity {
//图片id
public int resId[] = { R.drawable.kola, R.drawable.qie, R.drawable.yujinxiang };
//图片id下标
private int index;
private ImageView mImageView;
// 通过Handler机制更新UI
private Handler handler = new Handler();
// 创建一个实现图片轮流显示的Runnable对象
class PictureTask implements Runnable {
@Override
public void run() {
index ++;
index %= 3;
mImageView.setImageResource(resId[index]);
handler.postDelayed(task, 1000);
}
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mImageView = (ImageView) findViewById(R.id.imageView1);
PictureTask task= new PictureTask ();
handler.postDelayed(task, 2000);
}
}1234567891011121314151617181920212223242526272812345678910111213141516171819202122232425262728
当需要在子线程中创建Handler对象,并需要处理消息时,就要自己手动编码创建Looper,因为只有UI线程是系统已经将Looper创建好了的。创建方法很简单:
Looper.prepare();
Handler handler=new Handler();
Looper.loop()
或者:Handler handler=new Handle(Looper.getMainLooper());
即可得到在子线线程中的创建消息队列和消息轮询(Looper)。
二,AsyncTask工具
AsyncTask 异步任务加载:
AsyncTask抽象类用于被继承使用
参数说明:
Prams:启动任务时输入参数类型
Progress:后台任务执行过程中的进度值类型
Result:后台执行任务完成后返回值类型
回调方法说明:
doInBackground:必须重写,异步执行后台线程将要完成的任务
onPreExecute:执行完后台操作前被调用,初始化操作–准备工作
onPostExecute:完成后被调用
onProgressUpdate:被doInBackground调用,更新进度
调用一般顺序: onPreExecute->doInBackground->onPostExecute
宁波整形医院那家好http://www.lyxcl.org/