基于HTTP协议的多线程下载,实现思路如下:
1.通过URL实例获取HTTPConnection;
2.根据HTTPConnection获取文件大小,通过文件大小,设置的线程数,计算每一个现场下载文件的起止Byte数。
3.在每个线程里,通过connection.setRequestProperty设置获取文件的Byte的起止位置。
4.线程中,获取到下载文件后,先在本地创建临时文件,通过seek方法设置文件偏置点,然后将下载文件流write到临时文件。
下面我们来看一下代码的实现:
MainActivity中没有多少操作:
MainActivity:
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import com.honey.two.utils.DialogUtils;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//这里做展示弹框以及功能操作
DialogUtils.showUpdataDialog(this);
}
}
下面再来看看DialogUtils:
import android.annotation.SuppressLint;
import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.SystemClock;
import com.honey.two.net.DownloadThread;
import java.io.File;
import java.io.IOException;
public class DialogUtils {
public static long MAX_SIZE = 0;
public static long PROGRESS = -2;
public static void showUpdataDialog(final Context context){
AlertDialog.Builder builder=new AlertDialog.Builder(context);
builder.setTitle("是否更新")
.setMessage("版本太低,建议更新")
.setNegativeButton("以后再说", null)
.setPositiveButton("立即更新", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
new DownloadThread("http://169.254.177.227:8080/tm/alipay_wap_main.apk", context.getCacheDir() + "/alipay_wap_main.apk").start();
showProgress(context);
}
}).show();
}
@SuppressLint("StaticFieldLeak")
public static void showProgress(final Context context){
final ProgressDialog pd = new ProgressDialog(context);
pd.setTitle("正在更新");
pd.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
pd.setMax(100);
pd.show();
new AsyncTask<String, Integer, String>(){
@Override
protected String doInBackground(String... strings) {
while (PROGRESS + 1 < MAX_SIZE){
SystemClock.sleep(100);
if(MAX_SIZE>0){
publishProgress((int)(PROGRESS * 100 / MAX_SIZE));
}
}
return null;
}
@Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
pd.dismiss();
//安装的思路
File file = new File(context.getCacheDir() +"/alipay_wap_main.apk");
String[] command = {"chmod", "777", file.getPath() };
ProcessBuilder builder = new ProcessBuilder(command);
try {
builder.start();
} catch (IOException e) {
e.printStackTrace();
}
Intent intent = new Intent(Intent.ACTION_VIEW);
// 由于没有在Activity环境下启动Activity,设置下面的标签
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.setDataAndType(Uri.fromFile(file), "application/vnd.android.package-archive");
context.startActivity(intent);
}
@Override
protected void onProgressUpdate(Integer... values) {
super.onProgressUpdate(values);
pd.setProgress(values[0]);
}
}.execute();
}
}
这是DownloadTask:
public class DownloadTask extends Thread{
String downloadUrl;
String path;
int blockSize;
int startPosition;
public DownloadTask(String downloadUrl, String path, int blockSize, int startPosition) {
this.downloadUrl = downloadUrl;
this.path = path;
this.blockSize = blockSize;
this.startPosition = startPosition;
}
@Override
public void run() {
NetUtils.downloadFile(downloadUrl,path,blockSize,startPosition);
}
}
这是DownloadThread:
import com.honey.two.utils.DialogUtils;
public class DownloadThread extends Thread{
private String downloadUrl = "";
private String path;
private int threadNum = 5;
public DownloadThread(String downloadUrl, String path) {
this.downloadUrl = downloadUrl;
this.path = path;
}
@Override
public void run() {
super.run();
int len=NetUtils.getFileLength(downloadUrl);
DialogUtils.MAX_SIZE = len;
//例如 1000kb 3 333
int blockSize = len/threadNum;
// //四舍五入--- 让一个数字+0。5在四舍五入 就变成 向上取整
// int blockSize = (int) Math.round(tempSize + 0.5);
//计算出下载块以后 创建线程执行下载操作
for (int i = 0; i < threadNum; i++) {
//计算开始位置
int startPosition = blockSize * i;
//让最后一个线程下载的大小是正好的, 总长度 - 除了最后一个块的大小和
if(i == threadNum - 1){
blockSize = len - blockSize * (threadNum - 1);
}
new DownloadTask(downloadUrl, path, blockSize, startPosition).start();
}
}
public void setThreadNum(int threadNum){
this.threadNum = threadNum;
}
}
这是NetUtils:
import android.util.Log;
import com.honey.two.utils.DialogUtils;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.net.HttpURLConnection;
import java.net.URL;
public class NetUtils {
public static void downloadFile(String downloadUrl, String path, int blockSize, int startPosition){
BufferedInputStream bis=null;
RandomAccessFile raf=null;
try {
File file=new File(path);
if (!file.exists()){
file.createNewFile();
}
URL url=new URL(downloadUrl);
Log.i("===download===", "downloadFile: "+downloadUrl);
HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.setReadTimeout(8000);
urlConnection.setConnectTimeout(8000);
if(blockSize>0){
long end = blockSize + startPosition - 1;
urlConnection.setRequestProperty("Range","bytes="+startPosition+"-"+end);
Log.i(Thread.currentThread() + "======", "bytes====" + startPosition + "-" + end);
}
int code=urlConnection.getResponseCode();
if(code<400){
bis=new BufferedInputStream(urlConnection.getInputStream());
raf=new RandomAccessFile(file,"rwd");
raf.seek(startPosition);
int len=0;
byte[] buff=new byte[1024*8];
while ((len=bis.read(buff))!=-1){
synchronized (NetUtils.class){
raf.write(buff,0,len);
if(DialogUtils.PROGRESS<0){
DialogUtils.PROGRESS=0;
}
DialogUtils.PROGRESS+=len;
}
}
}
} catch (Exception e) {
e.printStackTrace();
}finally {
if(bis!=null){
try {
bis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(raf!=null){
try {
raf.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
public static int getFileLength(String downloadUrl){
int len=0;
try {
URL url=new URL(downloadUrl);
HttpURLConnection connection= (HttpURLConnection) url.openConnection();
connection.setReadTimeout(8000);
connection.setConnectTimeout(8000);
len=connection.getContentLength();
} catch (Exception e) {
e.printStackTrace();
}
return len;
}
}
多线程下载,进度条,以及安装
最新推荐文章于 2024-06-20 23:24:22 发布