想必很多Android开发人员都在用一些很新型的网络框架,但再某些需求中,第三方的网络请求框架是需要修改才能实现(比如上传进度实现),这样导致不仅引入了框架,还要重写他的方法,项目的体积还变大(虽然大小是KB,但对于Android开发人员来说项目体积越小越好),言归正传我们首先建立一个Demo,建立一个类名为HttpUrlConnectionUtil工具类,先用单利模式把它改进一下,我这边使用的是(内部类式)单利模式,还有其他的单利模式,大家可以去尝试(这里我们简单看一下HttpUrlConnection的工作流程这样更方便开发)
image.png
HttpUrlConnection网络请求(get和post)
image.png接下来,创建线程池来管理线程,使用Handler来进行线程这间的转换,也可以不用Handler,但为了方便期间使用,接下来看看代码就知道了,这就就不过多的解释了,代码里面都有注释
import android.annotation.SuppressLint;
import android.os.Handler;
import android.os.Message;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Iterator;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class HttpUrlConnectionUtil {
private HttpUrlConnectionUtil() {
}
//创建线程池
private ExecutorService executorService = Executors.newCachedThreadPool();
private OnHttpUtilListener onHttpUtilListener;
private static class Holder {
private static HttpUrlConnectionUtil INSTANCE = new HttpUrlConnectionUtil();
}
public static HttpUrlConnectionUtil getInstance() {
return Holder.INSTANCE;
}
@SuppressLint("HandlerLeak")
private Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case 1:
//成功
onHttpUtilListener.onSuccess((String) msg.obj);
break;
case 2:
//错误
onHttpUtilListener.onError((String) msg.obj);
break;
case 3:
break;
}
}
};
public void get(OnHttpUtilListener onHttpUtilListener, final String urlPath) {
this.onHttpUtilListener = onHttpUtilListener;
Runnable runnable = new Runnable() {
@Override
public void run() {
HttpURLConnection connection = null;
InputStream inputStream = null;
try {
//获得URL对象
URL url = new URL(urlPath);
//返回一个URLConnection对象,它表示到URL所引用的远程对象的连接
connection = (HttpURLConnection) url.openConnection();
// 默认为GET
connection.setRequestMethod("GET");
//不使用缓存
connection.setUseCaches(false);
//设置超时时间
connection.setConnectTimeout(10000);
//设置读取超时时间
connection.setReadTimeout(10000);
//设置是否从httpUrlConnection读入,默认情况下是true;
connection.setDoInput(true);
//很多项目需要传入cookie解开注释(自行修改)
// connection.setRequestProperty("Cookie", "my_cookie");
//相应码是否为200
if (connection.getResponseCode() == HttpURLConnection.HTTP_OK) {
//获得输入流
inputStream = connection.getInputStream();
//包装字节流为字符流
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
StringBuilder response = new StringBuilder();
String line;
while ((line = reader.readLine()) != null) {
response.append(line);
}
//这块是获取服务器返回的cookie(自行修改)
// String cookie = connection.getHeaderField("set-cookie");
//通过handler更新UI
Message message = handler.obtainMessage();
message.obj = response.toString();
message.what = 1;
handler.sendMessage(message);
} else {
Message message = handler.obtainMessage();
message.obj = String.valueOf(connection.getResponseCode());
message.what = 2;
handler.sendMessage(message);
}
} catch (Exception e) {
e.printStackTrace();
Message message = handler.obtainMessage();
message.obj = e.getMessage();
message.what = 2;
handler.sendMessage(message);
} finally {
if (connection != null) {
connection.disconnect();
}
//关闭读写流
if (inputStream != null) {
try {
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
};
//加入线程池
executorService.execute(runnable);
}
public void post(OnHttpUtilListener onHttpUtilListener, final String urlPath, final Map<String, String> params) {
this.onHttpUtilListener = onHttpUtilListener;
Runnable runnable = new Runnable() {
@Override
public void run() {
HttpURLConnection connection = null;
InputStream inputStream = null;
OutputStream outputStream = null;
StringBuffer body = getParamString(params);
byte[] data = body.toString().getBytes();
try {
//获得URL对象
URL url = new URL(urlPath);
//返回一个URLConnection对象,它表示到URL所引用的远程对象的连接
connection = (HttpURLConnection) url.openConnection();
// 默认为GET
connection.setRequestMethod("POST");
//不使用缓存
connection.setUseCaches(false);
//设置超时时间
connection.setConnectTimeout(10000);
//设置读取超时时间
connection.setReadTimeout(10000);
//设置是否从httpUrlConnection读入,默认情况下是true;
connection.setDoInput(true);
//设置为true后才能写入参数
connection.setDoOutput(true);
//post请求需要设置标头
connection.setRequestProperty("Connection", "Keep-Alive");
connection.setRequestProperty("Charset", "UTF-8");
//表单参数类型标头
connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
//很多项目需要传入cookie解开注释(自行修改)
// connection.setRequestProperty("Cookie", "my_cookie");
//获取写入流
outputStream=connection.getOutputStream();
//写入表单参数
outputStream.write(data);
//相应码是否为200
if (connection.getResponseCode() == HttpURLConnection.HTTP_OK) {
//获得输入流
inputStream = connection.getInputStream();
//包装字节流为字符流
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
StringBuilder response = new StringBuilder();
String line;
while ((line = reader.readLine()) != null) {
response.append(line);
}
//这块是获取服务器返回的cookie(自行修改)
// String cookie = connection.getHeaderField("set-cookie");
//通过handler更新UI
Message message = handler.obtainMessage();
message.obj = response.toString();
message.what = 1;
handler.sendMessage(message);
} else {
Message message = handler.obtainMessage();
message.obj = String.valueOf(connection.getResponseCode());
message.what = 2;
handler.sendMessage(message);
}
} catch (Exception e) {
e.printStackTrace();
Message message = handler.obtainMessage();
message.obj = e.getMessage();
message.what = 2;
handler.sendMessage(message);
} finally {
if (connection != null) {
connection.disconnect();
}
//关闭读写流
if (inputStream != null) {
try {
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
};
//加入线程池
executorService.execute(runnable);
}
//post请求参数
private StringBuffer getParamString(Map<String, String> params){
StringBuffer result = new StringBuffer();
Iterator<Map.Entry<String, String>> iterator = params.entrySet().iterator();
while (iterator.hasNext()){
Map.Entry<String, String> param = iterator.next();
String key = param.getKey();
String value = param.getValue();
result.append(key).append('=').append(value);
if (iterator.hasNext()){
result.append('&');
}
}
return result;
}
//回调接口
interface OnHttpUtilListener {
void onError(String e);
void onSuccess(String json);
}
}
里面还可以继续提取封装,这里我就不操作了,有兴趣的朋友,可以进化代码。
接下来看看如果使用
image.png
用起来很简单对不对,也可以用泛型封装,再用第三方Gson,这样在项目用起来很方便的。既然简单请求已经上手了,那我进阶一下吧,估计下面才是大家想找到东西~~~。
HttpUrlConnection上传进度(分块上传)和下载进度
既然说到上传下载我们必然离不开异步,这里我们就不使用Handler虽然它很强大也可以实现,但我们有更方便的解决方案。那就是AsyncTask用它来实现线程直接的调度
接下来需要创建一个类名为HttpUrlConnectionAsyncTask工具类,代码如下
import android.os.AsyncTask;
import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.math.BigDecimal;
import java.net.HttpURLConnection;
import java.net.URL;
/**
* 括号里的类型
* 第一个代表doInBackground方法需要传入的类型
* 第二个代表onProgressUpdate方法需要传入的类型
* 第一个代表onPostExecute方法需要传入的类型
*/
public class HttpUrlConnectionAsyncTask extends AsyncTask<Integer, Integer, String> {
private Integer UPLOAD = 1;
private OnHttpProgressUtilListener onHttpProgressUtilListener;
private String urlPath;
private String filePath;
public void uploadFile(OnHttpProgressUtilListener onHttpProgressUtilListener, String urlPath, String filePath) {
this.urlPath = urlPath;
this.filePath = filePath;
//调用doInBackground方法(方法里面是异步执行)
execute(UPLOAD);
}
public void downloadFile(OnHttpProgressUtilListener onHttpProgressUtilListener, String urlPath, String filePath) {
this.urlPath = urlPath;
this.filePath = filePath;
//调用doInBackground方法(方法里面是异步执行)
execute(2);
}
@Override
protected String doInBackground(Integer... integers) {
return integers[0].equals(UPLOAD) ? upload() : download();
}
private String upload() {
HttpURLConnection connection = null;
InputStream inputStream = null;
OutputStream outputStream = null;
File file = new File(filePath);
String result = "";
try {
//获得URL对象
URL url = new URL(urlPath);
//返回一个URLConnection对象,它表示到URL所引用的远程对象的连接
connection = (HttpURLConnection) url.openConnection();
// 默认为GET
connection.setRequestMethod("POST");
//不使用缓存
connection.setUseCaches(false);
//设置超时时间
connection.setConnectTimeout(10000);
//设置读取超时时间
connection.setReadTimeout(10000);
//设置是否从httpUrlConnection读入,默认情况下是true;
connection.setDoInput(true);
//设置为true后才能写入参数
connection.setDoOutput(true);
//设置为true后才能写入参数
connection.setRequestProperty("Content-Type", "multipart/form-data");
connection.setRequestProperty("Content-Length", String.valueOf(file.length()));
outputStream = new DataOutputStream(connection.getOutputStream());
DataInputStream dataInputStream = new DataInputStream(new FileInputStream(file));
int count = 0;
// 计算上传进度
Long progress = 0L;
byte[] bufferOut = new byte[2048];
while ((count = dataInputStream.read(bufferOut)) != -1) {
outputStream.write(bufferOut, 0, count);
progress += count;
//换算进度
double d = (new BigDecimal(progress / (double) file.length()).setScale(2, BigDecimal.ROUND_HALF_UP)).doubleValue();
double d1 = d * 100;
//传入的值为1-100
onProgressUpdate((int) d1);
}
dataInputStream.close();
//写入参数
if (connection.getResponseCode()==HttpURLConnection.HTTP_OK){
//获得输入流
inputStream = connection.getInputStream();
//包装字节流为字符流
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
StringBuilder response = new StringBuilder();
String line;
while ((line = reader.readLine()) != null) {
response.append(line);
}
result=response.toString();
}else {
result = String.valueOf(connection.getResponseCode());
}
} catch (Exception e) {
e.printStackTrace();
onCancelled(e.getMessage());
} finally {
//关闭
if (outputStream != null) {
try {
outputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (inputStream != null) {
try {
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (connection != null) {
connection.disconnect();
}
}
return result;
}
private String download() {
HttpURLConnection connection = null;
InputStream inputStream = null;
OutputStream outputStream = null;
String result = "";
try {
//获得URL对象
URL url = new URL(urlPath);
//返回一个URLConnection对象,它表示到URL所引用的远程对象的连接
connection = (HttpURLConnection) url.openConnection();
//建立实际链接
connection.connect();
inputStream=connection.getInputStream();
//获取文件长度
Double size = (double) connection.getContentLength();
outputStream = new FileOutputStream(filePath);
int count = 0;
// 计算上传进度
Long progress = 0L;
byte[] bytes= new byte[2048];
while ((count=inputStream.read(bytes))!=-1){
outputStream.write(bytes,0,count);
//换算进度
double d = (new BigDecimal(progress / size).setScale(2, BigDecimal.ROUND_HALF_UP)).doubleValue();
double d1 = d * 100;
//传入的值为1-100
onProgressUpdate((int) d1);
}
result = "下载成功";
} catch (Exception e) {
e.printStackTrace();
onCancelled(e.getMessage());
} finally {
//关闭
if (outputStream != null) {
try {
outputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (inputStream != null) {
try {
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (connection != null) {
connection.disconnect();
}
}
return result;
}
@Override
protected void onProgressUpdate(Integer... values) {
super.onProgressUpdate(values);
onHttpProgressUtilListener.onProgress(values[0]);
}
@Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
onHttpProgressUtilListener.onSuccess(s);
}
@Override
protected void onCancelled(String s) {
super.onCancelled(s);
onHttpProgressUtilListener.onError(s);
}
interface OnHttpProgressUtilListener {
void onError(String e);
void onProgress(Integer length);
void onSuccess(String json);
}
}
上传和下载已经分装好了,在进度换算中这里面需要注意,因为用Double类型比较好换算进度,BigDecimal保留了两位小数,
代码里,doInBackground是异步执行的,onPostExecute(上传和下载结果)和onProgressUpdate(上传和下载进度)它是调度到主线程了。下面我们来说说分块上传该怎么实现,因为在上传项目中有一些大的项目,服务器那边做了可以分块上传,这个时候Android该怎么实现上传。
HttpUrlConnection分块上传
首先需要一个方法来处理分块
private byte[] getBlock(Long offset, File file, int blockSize) {
byte[] result = new byte[blockSize];
RandomAccessFile accessFile = null;
try {
accessFile = new RandomAccessFile(file, "r");
//将文件记录指针定位到pos位置
accessFile.seek(offset);
int readSize = accessFile.read(result);
if (readSize == -1) {
return null;
} else if (readSize == blockSize) {
return result;
} else {
byte[] tmpByte = new byte[readSize];
System.arraycopy(result, 0, tmpByte, 0, readSize);
return tmpByte;
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (accessFile != null) {
try {
accessFile.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return null;
}
这里参数offset记录文件上一次读写的位置,blockSize代表每块大小,接下来咱们看看如果实现网络请求
private String filePath;
private byte[] data;
public void uploadFileBlock(OnHttpProgressUtilListener onHttpProgressUtilListener, String urlPath, byte[] data) {
this.urlPath = urlPath;
this.data = data;
//调用doInBackground方法(方法里面是异步执行)
}
private String uploadBlock() {
HttpURLConnection connection = null;
InputStream inputStream = null;
OutputStream outputStream = null;
String result = "";
try {
//获得URL对象
URL url = new URL(urlPath);
//返回一个URLConnection对象,它表示到URL所引用的远程对象的连接
connection = (HttpURLConnection) url.openConnection();
// 默认为GET
connection.setRequestMethod("POST");
//不使用缓存
connection.setUseCaches(false);
//设置超时时间
connection.setConnectTimeout(10000);
//设置读取超时时间
connection.setReadTimeout(10000);
//设置是否从httpUrlConnection读入,默认情况下是true;
connection.setDoInput(true);
//设置为true后才能写入参数
connection.setDoOutput(true);
//设置为true后才能写入参数
connection.setRequestProperty("Content-Type", "multipart/form-data");
//这里需要改动
connection.setRequestProperty("Content-Length", String.valueOf(data.length));
outputStream = new DataOutputStream(connection.getOutputStream());
//这块需要改为ByteArrayInputStream写入流
ByteArrayInputStream inputStreamByte = new ByteArrayInputStream(data);
int count = 0;
// 计算上传进度
Integer progress = 0;
byte[] bufferOut = new byte[2048];
while ((count = inputStreamByte.read(bufferOut)) != -1) {
outputStream.write(bufferOut, 0, count);
progress += count;
onProgressUpdate(progress);
}
inputStreamByte.close();
//写入参数
if (connection.getResponseCode() == HttpURLConnection.HTTP_OK) {
//获得输入流
inputStream = connection.getInputStream();
//包装字节流为字符流
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
StringBuilder response = new StringBuilder();
String line;
while ((line = reader.readLine()) != null) {
response.append(line);
}
result = response.toString();
} else {
result = String.valueOf(connection.getResponseCode());
}
} catch (Exception e) {
e.printStackTrace();
onCancelled(e.getMessage());
} finally {
//关闭
if (outputStream != null) {
try {
outputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (inputStream != null) {
try {
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (connection != null) {
connection.disconnect();
}
}
return result;
}
这里我们传的是byte[]而不是文件路径了,我们下面看看整个类变成什么样了
import android.os.AsyncTask;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.math.BigDecimal;
import java.net.HttpURLConnection;
import java.net.URL;
/**
* 括号里的类型
* 第一个代表doInBackground方法需要传入的类型
* 第二个代表onProgressUpdate方法需要传入的类型
* 第一个代表onPostExecute方法需要传入的类型
*/
public class HttpUrlConnectionAsyncTask extends AsyncTask<Integer, Integer, String> {
private Integer UPLOAD = 1;
private Integer DOWNLOAD = 2;
private OnHttpProgressUtilListener onHttpProgressUtilListener;
private String urlPath;
private String filePath;
private byte[] data;
public void uploadFileBlock(OnHttpProgressUtilListener onHttpProgressUtilListener, String urlPath, byte[] data) {
this.urlPath = urlPath;
this.data = data;
//调用doInBackground方法(方法里面是异步执行)
execute(UPLOAD);
}
public void uploadFile(OnHttpProgressUtilListener onHttpProgressUtilListener, String urlPath, String filePath) {
this.urlPath = urlPath;
this.filePath = filePath;
//调用doInBackground方法(方法里面是异步执行)
execute(UPLOAD);
}
public void downloadFile(OnHttpProgressUtilListener onHttpProgressUtilListener, String urlPath, String filePath) {
this.urlPath = urlPath;
this.filePath = filePath;
//调用doInBackground方法(方法里面是异步执行)
execute(2);
}
@Override
protected String doInBackground(Integer... integers) {
String result;
if (integers[0].equals(UPLOAD)) {
result = upload();
} else if (integers[0].equals(DOWNLOAD)) {
result = download();
} else {
result = uploadBlock();
}
return result;
}
private String upload() {
HttpURLConnection connection = null;
InputStream inputStream = null;
OutputStream outputStream = null;
File file = new File(filePath);
String result = "";
try {
//获得URL对象
URL url = new URL(urlPath);
//返回一个URLConnection对象,它表示到URL所引用的远程对象的连接
connection = (HttpURLConnection) url.openConnection();
// 默认为GET
connection.setRequestMethod("POST");
//不使用缓存
connection.setUseCaches(false);
//设置超时时间
connection.setConnectTimeout(10000);
//设置读取超时时间
connection.setReadTimeout(10000);
//设置是否从httpUrlConnection读入,默认情况下是true;
connection.setDoInput(true);
//设置为true后才能写入参数
connection.setDoOutput(true);
//设置为true后才能写入参数
connection.setRequestProperty("Content-Type", "multipart/form-data");
connection.setRequestProperty("Content-Length", String.valueOf(file.length()));
outputStream = new DataOutputStream(connection.getOutputStream());
DataInputStream dataInputStream = new DataInputStream(new FileInputStream(file));
int count = 0;
// 计算上传进度
Long progress = 0L;
byte[] bufferOut = new byte[2048];
while ((count = dataInputStream.read(bufferOut)) != -1) {
outputStream.write(bufferOut, 0, count);
progress += count;
//换算进度
double d = (new BigDecimal(progress / (double) file.length()).setScale(2, BigDecimal.ROUND_HALF_UP)).doubleValue();
double d1 = d * 100;
//传入的值为1-100
onProgressUpdate((int) d1);
}
dataInputStream.close();
//写入参数
if (connection.getResponseCode() == HttpURLConnection.HTTP_OK) {
//获得输入流
inputStream = connection.getInputStream();
//包装字节流为字符流
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
StringBuilder response = new StringBuilder();
String line;
while ((line = reader.readLine()) != null) {
response.append(line);
}
result = response.toString();
} else {
result = String.valueOf(connection.getResponseCode());
}
} catch (Exception e) {
e.printStackTrace();
onCancelled(e.getMessage());
} finally {
//关闭
if (outputStream != null) {
try {
outputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (inputStream != null) {
try {
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (connection != null) {
connection.disconnect();
}
}
return result;
}
private String uploadBlock() {
HttpURLConnection connection = null;
InputStream inputStream = null;
OutputStream outputStream = null;
String result = "";
try {
//获得URL对象
URL url = new URL(urlPath);
//返回一个URLConnection对象,它表示到URL所引用的远程对象的连接
connection = (HttpURLConnection) url.openConnection();
// 默认为GET
connection.setRequestMethod("POST");
//不使用缓存
connection.setUseCaches(false);
//设置超时时间
connection.setConnectTimeout(10000);
//设置读取超时时间
connection.setReadTimeout(10000);
//设置是否从httpUrlConnection读入,默认情况下是true;
connection.setDoInput(true);
//设置为true后才能写入参数
connection.setDoOutput(true);
//设置为true后才能写入参数
connection.setRequestProperty("Content-Type", "multipart/form-data");
//这里需要改动
connection.setRequestProperty("Content-Length", String.valueOf(data.length));
outputStream = new DataOutputStream(connection.getOutputStream());
//这块需要改为ByteArrayInputStream写入流
ByteArrayInputStream inputStreamByte = new ByteArrayInputStream(data);
int count = 0;
// 计算上传进度
Integer progress = 0;
byte[] bufferOut = new byte[2048];
while ((count = inputStreamByte.read(bufferOut)) != -1) {
outputStream.write(bufferOut, 0, count);
progress += count;
onProgressUpdate(progress);
}
inputStreamByte.close();
//写入参数
if (connection.getResponseCode() == HttpURLConnection.HTTP_OK) {
//获得输入流
inputStream = connection.getInputStream();
//包装字节流为字符流
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
StringBuilder response = new StringBuilder();
String line;
while ((line = reader.readLine()) != null) {
response.append(line);
}
result = response.toString();
} else {
result = String.valueOf(connection.getResponseCode());
}
} catch (Exception e) {
e.printStackTrace();
onCancelled(e.getMessage());
} finally {
//关闭
if (outputStream != null) {
try {
outputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (inputStream != null) {
try {
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (connection != null) {
connection.disconnect();
}
}
return result;
}
private String download() {
HttpURLConnection connection = null;
InputStream inputStream = null;
OutputStream outputStream = null;
String result = "";
try {
//获得URL对象
URL url = new URL(urlPath);
//返回一个URLConnection对象,它表示到URL所引用的远程对象的连接
connection = (HttpURLConnection) url.openConnection();
//建立实际链接
connection.connect();
inputStream = connection.getInputStream();
//获取文件长度
Double size = (double) connection.getContentLength();
outputStream = new FileOutputStream(filePath);
int count = 0;
// 计算上传进度
Long progress = 0L;
byte[] bytes = new byte[2048];
while ((count = inputStream.read(bytes)) != -1) {
outputStream.write(bytes, 0, count);
//换算进度
double d = (new BigDecimal(progress / size).setScale(2, BigDecimal.ROUND_HALF_UP)).doubleValue();
double d1 = d * 100;
//传入的值为1-100
onProgressUpdate((int) d1);
}
result = "下载成功";
} catch (Exception e) {
e.printStackTrace();
onCancelled(e.getMessage());
} finally {
//关闭
if (outputStream != null) {
try {
outputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (inputStream != null) {
try {
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (connection != null) {
connection.disconnect();
}
}
return result;
}
@Override
protected void onProgressUpdate(Integer... values) {
super.onProgressUpdate(values);
onHttpProgressUtilListener.onProgress(values[0]);
}
@Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
onHttpProgressUtilListener.onSuccess(s);
}
@Override
protected void onCancelled(String s) {
super.onCancelled(s);
onHttpProgressUtilListener.onError(s);
}
interface OnHttpProgressUtilListener {
void onError(String e);
void onProgress(Integer length);
void onSuccess(String json);
}
}
下面我们看看如果使用分块上传,使用分块上传必须服务器支持分块上传才可以
int chuncks=0;//流块
double chunckProgress=0.0;//进度
private void upload(){
//每一块大小
int blockLength=1024*1024*2;
File file = new File("文件路径");
final long fileSize=file.length();
//当前第几块
int chunck = 0;
//换算总共分多少块
if (file.length() % blockLength == 0L) {
chuncks= (int) (file.length() / blockLength);
} else {
chuncks= (int) (file.length()/ blockLength + 1);
}
while (chunck<chuncks){
//换算出第几块的byte[]
byte[] block = getBlock((long) (chunck * blockLength), file, blockLength);
new HttpUrlConnectionAsyncTask().uploadFileBlock(new HttpUrlConnectionAsyncTask.OnHttpProgressUtilListener() {
@Override
public void onError(String e) {
}
@Override
public void onProgress(Integer progress) {
//换算进度
double d = (new BigDecimal(progress / fileSize).setScale(2, BigDecimal.ROUND_HALF_UP)).doubleValue();
int pro= (int) (d*100);
//这个就是上传进度,已经换算为1-100
Log.d(TAG, "onProgress: "+pro);
}
@Override
public void onSuccess(String json) {
//上传成功
}
},"上传URL 需要传入当前块chunck和总块数chuncks参数,需接口支持才行",block);
chunck++;
}
}
这样就上传成功了,以后遇到上传下载都可以这样用,但也可以选择第三方网络请求框架,各有所长
这个是项目地址大家可以作为参考
git :https://github.com/GuoLiangGod/HttpUrlConnectionDemo
这篇文件,希望对大家又帮助,如果遇到问题可以留言
网友评论