一 相关概念
几个关键词:应用程序,进程,线程,多线程。
应用程序(Application)
为了完成特定任务,用某种语言编写的一组指令集合(一组静态代码)
进程(Process)
运行中的程序,系统调度与资源分配的一个独立单位,操作系统会为每个进程分配 一段内存空间,程序的依次动态执行:代码加载 >>>> 执行 >>>> 执行完毕的完整过程!
线程(Thread)
比进程更小的执行单元,每个进程可能有多条线程,线程需要放在一个进程中才能执行! 线程是由程序负责管理的!!!而进程则是由系统进行调度的!!!
多线程概念(Multithreading)
并行地执行多条指令,将CPU的时间片按照调度算法,分配给各个线程,实际上是分时执行的,只是这个切换的时间很短,用户感觉同时而已!
同步与异步的概念:
同步:当我们执行某个功能时,在没有得到结果之前,这个调用就不能返回!简单点就是说必须 等前一件事做完才能做下一件事。
异步:和同步则是相对的,当我们执行某个功能后,我们并不需要立即得到结果,我们额可以正常地 做其他操作,这个功能可以在完成后通知或者回调来告诉我们。举例:下载软件的时候,在后台下载, 我们执行下载功能后,我们就无需去关心它的下载过程,当下载完毕后通知我们就可以了。
二 AsyncTask基本解析
新建一个类TestAsyncTask
继承AsyncTask
,需要指定三个泛型参数。
public class TestAsyncTask extends AsyncTask<Void, Integer, String>{
}
第一个参数Params
: 开始异步任务执行时传入的参数类型,对应excute()中传递的参数。
第二个参数Progress
: 异步任务执行过程中,返回下载进度值的类型。
第三个参数Result
: 异步任务执行完成后,返回的结果类型,与doInBackground()的返回值类型保持一致。
/**
* 第一个参数Parma: 执行异步任务时传入的参数,即doInBackground方法参数类型。
* 第二个参数Progress: 显示异步任务的进度,选择Integer类型,即onProgressUpdate方法参数类型。
* 第三个参数Result: 异步任务执行完成后,返回的结果类型。即onPostExecute方法的参数类型与
doInBackground()的返回值类型保持一致。
* 执行顺序: onPreExecute --> doInBackground --> onProgressUpdate --> onPostExecute
*/
public class TestAsyncTask extends AsyncTask<Void, Integer, String> {
/**
* 通常用于一些初始化操作
*/
@Override
protected void onPreExecute() {
super.onPreExecute();
// 在主线程(UI线程)
// 进行各种初始化
}
/**
* 核心方法,负责执行很耗时的异步任务工作。
*/
@Override
protected String doInBackground(Void... voids) {
// 在子线程
// 在onPreExecute方法执行后马上执行
// 可调用publishProgress() 方法触发onProgressUpdate对UI进行操作
// 比如传递后台任务的进度值,倒计时,下载进度....等
publishProgress(10);
return "String";
}
/**
* 负责回主线程进行UI交互,比如实时刷新显示进度条数据等
* 在doInBackground方法中调用publishProgress方法则触发该方法
*/
@Override
protected void onProgressUpdate(Integer... values) {
super.onProgressUpdate(values);
// 在主线程(UI线程)
// 在这里处理UI更新等
}
/**
* 接收线程任务的执行结果,将执行结果进行回调到主线程
*/
@Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
// 在主线程(UI线程)
// 异步任务doInBackground执行完毕会自动执行该方法
// 这里onPostExecute方法的参数,和doInBackground的返回值类型必须保持一致
}
/**
* 取消异步任务时触发该方法
*/
@Override
protected void onCancelled(String s) {
super.onCancelled(s);
// 在主线程(UI线程)
// 取消异步任务时触发该方法
}
}
三 如何使用
1、在doInBackground
方法中实现异步任务。
2、建AsyncTask
子类的实例对象
3、手动调用execute( )
从而执行异步线程任务。
-
Task
的实例必须在主线程中创建; -
execute()
方法必须在主线程中调用; - 不要手动的调用
onPreExecute()、onPostExecute(Result)、doInBackground(Param…)、onProgressUpdate(Progress…)
这几个方法; - 每个实例
Task
只能被执行一次,否则多次调用时将会出现异常。所以要进行判断。
public class MainActivity extends AppCompatActivity {
private TextView titleLab;
private MyAsyncTask myAsyncTask;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initTestAsyncTask();
}
private void initTestAsyncTask() {
titleLab = (TextView) findViewById(R.id.titleLab);
myAsyncTask = new MyAsyncTask();
findViewById(R.id.startBtn).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (myAsyncTask.isCancelled()) {
// 异步任务类只能执行一次,当取消或完成时需要重新创建对象
myAsyncTask = new MyAsyncTask();
}
myAsyncTask.execute();
}
});
findViewById(R.id.stopBtn).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
myAsyncTask.cancel(true);
}
});
}
public class MyAsyncTask extends AsyncTask<Void, Integer, String> {
@Override
protected void onPreExecute() {
super.onPreExecute();
}
@Override
protected String doInBackground(Void... voids) {
try {
for (int i = 1; i <= 10; i++) {
publishProgress(i);
Thread.sleep(50);
}
return "100%";
} catch (InterruptedException e) {
e.printStackTrace();
}
return null;
}
@Override
protected void onProgressUpdate(Integer... values) {
super.onProgressUpdate(values);
titleLab.setText("加载中..." + values[0] + "%");
}
@Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
if (s != null) {
titleLab.setText("任务已经完成,进度为: " + s);
}
// 异步任务类只能执行一次,当取消或完成时需要重新创建对象
// 否则重复执行会闪退
myAsyncTask = new MyAsyncTask();
}
@Override
protected void onCancelled() {
super.onCancelled();
titleLab.setText("任务已取消!");
}
}
}
网友评论