什么是AsyncTask
当执行一个比较简单的耗时操作时,AndroidSDK提供一种轻量级的消息通信方法——AsyncTask,降低了通信的难度。
AsyncTask是Android提供的轻量级的异步类;
AsyncTask直接继承Object类;
使用AsyncTask可以忽略Looper、MessageQueue、Handle等复杂对象,更便捷的完成异步耗时操作。
使用AsyncTask
AsyncTask的执行过程
UI线程——>启动AsyncTask——>执行耗时操作——>接收消息
使用AsyncTask步骤:
- 新建内部类继承AsyncTask;
- 定义AsyncTask的三种泛型参数;
- 重写doInBackground抽象方法(作为子线程,做耗时操作);
- 重写onProExecute方法;
- 重写onProgressUpdate方法;
- 重写PostExecute方法;
- 需要在启动的地方调用execute方法。
AsyncTask的泛型参数和常用方法:
三种泛型参数:
Params:启动任务执行的输入参数;
Progress:后台任务执行百分比;
Result:后台执行任务最终返回的结果。
方法:
onPreExecute方法:
异步任务开始执行时,系统最先调用此方法;此方法运行在主线程中,可以对控件进行初始化等操作。
doInBackground方法:
执行onPreExecute方法后,系统执行此方法;此方法运行在子线程中,比较耗时操作。
publishProgress方法:在DoInBackground中使用。
onPostExecute方法:此方法运行在主线程中,可以修改控件状态。例如:下载完成。
onProgressUpdate方法:显示当前进度,适用于下载或扫描这类需要实时显示进度的需求,此方法运行在主线程中,可以修改控件状态。
使用AsyncTask做倒计时
效果图:
<RelativeLayout
android:gravity="center"
android:layout_width="match_parent"
android:layout_height="100dp">
<TextView
android:id="@+id/cc2_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="设置时间为"
android:textSize="30sp"
/>
<EditText
android:id="@+id/time_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="20sp"
android:layout_toRightOf="@+id/cc2_text"
/>
<TextView
android:id="@+id/cc2_text2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="秒"
android:textSize="30sp"
android:layout_toRightOf="@+id/time_text"
/>
</RelativeLayout>
<TextView
android:layout_gravity="center"
android:id="@+id/time_pre"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="30sp"
android:text="计时开始"
/>
<Button
android:id="@+id/time_btn"
android:layout_gravity="center"
android:layout_width="200dp"
android:layout_height="100dp"
android:text="开始倒计时"
android:textSize="30sp"
/>
public class DaojishiActivity extends AppCompatActivity {
private EditText timetext;
private TextView timepre;
private Button timebtn;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_daojishi);
bindID();
timebtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//把int类型转换成String类型,setText()只能是输出String类型
int time=Integer.parseInt(timetext.getText().toString());
new Mytask().execute(time);//启动AsyncTask任务
}
});
}
private void bindID() {
timebtn = findViewById(R.id.time_btn);
timetext=findViewById(R.id.time_text);
timepre=findViewById(R.id.time_pre);
}
class Mytask extends AsyncTask<Integer, Integer, String> {
//子线程,进行耗时工作
@Override
protected String doInBackground(Integer... Integer) {
for (int i=Integer[0];i>0;i--){
try {
Thread.sleep(1000);
publishProgress(i);//调用onProgressUpdate方法
} catch (InterruptedException e) {
e.printStackTrace();
}
}
return "计时结束";//计时结束后,返回
}
//被调用的次数是循环次数-1
//主线程,进度条更新,对UI界面进行更新
@Override
protected void onProgressUpdate(Integer... values) {
super.onProgressUpdate(values);
timepre.setText(values[0]+"");
// values是输出 publishProgress(i)穿的值
//利用publishProgress(i)进行主线程与子线程之间的信息交流
}
//被调用执行一次
//主线程,耗时工作进行后,
@Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
timepre.setText(s);//耗时工作之后,对button按钮进行进行更新传值
}
}
}
使用AsyncTask做进度条
<ProgressBar
android:layout_width="match_parent"
android:layout_height="wrap_content"
style="@style/Widget.AppCompat.ProgressBar.Horizontal"
android:id="@+id/progress_prg"
/>
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/progress_btn"
android:text="第一个"
android:textSize="30sp"
/>
public class JindutiaoActivity extends AppCompatActivity implements View.OnClickListener{
private Button probtn;
private ProgressBar progressBar;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_jindutiao);
bindID();
}
private void bindID() {
probtn = findViewById(R.id.progress_btn);
progressBar = findViewById(R.id.progress_prg);
probtn.setOnClickListener(this);
progressBar.setMax(10);//设置进度条最大值为10
}
@Override
public void onClick(View v) {
switch (v.getId()){
case R.id.progress_btn:
new MyTasks().execute();
break;
}
}
class MyTasks extends AsyncTask<Integer,Integer,Integer>{
@Override
protected Integer doInBackground(Integer... integers) {
for(int i=0;i<=10;i++){
try {
Thread.sleep(1000);
publishProgress(i);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
return null;
}
@Override
protected void onProgressUpdate(Integer... values) {
super.onProgressUpdate(values);
progressBar.setProgress(Integer.parseInt(values[0]+""));
}
@Override
protected void onPostExecute(Integer values) {
super.onPostExecute(values);
probtn.setText("下载完成");
}
}
}
######Execute()和ExecuteOnExector()区别
**execute方法:**启动异步任务后,AsyncTask中的方法会被系统逐一调用;它的下载任务是串行的,必须等第一个任务下载完毕后才能下载第二个。
**executeOnExecutor方法:**调用此方法,AsyncTask中的方法会被系统逐一调用,通常和THREAD_POOL_EXECUTOR一起使用,允许多个任务在由AsyncTask管理的线程池中并行执行,但是一次最多只能实现五个任务同时进行。
**ExecuteOnExector()实例演示:**
<ProgressBar
android:layout_width="match_parent"
android:layout_height="wrap_content"
style="@style/Widget.AppCompat.ProgressBar.Horizontal"
android:id="@+id/progress_prg1"
/>
<ProgressBar
android:layout_width="match_parent"
android:layout_height="wrap_content"
style="@style/Widget.AppCompat.ProgressBar.Horizontal"
android:id="@+id/progress_prg2"
/>
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/progress_btn1"
android:text="第一个"
android:textSize="30sp"
/>
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/progress_btn2"
android:text="第二个"
android:textSize="30sp"
/>```
public class Main5Activity extends AppCompatActivity implements View.OnClickListener{
private Button probtn1;
private Button probtn2;
private ProgressBar progressBar1;
private ProgressBar progressBar2;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main5);
bindID();
}
private void bindID() {
probtn1 = findViewById(R.id.progress_btn);
probtn2 = findViewById(R.id.progress_btn);
progressBar1 = findViewById(R.id.progress_prg);
progressBar2 = findViewById(R.id.progress_prg);
probtn1.setOnClickListener(this);
probtn2.setOnClickListener(this);
progressBar1.setMax(10);//设置进度条最大值为10
progressBar2.setMax(10);//设置进度条最大值为10
}
@Override
public void onClick(View v) {
switch (v.getId()){
case R.id.progress_btn1:
probtn1.setText("正在下载");
probtn1.setEnabled(false);
new Mytaskss().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR,1);
break;
case R.id.progress_btn2:
probtn2.setText("正在下载");
probtn2.setEnabled(false);
new Mytaskss().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR,2);//与execute有区别的地方
break;
}
}
class Mytaskss extends AsyncTask<Integer,Integer,Integer>{
@Override
protected Integer doInBackground(Integer... integers) {
int whichpb=integers[0];//用来判断哪一个按钮
for(int i=0;i<=10;i++){
try {
Thread.sleep(1000);
publishProgress(i,whichpb);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
return whichpb;
}
@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]);
}
}
@Override
protected void onPostExecute(Integer values) {
super.onPostExecute(values);
switch (integers){
case 1:
probtn1.setText("下载完成");
probtn1.setEnabled(true);
break;
case 2:
probtn2.setText("下载完成");
probtn2.setEnabled(true);
break;
}
}
}
}
“`
小结AsyncTask和Handle
怎么说呢,Handle在上学期简单的学过一次但当时不是很理解,这学期的学习过程中更加加深理解。AsyncTask相对来说比Handle简单一些,对于AsyncTask里面的方法和属性比Handle更加熟悉一些,可能是上课时听得比较认真吧。