想必很多Android開發(fā)人員都在用一些很新型的網(wǎng)絡(luò)框架镰吵,但再某些需求中,第三方的網(wǎng)絡(luò)請求框架是需要修改才能實(shí)現(xiàn)(比如上傳進(jìn)度實(shí)現(xiàn))旺入,這樣導(dǎo)致不僅引入了框架兑凿,還要重寫他的方法,項(xiàng)目的體積還變大(雖然大小是KB茵瘾,但對于Android開發(fā)人員來說項(xiàng)目體積越小越好)礼华,言歸正傳我們首先建立一個(gè)Demo,建立一個(gè)類名為HttpUrlConnectionUtil工具類拗秘,先用單利模式把它改進(jìn)一下圣絮,我這邊使用的是(內(nèi)部類式)單利模式,還有其他的單利模式雕旨,大家可以去嘗試(這里我們簡單看一下HttpUrlConnection的工作流程這樣更方便開發(fā))
HttpUrlConnection網(wǎng)絡(luò)請求(get和post)
接下來扮匠,創(chuàng)建線程池來管理線程捧请,使用Handler來進(jìn)行線程這間的轉(zhuǎn)換,也可以不用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() {
}
//創(chuàng)建線程池
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:
//錯(cuò)誤
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);
//返回一個(gè)URLConnection對象可款,它表示到URL所引用的遠(yuǎn)程對象的連接
connection = (HttpURLConnection) url.openConnection();
// 默認(rèn)為GET
connection.setRequestMethod("GET");
//不使用緩存
connection.setUseCaches(false);
//設(shè)置超時(shí)時(shí)間
connection.setConnectTimeout(10000);
//設(shè)置讀取超時(shí)時(shí)間
connection.setReadTimeout(10000);
//設(shè)置是否從httpUrlConnection讀入,默認(rèn)情況下是true;
connection.setDoInput(true);
//很多項(xiàng)目需要傳入cookie解開注釋(自行修改)
// connection.setRequestProperty("Cookie", "my_cookie");
//相應(yīng)碼是否為200
if (connection.getResponseCode() == HttpURLConnection.HTTP_OK) {
//獲得輸入流
inputStream = connection.getInputStream();
//包裝字節(jié)流為字符流
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
StringBuilder response = new StringBuilder();
String line;
while ((line = reader.readLine()) != null) {
response.append(line);
}
//這塊是獲取服務(wù)器返回的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();
}
//關(guān)閉讀寫流
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);
//返回一個(gè)URLConnection對象克蚂,它表示到URL所引用的遠(yuǎn)程對象的連接
connection = (HttpURLConnection) url.openConnection();
// 默認(rèn)為GET
connection.setRequestMethod("POST");
//不使用緩存
connection.setUseCaches(false);
//設(shè)置超時(shí)時(shí)間
connection.setConnectTimeout(10000);
//設(shè)置讀取超時(shí)時(shí)間
connection.setReadTimeout(10000);
//設(shè)置是否從httpUrlConnection讀入闺鲸,默認(rèn)情況下是true;
connection.setDoInput(true);
//設(shè)置為true后才能寫入?yún)?shù)
connection.setDoOutput(true);
//post請求需要設(shè)置標(biāo)頭
connection.setRequestProperty("Connection", "Keep-Alive");
connection.setRequestProperty("Charset", "UTF-8");
//表單參數(shù)類型標(biāo)頭
connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
//很多項(xiàng)目需要傳入cookie解開注釋(自行修改)
// connection.setRequestProperty("Cookie", "my_cookie");
//獲取寫入流
outputStream=connection.getOutputStream();
//寫入表單參數(shù)
outputStream.write(data);
//相應(yīng)碼是否為200
if (connection.getResponseCode() == HttpURLConnection.HTTP_OK) {
//獲得輸入流
inputStream = connection.getInputStream();
//包裝字節(jié)流為字符流
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
StringBuilder response = new StringBuilder();
String line;
while ((line = reader.readLine()) != null) {
response.append(line);
}
//這塊是獲取服務(wù)器返回的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();
}
//關(guān)閉讀寫流
if (inputStream != null) {
try {
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
};
//加入線程池
executorService.execute(runnable);
}
//post請求參數(shù)
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;
}
//回調(diào)接口
interface OnHttpUtilListener {
void onError(String e);
void onSuccess(String json);
}
}
里面還可以繼續(xù)提取封裝,這里我就不操作了埃叭,有興趣的朋友摸恍,可以進(jìn)化代碼。
接下來看看如果使用
用起來很簡單對不對游盲,也可以用泛型封裝误墓,再用第三方Gson,這樣在項(xiàng)目用起來很方便的益缎。既然簡單請求已經(jīng)上手了谜慌,那我進(jìn)階一下吧,估計(jì)下面才是大家想找到東西~~~莺奔。
HttpUrlConnection上傳進(jìn)度(分塊上傳)和下載進(jìn)度
既然說到上傳下載我們必然離不開異步欣范,這里我們就不使用Handler雖然它很強(qiáng)大也可以實(shí)現(xiàn),但我們有更方便的解決方案令哟。那就是AsyncTask用它來實(shí)現(xiàn)線程直接的調(diào)度
接下來需要?jiǎng)?chuàng)建一個(gè)類名為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;
/**
* 括號里的類型
* 第一個(gè)代表doInBackground方法需要傳入的類型
* 第二個(gè)代表onProgressUpdate方法需要傳入的類型
* 第一個(gè)代表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;
//調(diào)用doInBackground方法(方法里面是異步執(zhí)行)
execute(UPLOAD);
}
public void downloadFile(OnHttpProgressUtilListener onHttpProgressUtilListener, String urlPath, String filePath) {
this.urlPath = urlPath;
this.filePath = filePath;
//調(diào)用doInBackground方法(方法里面是異步執(zhí)行)
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);
//返回一個(gè)URLConnection對象,它表示到URL所引用的遠(yuǎn)程對象的連接
connection = (HttpURLConnection) url.openConnection();
// 默認(rèn)為GET
connection.setRequestMethod("POST");
//不使用緩存
connection.setUseCaches(false);
//設(shè)置超時(shí)時(shí)間
connection.setConnectTimeout(10000);
//設(shè)置讀取超時(shí)時(shí)間
connection.setReadTimeout(10000);
//設(shè)置是否從httpUrlConnection讀入屏富,默認(rèn)情況下是true;
connection.setDoInput(true);
//設(shè)置為true后才能寫入?yún)?shù)
connection.setDoOutput(true);
//設(shè)置為true后才能寫入?yún)?shù)
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;
// 計(jì)算上傳進(jìn)度
Long progress = 0L;
byte[] bufferOut = new byte[2048];
while ((count = dataInputStream.read(bufferOut)) != -1) {
outputStream.write(bufferOut, 0, count);
progress += count;
//換算進(jìn)度
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();
//寫入?yún)?shù)
if (connection.getResponseCode()==HttpURLConnection.HTTP_OK){
//獲得輸入流
inputStream = connection.getInputStream();
//包裝字節(jié)流為字符流
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 {
//關(guān)閉
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);
//返回一個(gè)URLConnection對象晴竞,它表示到URL所引用的遠(yuǎn)程對象的連接
connection = (HttpURLConnection) url.openConnection();
//建立實(shí)際鏈接
connection.connect();
inputStream=connection.getInputStream();
//獲取文件長度
Double size = (double) connection.getContentLength();
outputStream = new FileOutputStream(filePath);
int count = 0;
// 計(jì)算上傳進(jìn)度
Long progress = 0L;
byte[] bytes= new byte[2048];
while ((count=inputStream.read(bytes))!=-1){
outputStream.write(bytes,0,count);
//換算進(jìn)度
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 {
//關(guān)閉
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);
}
}
上傳和下載已經(jīng)分裝好了,在進(jìn)度換算中這里面需要注意狠半,因?yàn)橛肈ouble類型比較好換算進(jìn)度噩死,BigDecimal保留了兩位小數(shù),
代碼里神年,doInBackground是異步執(zhí)行的已维,onPostExecute(上傳和下載結(jié)果)和onProgressUpdate(上傳和下載進(jìn)度)它是調(diào)度到主線程了。下面我們來說說分塊上傳該怎么實(shí)現(xiàn)已日,因?yàn)樵谏蟼黜?xiàng)目中有一些大的項(xiàng)目垛耳,服務(wù)器那邊做了可以分塊上傳,這個(gè)時(shí)候Android該怎么實(shí)現(xiàn)上傳。
HttpUrlConnection分塊上傳
首先需要一個(gè)方法來處理分塊
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;
}
這里參數(shù)offset記錄文件上一次讀寫的位置堂鲜,blockSize代表每塊大小栈雳,接下來咱們看看如果實(shí)現(xiàn)網(wǎng)絡(luò)請求
private String filePath;
private byte[] data;
public void uploadFileBlock(OnHttpProgressUtilListener onHttpProgressUtilListener, String urlPath, byte[] data) {
this.urlPath = urlPath;
this.data = data;
//調(diào)用doInBackground方法(方法里面是異步執(zhí)行)
}
private String uploadBlock() {
HttpURLConnection connection = null;
InputStream inputStream = null;
OutputStream outputStream = null;
String result = "";
try {
//獲得URL對象
URL url = new URL(urlPath);
//返回一個(gè)URLConnection對象,它表示到URL所引用的遠(yuǎn)程對象的連接
connection = (HttpURLConnection) url.openConnection();
// 默認(rèn)為GET
connection.setRequestMethod("POST");
//不使用緩存
connection.setUseCaches(false);
//設(shè)置超時(shí)時(shí)間
connection.setConnectTimeout(10000);
//設(shè)置讀取超時(shí)時(shí)間
connection.setReadTimeout(10000);
//設(shè)置是否從httpUrlConnection讀入泡嘴,默認(rèn)情況下是true;
connection.setDoInput(true);
//設(shè)置為true后才能寫入?yún)?shù)
connection.setDoOutput(true);
//設(shè)置為true后才能寫入?yún)?shù)
connection.setRequestProperty("Content-Type", "multipart/form-data");
//這里需要改動(dòng)
connection.setRequestProperty("Content-Length", String.valueOf(data.length));
outputStream = new DataOutputStream(connection.getOutputStream());
//這塊需要改為ByteArrayInputStream寫入流
ByteArrayInputStream inputStreamByte = new ByteArrayInputStream(data);
int count = 0;
// 計(jì)算上傳進(jìn)度
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();
//寫入?yún)?shù)
if (connection.getResponseCode() == HttpURLConnection.HTTP_OK) {
//獲得輸入流
inputStream = connection.getInputStream();
//包裝字節(jié)流為字符流
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 {
//關(guān)閉
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[]而不是文件路徑了甫恩,我們下面看看整個(gè)類變成什么樣了
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;
/**
* 括號里的類型
* 第一個(gè)代表doInBackground方法需要傳入的類型
* 第二個(gè)代表onProgressUpdate方法需要傳入的類型
* 第一個(gè)代表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;
//調(diào)用doInBackground方法(方法里面是異步執(zhí)行)
execute(UPLOAD);
}
public void uploadFile(OnHttpProgressUtilListener onHttpProgressUtilListener, String urlPath, String filePath) {
this.urlPath = urlPath;
this.filePath = filePath;
//調(diào)用doInBackground方法(方法里面是異步執(zhí)行)
execute(UPLOAD);
}
public void downloadFile(OnHttpProgressUtilListener onHttpProgressUtilListener, String urlPath, String filePath) {
this.urlPath = urlPath;
this.filePath = filePath;
//調(diào)用doInBackground方法(方法里面是異步執(zhí)行)
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);
//返回一個(gè)URLConnection對象逆济,它表示到URL所引用的遠(yuǎn)程對象的連接
connection = (HttpURLConnection) url.openConnection();
// 默認(rèn)為GET
connection.setRequestMethod("POST");
//不使用緩存
connection.setUseCaches(false);
//設(shè)置超時(shí)時(shí)間
connection.setConnectTimeout(10000);
//設(shè)置讀取超時(shí)時(shí)間
connection.setReadTimeout(10000);
//設(shè)置是否從httpUrlConnection讀入酌予,默認(rèn)情況下是true;
connection.setDoInput(true);
//設(shè)置為true后才能寫入?yún)?shù)
connection.setDoOutput(true);
//設(shè)置為true后才能寫入?yún)?shù)
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;
// 計(jì)算上傳進(jìn)度
Long progress = 0L;
byte[] bufferOut = new byte[2048];
while ((count = dataInputStream.read(bufferOut)) != -1) {
outputStream.write(bufferOut, 0, count);
progress += count;
//換算進(jìn)度
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();
//寫入?yún)?shù)
if (connection.getResponseCode() == HttpURLConnection.HTTP_OK) {
//獲得輸入流
inputStream = connection.getInputStream();
//包裝字節(jié)流為字符流
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 {
//關(guān)閉
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);
//返回一個(gè)URLConnection對象,它表示到URL所引用的遠(yuǎn)程對象的連接
connection = (HttpURLConnection) url.openConnection();
// 默認(rèn)為GET
connection.setRequestMethod("POST");
//不使用緩存
connection.setUseCaches(false);
//設(shè)置超時(shí)時(shí)間
connection.setConnectTimeout(10000);
//設(shè)置讀取超時(shí)時(shí)間
connection.setReadTimeout(10000);
//設(shè)置是否從httpUrlConnection讀入奖慌,默認(rèn)情況下是true;
connection.setDoInput(true);
//設(shè)置為true后才能寫入?yún)?shù)
connection.setDoOutput(true);
//設(shè)置為true后才能寫入?yún)?shù)
connection.setRequestProperty("Content-Type", "multipart/form-data");
//這里需要改動(dòng)
connection.setRequestProperty("Content-Length", String.valueOf(data.length));
outputStream = new DataOutputStream(connection.getOutputStream());
//這塊需要改為ByteArrayInputStream寫入流
ByteArrayInputStream inputStreamByte = new ByteArrayInputStream(data);
int count = 0;
// 計(jì)算上傳進(jìn)度
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();
//寫入?yún)?shù)
if (connection.getResponseCode() == HttpURLConnection.HTTP_OK) {
//獲得輸入流
inputStream = connection.getInputStream();
//包裝字節(jié)流為字符流
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 {
//關(guān)閉
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);
//返回一個(gè)URLConnection對象抛虫,它表示到URL所引用的遠(yuǎn)程對象的連接
connection = (HttpURLConnection) url.openConnection();
//建立實(shí)際鏈接
connection.connect();
inputStream = connection.getInputStream();
//獲取文件長度
Double size = (double) connection.getContentLength();
outputStream = new FileOutputStream(filePath);
int count = 0;
// 計(jì)算上傳進(jìn)度
Long progress = 0L;
byte[] bytes = new byte[2048];
while ((count = inputStream.read(bytes)) != -1) {
outputStream.write(bytes, 0, count);
//換算進(jìn)度
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 {
//關(guān)閉
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);
}
}
下面我們看看如果使用分塊上傳,使用分塊上傳必須服務(wù)器支持分塊上傳才可以
int chuncks=0;//流塊
double chunckProgress=0.0;//進(jìn)度
private void upload(){
//每一塊大小
int blockLength=1024*1024*2;
File file = new File("文件路徑");
final long fileSize=file.length();
//當(dāng)前第幾塊
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) {
//換算進(jìn)度
double d = (new BigDecimal(progress / fileSize).setScale(2, BigDecimal.ROUND_HALF_UP)).doubleValue();
int pro= (int) (d*100);
//這個(gè)就是上傳進(jìn)度简僧,已經(jīng)換算為1-100
Log.d(TAG, "onProgress: "+pro);
}
@Override
public void onSuccess(String json) {
//上傳成功
}
},"上傳URL 需要傳入當(dāng)前塊chunck和總塊數(shù)chuncks參數(shù)建椰,需接口支持才行",block);
chunck++;
}
}
這樣就上傳成功了,以后遇到上傳下載都可以這樣用岛马,但也可以選擇第三方網(wǎng)絡(luò)請求框架棉姐,各有所長
這個(gè)是項(xiàng)目地址大家可以作為參考
git :https://github.com/GuoLiangGod/HttpUrlConnectionDemo
這篇文件,希望對大家又幫助啦逆,如果遇到問題可以留言