本次实验我们使用该方法从网络上下载一个文件并同步显示下载状态(等待下载,正在下载中,下载完成)

效果图
效果图

本次实验代码大部分与上一个实验相同(『Android Studio』AsyncTask异步类的功能和用法)只需要将上一个的实验代码做少许修改即可,进一步巩固AsyncTask异步类的使用。
运行环境

  • Windows 10
  • Android Studio Arctic Fox (2020.3.1)
  • jdk1.7.0_67

1.在布局文件中新建TextView,ProgressBar,Button三个控件。(我的布局文件采用线性布局。)

<TextView
        android:id="@+id/tv"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:textSize="18sp"
        android:text="等待下载"/>

    <ProgressBar
        android:id="@+id/pb"
        style="@style/Widget.AppCompat.ProgressBar.Horizontal"
        android:layout_width="match_parent"
        android:layout_height="30dp" />
    <Button
        android:id="@+id/btn"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Download"/>

ProgressBar即进度条,style="@style/Widget.AppCompat.ProgressBar.Horizontal"表示将进度条设置为线性,默认风格为圆圈类型。

2.在上次实验中MainActivity的基础上修改以下内容

①声明变量

private Button btn;
    private ProgressBar pb;
    private TextView tv;
    private String url="";

②对声明的变量设置监听(btn,pb,tv)

private void initView(){
        pb=(ProgressBar)findViewById(R.id.pb);
        tv=(TextView)findViewById(R.id.tv);
        btn=(Button)findViewById(R.id.btn);
        btn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                FileDownTask task=new FileDownTask(pb,tv);
                task.execute(url);
            }
        });
    }

FileDownTask task=new FileDownTask(pb,tv);不能漏掉pb和tv变量,否则会有空指针报错。

3.新建一个 Java Class,命名为FileDownTask.java

继承 Async­Task,并声明变量

public class FileDownTask extends AsyncTask<String, Integer, String> {
    private ProgressBar pb;
    private TextView tv;
    ......
    }

对pb,tv进行初始化,我这里直接使用通过构造方法进行依赖注入。

public FileDownTask(ProgressBar pb,TextView tv) {
        this.pb=pb;
        this.tv=tv;
    }

4.定义下载功能(后台处理逻辑)

@Override
    protected String doInBackground(String... strings) {
        String str=null;
        try {
            URL url=new URL(strings[0]);
            HttpURLConnection coon=(HttpURLConnection) url.openConnection();
            int totalsize=coon.getContentLength();
            int currentsize=0;
            InputStream is=coon.getInputStream();
            byte[] buffer=new byte[2048];
            int length=0;
            while((length=is.read(buffer))!=-1){
                currentsize=currentsize+length;
                publishProgress((int) ((float)currentsize/totalsize*100));

            }
            is.close();
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return "下载完成";
    }

这里不需要跟上一个实验一样加缓冲流,所以也不需要将缓冲流封装。
以下两行代码多余
BufferedInputStream bis=new BufferedInputStream(is);
bmp = BitmapFactory.decodeStream(bis);

进度条的更新

@Override
    protected void onProgressUpdate(Integer... values) {
        super.onProgressUpdate(values);
        pb.setProgress(values[0]);
        tv.setText("正在下载中...");
    }

下载完成提示

@Override
    protected void onPostExecute(String s) {
        super.onPostExecute(s);
        tv.setText(s);
    }

5.开启联网权限

20211019134156.jpg
20211019134156.jpg

如果不开启联网权限点击下载按钮就会闪退
在项目目录中点击manifests,选择AndroidManifest.xml,在<application ··· </application>标签后添加如下代码

<uses-permission android:name="android.permission.INTERNET"/>

<application ··· </application>标签内添加如下代码

android:usesCleartextTraffic="true"

完整代码下载连接