在Android中,线程分为主线程和子线程,主界面用于与用户交互,进行UI的相关操作,而子线程则负责耗时操作。如果在主线程中进行耗时操作,就会使程序无法及时的响应。因此耗时操作必须放在子线程中进行。
1、主线程和子线程
主线程是指进程所有用的线程,在Android中即指进行UI与用户交互的线程就是主线程。因此在Android开发中,需要竟可能的把耗时操作,网络请求访问操作,数据库读取操作等放在子线程,以避免主线程长期处于占用状态以降低用户体验。系统要求网络访问必须在子线程中进行,否则会抛出NetworkOnMainThreadException异常。
2、线程形态
Android中的线程形态有传统的Thread,AsyncTask,HandlerThread和IntentService。
2.1、AsyncTask
AsyncTask封装了Thread和Handler,必须在主线程进行调用,它可以在子线程中执行任务,然后将执行的结果传递给主线程并更新UI。但AsyncTask并不适合执行特别耗时的任务。
2.1.1、参数:
AsyncTask是一个泛型类,提供了三个泛型参数,Params ,Progress 和Result。
- Params表示参数的类型
- Progress表示后台任务的执行进度的类型
- Result表示后台任务返回结果的类型
AsyncTask的声明:
public abstract class Asynctask<Params,Progress,Result>
2.1.2、方法:
AsyncTask提供了一些核心方法:
- onPreExecute() 在主线程中调用用来进行异步任务的准备操作。
- doInBackground(Params …… params) 在执行完onPreExecute()后进行子线程任务时自动调用,Params表示异步任务的输入参数。在方法中可以通过publishProgress更新任务的完成进度,同时在结束调用后会返回结果给onPostExecute()方法。
- onProgressUpdate(Params …… params) 在主线程中用于显示任务进行的进度,在publishProgress()方法中被调用。
- onProgressExecute(Result result) 在主线程中用户获取任务结束后回返的结果,即doInBackground的返回值。
- onCancelled() 在主线程中执行,当异步任务被取消后不会执行onProgressExecute方法而会执行onCancelled方法。
2.1.3、调用:
AsyncTask的使用步骤如下: 1.创建AsyncTask子类,具体实现其核心方法 2.创建子类的实例对象 3.调用execute执行异步线程任务
2.1.4、AsyncTask的限制:
1.必须在主线程加载,即第一次访问AsyncTask必须在主线程,对象必须在主线程创建 2.execute必须在UI线程中调用 3.不能再程序中直接调用onPreExecute(),onPostExecute(),doInBackground和onProgressUpdate方法。 4.一个AsyncTask方法只能使用一次
2.1.5、AsyncTask的工作原理:
- execute方法
public final AsyncTask<Params, Progress, Result> execute(Params... params) {
return executeOnExecutor(sDefaultExecutor, params);
}
public final AsyncTask<Params,Progress,Result>executeOnExecutor(Executor exec, Params...params){
if (mStatus != Status.PENDING) {
switch (mStatus) {
case RUNNING:
throw new IllegalStateException("Cannot execute task:"
+ " the task is already running.");
case FINISHED:
throw new IllegalStateException("Cannot execute task:"
+ " the task has already been executed "
+ "(a task can be executed only once)");
}
}
mStatus=Status.RUNNING;
onPreExecute();
mWorker.mParams=params;
exec.execute(mFuture);
return this;
}
在execute方法中,会检测AsyncTask的当前状态,如果当前为RUNNING或FINI