素材巴巴 > 程序开发 >

Android简单的异步下载文件更新进度条

程序开发 2023-09-15 06:10:42

我的整个操作在fragment中进行,与在活动中进行无异;

一、在xml中添加两个控件:按钮(用于开启下载操作),进度条(用于查看下载进度);

二、准备好所需常量(用于handler传递消息)以及下载链接;


 三、实例化控件对象,以及为按钮设置监听;

 点击按钮便开始进行下载操作,download方法用于进行下载操作,传入的形参为下载链接,由于下载方法内有相关网络操作,需放在线程中进行(线程通过Thread匿名内部类简单实现,由于并没有创建线程池,AS给出相应提示(冒黄线),但并不影响程序执行);


四、准备好handler对象,使用handler进行异步操作,并通过handler传送下载进度;

重写handler类的handMessage方法,用于接收download方法传来的消息,消息定义为两种:网络连接成功和网络连接失败;

DOWNLOAD_MESSAGE_CODE表示网络连接成功,DOWNLOAD_MESSAGE_FILE_CODE则表示传输失败

被注释掉的行为放在后面讲解;


五、实现download方法(核心),代码稍微有点长,但是细节慢慢、通俗易懂,请耐心观看!!!

private void download(String appUrl) {try {//创建URL对象URL url = new URL(appUrl);//获取URL连接对象URLConnection connection = url.openConnection();//获取连接的输入流对象InputStream inputStream = connection.getInputStream();//获取文件总长度int contentLength = connection.getContentLength();Log.d(TAG, "文件总长度: " + contentLength);/*getContext().getFilesDir()表示外部存储通过getAbsolutePath()获得外部存储路径File.separator表示分隔符 ""以下路径表示SD卡的”imooc“文件*///创建存储apk的目录文件路径String downloadFolderName = getContext().getFilesDir().getAbsolutePath()+ File.separator + "APP" + File.separator;//通过路径创建文件夹对象,用于存放apk文件File file = new File(downloadFolderName);//如果该目录文件不存在则创建if (!file.exists()){file.mkdir();}//在刚创建的文件下,创建文件名,用于存放下载的apkString fileName = downloadFolderName + "APP.apk";//定义一个下载的长度int downloadSize = 0;//用于传输文件byte[] bytes = new byte[1024];//用于判断int length = 0;/*OutputStream需要注意的细节:1、如何文件夹存在则先清空文件夹,如果不存在则创建,然后再写入(但如果目标文件所在的文件夹不存在,则抛出异常)2、如果目标文件已经存在,则会先清空文件中的数据,然后再写入新的数据*/OutputStream outputStream = new FileOutputStream(fileName,false);//读取数据while((length = inputStream.read(bytes)) != -1){outputStream.write(bytes,0,length);downloadSize += length;/*message对象可携带四个参数:what、arg1、arg2、obj;第一个参数为消息编码,整形。用于区分不同消息第二和第三都为整形参数,用于传输整形数据第四个为obj类型。可携带任意对象*///创建消息对象,用于发送进度值给主线程来更新UIMessage message = Message.obtain();//将下载进度比作为对象进行传输(由于我给进度条设置的最大值是一百,算出进度比,然后乘以100便是对应的进度值)message.obj = downloadSize * 100 /contentLength;message.what = DOWNLOAD_MESSAGE_CODE;//发送消息handler.sendMessage(message);}//关闭流inputStream.close();outputStream.close();} catch (MalformedURLException e) {notifyDownloadFile(e.getMessage());e.printStackTrace();} catch (IOException e) {notifyDownloadFile(e.getMessage());e.printStackTrace();}}
 

 该方法用于发送错误消息

protected void notifyDownloadFile(String error){Message message = Message.obtain();message.obj = error;message.what = DOWNLOAD_MESSAGE_FILE_CODE;handler.sendMessage(message);
 }

再回到接收消息的地方

switch (msg.what){//传输成功case DOWNLOAD_MESSAGE_CODE:// TODO: 设置进度条bar.setProgress((Integer) msg.obj);if (bar.getProgress() == 100){Toast.makeText(getActivity(),"下载完成",Toast.LENGTH_SHORT).show();bar.setProgress(0);}break;//传输失败case DOWNLOAD_MESSAGE_FILE_CODE:// TODO: 打印错误日志/*String Message = (String) msg.obj;Log.d(TAG, "ErrorMessage: " + Message);*/break;default:}

通过switch区分开消息类型,在下载的过程中,download方法会远远不断的向主线程发送消息,直到下载完成,而主线程(UI线程)则来完成进度条的加载操作;


六、最后一步,同时也是最最最不应该忘记的一步,在AndroidManifest.xml写入相关权限

 一个为网络访问权限,二为读文件权限,三为写文件权限;


七、!!!重要的事情说三遍

在Android9.0版本中,对网络安全有较高的要求,如果访问的是https协议则不受影响;

而若是访问了http协议的网站,则还需要添加安全配置文件,步骤如下:

1、创建安全配置文件

在res中创建一个xml目录,在此目录下新建一个”network_security_config"文件(文件名和内容不可修改),文件内容如下:


 
 

2、添加安全配置

在 AndroidManifest.xml添加该配置


标签:

素材巴巴 Copyright © 2013-2021 http://www.sucaibaba.com/. Some Rights Reserved. 备案号:备案中。