一.AsynsTask是什么
1.AsynsTask是Android提供的轻量级(实现代码量少)的异步类
2.为了降低异步通信的开发难度,提供了AsynsTask
3.AsynsTask直接继承于Object类,位于android.os包中
4.使用AsynsTask可以忽略Looper,MessageQueue,Handler等复杂对象,更便捷的完成异步耗时操作
二.AsynsTask怎么用
第一步:新建内部类继承AsynsTask
第二步:定义AsynsTask的三种泛型参数
第三步:重写doInBackground抽象方法
第四步:重写onPreExecute方法
第五步:重写onProgressUpdate方法
第六步:重写onPostExecute方法
第七步:在需要启动的地方调用execute方法
一定要重写doInBackground抽象方法
三.需要实现的几个方法分别是什么,有什么用
doInBackground方法
此方法在子线程中执行,用于执行异步任务,注意这里的params就是AsyncTask的第一个参数类型。
1.执行onPreExecute方法后,系统执行
onPreExecute方法
1.异步任务开始执行时,系统最先调用此方法
2.此方法运行在主线程中,可以对控件进行初始化
onProgressUpdate方法
此方法在主线程中执行,values的类型就是AsyncTask传入的第二个参数类型,当后台任务的执行进度发生变化时此方法执行。
onPostExecute方法
此方法在主线程中执行,在 doInBackground 方法执行完成以后此方法会被调用,其中result的类型就是AsyncTask传入的第三个参数类型,它的值就是doInBackground方法的返回值。
四.什么是泛型参数
AsynsTask的三种泛型参数:
Params:启动任务执行的输入参数
Progress:后台任务执行的百分比
Result:后台执行任务最终返回的结果
五.是什么长度可变的参数列表
String后面的三个点就是代表可变参数,调用的时候可以随便写参数个数,适合不指定性参数
protected void onProgressUpdate(String... values) {
super.onProgressUpdate(values);
task_tv.setText(values[0]);
}
六.案例解析——倒计时Demo
布局文件:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="com.example.myapplication.DownloadTaskActivity">
<TextView
android:layout_width="match_parent"
android:layout_height="200dp"
android:id="@+id/task_tv"
android:gravity="center"/>
<Button
android:layout_width="match_parent"
android:layout_height="50dp"
android:id="@+id/task_btn"
android:text="点击下载"/>
</LinearLayout>
界面效果图:
主类:
新建一个类叫DownloadTask,继承 AsyncTask
如果要在启动线程前做一些操作可以在onPreExecute里面执行
在doInBackground里面开启一个线程
在onProgressUpdate里面接收doInBackground里面的值
在onPostExecute可以把doInBackground返回的值设置在控件里面显示
class DownloadTask extends AsyncTask<String, String, String> {
//启动前
@Override
protected void onPreExecute() {
super.onPreExecute();
task_tv.setText("正在下载");
}
//这个方法一定要重写
@Override
protected String doInBackground(String... strings) {
while (count>0){
publishProgress(count+"");
count--;
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
return "下载完成";
}
@Override
protected void onProgressUpdate(String... values) {
super.onProgressUpdate(values);
task_tv.setText(values[0]);
}
@Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
task_tv.setText(s);
}
}
最后在按钮按下时执行线程
task_btn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
new DownloadTask().execute();
}
});
下面是完整代码:
package com.example.myapplication;
import android.os.AsyncTask;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
public class DownloadTaskActivity extends AppCompatActivity {
private TextView task_tv;
private Button task_btn;
private int count=10;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_download_task);
task_tv = findViewById(R.id.task_tv);
task_btn = findViewById(R.id.task_btn);
task_btn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
new DownloadTask().execute();
}
});
}
class DownloadTask extends AsyncTask<String, String, String> {
//启动前
@Override
protected void onPreExecute() {
super.onPreExecute();
task_tv.setText("正在下载");
}
//这个方法一定要重写
@Override
protected String doInBackground(String... strings) {
while (count>0){
publishProgress(count+"");
count--;
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
return "下载完成";
}
@Override
protected void onProgressUpdate(String... values) {
super.onProgressUpdate(values);
task_tv.setText(values[0]);
}
@Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
task_tv.setText(s);
}
}
}
10之后的效果图:
进度条下载案例:
(需要实现按下按钮一,进度条一能够走动,按下按钮二,进度条二能够走动,意思就是两个线程能够同时进行)
布局文件
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="com.example.myapplication.ProgressActivity">
<ProgressBar
android:layout_width="match_parent"
android:layout_height="200dp"
style="?android:progressBarStyleHorizontal"
android:id="@+id/progress1"
android:max="100"/>
<Button
android:layout_width="match_parent"
android:layout_height="50dp"
android:id="@+id/start_button1"
android:text="开始下载1"/>
<ProgressBar
android:layout_width="match_parent"
android:layout_height="200dp"
style="?android:progressBarStyleHorizontal"
android:id="@+id/progress2"
android:max="100"/>
<Button
android:layout_width="match_parent"
android:layout_height="50dp"
android:id="@+id/start_button2"
android:text="开始下载2"/>
</LinearLayout>
效果图:
主类:
先建一个内部类,我的名字是DownProgrss:
class DownProgrss extends AsyncTask<Integer, Integer, Integer> {
new DownProgrss().execute();
@Override
protected Integer doInBackground(Integer... index) {
}
}
给按钮添加点击事件:
通过按钮按下,实现new DownProgrss().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, 1);
然后把第二个参数传进doInBackground方法里面,因为第一个参数是一个常量。所以在doInBackground方法里面的index参数返回的是index[0]
@Override
public void onClick(View view) {
switch (view.getId()) {
case R.id.start_button1:
new DownProgrss().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, 1);
start_button1.setEnabled(false);
break;
case R.id.start_button2:
new DownProgrss().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, 2);
start_button2.setEnabled(false);
break;
default:
break;
}
}
在doInBackground方法里面启动线程:
我给进度条初始化定义为private int len = 0;如果它小于等于100它就每秒加5,通过return index[0];把值传到
@Override
protected Integer doInBackground(Integer... index) {
while (len <= 100) {
publishProgress(len, index[0]);
len += 5;
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
len=0;
return index[0];
}
通过doInBackground方法里面的publishProgress(len, index[0]);把进度条加上的值传进onProgressUpdate方法进行更新
values[0]的值就是 publishProgress(len, index[0]);里面len值
@Override
protected void onProgressUpdate(Integer... values) {
super.onProgressUpdate(values);
switch (values[1]) {
case 1:
progressBar1.setProgress(values[0]);
break;
case 2:
progressBar2.setProgress(values[0]);
break;
default:
break;
}
}
这是在进度条走完后实现的方法
start_button1.setEnabled(true);设置按钮不可用
@Override
protected void onPostExecute(Integer s) {
super.onPostExecute(s);
switch (s) {
case 1:
start_button1.setText("下载完成");
start_button1.setEnabled(true);
break;
case 2:
start_button2.setText("下载完成");
start_button2.setEnabled(true);
break;
default:
break;
}
}
下面是完整代码:
package com.example.myapplication;
import android.os.AsyncTask;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.ProgressBar;
public class ProgressActivity extends AppCompatActivity implements View.OnClickListener {
private Button start_button1, start_button2;
private ProgressBar progressBar1, progressBar2;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_progress);
start_button1 = findViewById(R.id.start_button1);
progressBar1 = findViewById(R.id.progress1);
start_button1.setOnClickListener(this);
start_button2 = findViewById(R.id.start_button2);
progressBar2 = findViewById(R.id.progress2);
start_button2.setOnClickListener(this);
}
class DownProgrss extends AsyncTask<Integer, Integer, Integer> {
private int len = 0;
@Override
protected void onPreExecute() {
super.onPreExecute();
}
@Override
protected Integer doInBackground(Integer... index) {
while (len <= 100) {
publishProgress(len, index[0]);
len += 5;
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
len=0;
return index[0];
}
@Override
protected void onProgressUpdate(Integer... values) {
super.onProgressUpdate(values);
switch (values[1]) {
case 1:
progressBar1.setProgress(values[0]);
break;
case 2:
progressBar2.setProgress(values[0]);
break;
default:
break;
}
}
@Override
protected void onPostExecute(Integer s) {
super.onPostExecute(s);
switch (s) {
case 1:
start_button1.setText("下载完成");
start_button1.setEnabled(true);
break;
case 2:
start_button2.setText("下载完成");
start_button2.setEnabled(true);
break;
default:
break;
}
}
}
@Override
public void onClick(View view) {
switch (view.getId()) {
case R.id.start_button1:
new DownProgrss().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, 1);
start_button1.setEnabled(false);
break;
case R.id.start_button2:
new DownProgrss().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, 2);
start_button2.setEnabled(false);
break;
default:
break;
}
}
}
效果图: