移动技术开发:HandlerAsyncTask
1 实验名称
Handler&AsyncTask
2 实验目的
掌握使用Handler消息传递机制和AsyncTask处理后台线程周期性的改变Activity中界面控件的属性
3 实验源代码
布局文件代码:
(1)HandlerTest
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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"
tools:context=".MainActivity"
android:id="@+id/constraintlayout"
>
</androidx.constraintlayout.widget.ConstraintLayout>
(2)AsyncTask
<?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:id="@+id/main"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity"
android:orientation="vertical"
>
<Button
android:id="@+id/downLoadBtn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="开始下载"
/>
<TextView
android:id="@+id/resultTv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="invisible"
/>
<ProgressBar
android:id="@+id/downLoadPb"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:visibility="invisible"
style="?android:attr/progressBarStyleHorizontal"
android:max="100"
/>
</LinearLayout>
Java代码:
(1)HandlerTest
package com.example.handlertest2;
import android.graphics.Color;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import androidx.activity.EdgeToEdge;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.constraintlayout.widget.ConstraintLayout;
import androidx.core.graphics.Insets;
import androidx.core.view.ViewCompat;
import androidx.core.view.WindowInsetsCompat;
public class MainActivity extends AppCompatActivity {
private ConstraintLayout constraintLayout = null;
private Handler handler = null;
private int [] colors = {Color.RED,Color.GREEN,Color.BLUE,Color.YELLOW,Color.MAGENTA};
private int currentIndex = 0;//当前颜色的下标
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
constraintLayout = findViewById(R.id.constraintlayout);
handler = new Handler(){
@Override
public void handleMessage(@NonNull Message msg) {
if (msg.what == 0x11){
currentIndex = (currentIndex+1)%colors.length;
constraintLayout.setBackgroundColor(colors[currentIndex]);
}
}
};start();
}
private void start(){
//创建一个每隔3秒钟就发送一个what值为0x11消息的子线程并运行起来
new Thread(){
@Override
public void run() {
while (true){
try {
Thread.sleep(3000);
handler.sendEmptyMessage(0x11);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}
}.start();
}
}
(2)AsyncTask
package com.example.asynctasktest;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.ProgressBar;
import android.widget.TextView;
import androidx.activity.EdgeToEdge;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.graphics.Insets;
import androidx.core.view.ViewCompat;
import androidx.core.view.WindowInsetsCompat;
public class MainActivity extends AppCompatActivity {
private Button downLoadBtn = null;
private TextView resultTv = null;
private ProgressBar downLoadPb = null;
//定义一个异步任务类的对象
private DownLoadAsyncTask downLoadAsyncTask = null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
downLoadBtn = findViewById(R.id.downLoadBtn);
resultTv = findViewById(R.id.resultTv);
downLoadPb = findViewById(R.id.downLoadPb);
downLoadBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//创建模拟下载的异步任务类的对象,调用带参数的构造方法获取到MainActivity中的三个控件的引用
downLoadAsyncTask = new DownLoadAsyncTask(downLoadBtn,resultTv,downLoadPb);
//启动模拟下载的异步任务
downLoadAsyncTask.execute(500);
}
});
}
}
(3)DownLoadAsyncTask
package com.example.asynctasktest;
import android.graphics.Color;
import android.os.AsyncTask;
import android.view.View;
import android.widget.Button;
import android.widget.ProgressBar;
import android.widget.TextView;
public class DownLoadAsyncTask extends AsyncTask<Integer,Integer,String> {
private Button downLoadBtn = null;
private TextView resultTv = null;
private ProgressBar downLoadPb = null;
public DownLoadAsyncTask(Button downLoadBtn, TextView resultTv, ProgressBar downLoadPb) {
this.downLoadBtn = downLoadBtn;
this.resultTv = resultTv;
this.downLoadPb = downLoadPb;
}
@Override
protected void onPreExecute() {
downLoadBtn.setText("正在下载中。。。");
downLoadBtn.setEnabled(false);//将按钮设置为不可用
resultTv.setVisibility(View.VISIBLE);//将文本框可见
resultTv.setTextSize(24);
resultTv.setTextColor(Color.BLUE);
downLoadPb.setVisibility(View.VISIBLE);//将进度条可见
}
@Override
protected String doInBackground(Integer... integers) {
//模拟下载,每隔一个时间下载1%
for (int i=0;i<101;i++){
try {
Thread.sleep(integers[0]);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
publishProgress(i);//发布异步任务的进度
}
return "下载完毕";
}
@Override
protected void onProgressUpdate(Integer... values) {
downLoadPb.setProgress(values[0]);//将publishProgress(i)方法中的i值设置为进度条的当前进度值
resultTv.setText("当前完成了任务的"+values[0]+"%");
}
@Override
protected void onPostExecute(String s) {
resultTv.setText(s);
downLoadBtn.setText("重新下载");
downLoadBtn.setEnabled(true);
}
}
4 实验运行结果图
5 实验总结
对于HandlerTest,保留文件初始布局文件,直接开始写Java代码。定义当前颜色的小标,创建一个每隔三秒钟就发送一个what值为0x11消息的子线程并运行起来。
对于AsyncTask,先写布局文件,再写Java代码。界面布局比较简洁,包括了一个下载按钮,一个文本框和一个下载进度条。
实现下载的过程中,先定义一个异步任务类的对象,然后创建模拟下载的异步任务类的对象,调用带参数的构造方法获取到三个控件的引用,最后启动模拟下载的异步任务;模拟下载过程中,设置每隔一个时间下载1%。