Android的UI更新只能在UI线程中,即主线程。子线程中若是要进行UI更新,都是要通知主线程来进行。ide
几种实现方式总结以下,欢迎补充。函数
一、runOnUiThread()oop
子线程中持有当前Activity引用(假如为Activity mActivity;),便可以调用mActivity的runOnUiThread(Runnable r)方法。post
二、post()和postDelay()this
子线程若是持有某个View的引用,要对该View进行更新,则可调用该View对象的post(Runnable r)或postDelay(Runnable r)方法url
Handler对象也有post()方法。其实在Android的源码中,这些post()方法都是借助下面的第3种方法:Handler + Message来实现的。spa
三、Handler + Message或者Handler + Thread + Message线程
主线程创建时,默认状况下是有Looper的,能够处理消息队列。orm
在主线程创建一个Handler对象,复写其handleMessage()方法,在该方法中实现UI更新。对象
示例:
private static final int MSG_CODE = 1001;
private Handler mHandler = new Handler()
{
@Override
public void handleMessage(Message msg)
{
//接收并处理消息
if(msg.what == MSG_CODE)
{
//UI更新
}
}
};
public void doSomething()
{
new Thread()
{
@Override
public void run()
{
//子线程发送信息
Message msg = mHandler.obtainMessage(MSG_CODE);
msg.sendToTarget();
}
}.start();
}
四、Broadcast
子线程中发送广播,主线程中接收广播并更新UI
五、AsyncTask
AsyncTask可方便地实现新开一个线程,并将结果返回给UI线程,而不须要开发者手动去新开一个线程,也无须开发者使用Handler,很是方便。
应当注意的是AsyncTask是一个抽象类,其三个泛型参数的意义以下:
AsyncTask<Param, Progress, Result>
Param:发送给新开的线程的参数类型
Progress:表征任务处理进度的类型。
Result:线程任务处理完以后,返回给UI线程的值的类型。
该类中有四个抽象函数,onPreExecute(), doInBackground(Params... param),
onProgressUpdate(Progress... progress), onPostExecute(Result result)。
除了,doInBackground(Params...)方法,其它三个方法都运行在UI线程。
自定义一个类继承AsyncTask并至少实现 doInBackground()函数。在该函数中执行的过程当中,能够随时调用publishProgress(Progress...)报告其执行进 度。此时会触发另外一个方法onProgressUpdate(Progress... progress),以便在UI线程中的某些控件(如ProgressBar)上更新任务处理的进度。
也能够等doInBackground()执行完,进入onPostExecute()方法后,再进行UI控件的更新。
可在任意时间,任意线程中,取消AsyncTask开启的任务(调用自定义的AsynTask子类的cancel(boolean mayInterruptIfRunning)方法)
使用示例以下:
//若是没记错的话,这个例子应该是以前总结的时候从官网剪下来的
public void onClick(View v) {
new DownloadImageTask().execute("http://example.com/image.png");
}
private class DownloadImageTask extends AsyncTask<String, Void, Bitmap> {
/** The system calls this to perform work in a worker thread and
* delivers it the parameters given to AsyncTask.execute() */
protected Bitmap doInBackground(String... urls) {
return loadImageFromNetwork(urls[0]);
}
/** The system calls this to perform work in the UI thread and delivers
* the result from doInBackground() */
protected void onPostExecute(Bitmap result) {
mImageView.setImageBitmap(result);
}
}