当一个程序第一次启动时,Android会同时启动一个主线程(Main Thread),主线程主要负责处理与UI相关的事件,如:用户的按键事件,用户点击按钮的事件,用户接触屏幕的事件以及屏幕绘图事件等,同时,主线程会把相关的事件分发到对应的组件进行处理。所以主线程通常又叫做UI线程。
在开发Android 应用时必须遵守单线程模型的原则:
Android UI操作并不是线程安全的并且这些操作必须在UI线程中执行。
在非UI线程(子线程)中不可以直接操作UI线程,即不可以设定UI,否则会抛出:android.view.ViewRoot$CalledFromWrongThreadException异常。
单线程模型优点:
1. 保证UI的准确性
2. 保证UI的稳定性,避免多线程同时对UI操作而造成的混乱
Android虽然是单线程模型,但这个单线程只限于UI。另外的一些耗时操作,如网络连接、读取文件等都可以放在子线程中进行。但多线程编程实现又较为繁琐,所以,Android提供了一个封装良好的组件——AsyncTask。
AsyncTask是Android中进行异步任务的组件,其诞生的目的是:
- 实现子线程中更新UI
- 封装、简化异步任务
AsyncTask<Params,Progress,Result>是抽象类,使用时需被继承,下面介绍其基本结构。
public class AsyncTaskTest extends AsyncTask<Void,Void,Void>{
@Override
protected Void doInBackground(Void... params) {
// TODO Auto-generated method stub
return null;
}
}
上例中AsyncTask三个泛型参数都为Void。
package com.asynctasktest;
import android.os.AsyncTask;
public class AsyncTaskTest extends AsyncTask<Void,Void,Void>{
@Override
protected Void doInBackground(Void... params) {
// TODO Auto-generated method stub
return null;
}
@Override
protected void onPreExecute() {
}
@Override
protected void onPostExecute(Void result) {
}
@Override
protected void onProgressUpdate(Void... values) {
}
}
doInBackground可以自动生成,另外三个方法就需要自己添加了。
先补充一下上述四个方法里面的执行内容:
package com.asynctasktest;
import android.os.AsyncTask;
import android.util.Log;
public class AsyncTaskTest extends AsyncTask<Void,Void,Void>{
@Override
protected Void doInBackground(Void... params) {
// TODO Auto-generated method stub
Log.d("AsyncTaskTest","doInBackground");
//更新进度,执行了此方法方可执行onPregressUpdate
this.publishProgress();
return null;
}
@Override
protected void onPreExecute() {
Log.d("AsyncTaskTest","onPreExecute");
}
@Override
protected void onPostExecute(Void result) {
Log.d("AsyncTaskTest","onPostExecute");
}
@Override
protected void onProgressUpdate(Void... values) {
Log.d("AsyncTaskTest","onProgressUpdate");
}
}
执行的任务只是在Android日志里输出四个方法名。
下面是在主线程中调用AsyncTaskTest,即执行此异步任务:
public class MainActivity extends ActionBarActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//实例化AsyncTask
AsyncTaskTest test = new AsyncTaskTest();
//启动后台线程
test.execute();
//主线程执行任务:在日志中输出Hello,World
Log.d("MainActivity","Hello, World");
}
}
执行后在日志中的输出结果为:
最先执行的是onPreExecute,这个方法负责初始化参数,并且是在UI线程中执行,然后就输出了主线程要输出的“Hello, World”,表明AsyncTask的确没阻塞主线程;然后执行了后台任务执行方法doInBackground以及进度更新方法onProgressUpdate方法,最后在doInBackground方法执行后执行了onPostExecute方法,表明后台线程运行结束。
版权声明:本文为博主原创文章,未经博主允许不得转载。
原文地址:http://blog.csdn.net/zgljl2012/article/details/47103527