android遞歸壓縮上傳多張圖片到七牛的實(shí)例代碼
最近遇到這樣一個(gè)需求:要做一個(gè)仿微信朋友圈的功能,要求上傳最多九張圖到七牛。七牛有上傳圖片的接口,但是每次只能上傳一張。如果是九張圖片一齊上傳,使用for循環(huán)的話肯定不行的,很容易出錯(cuò)。因?yàn)樯蟼髌吲5膭?dòng)作是在子線程完成的,for循環(huán)是在主線程的,這就相當(dāng)于同時(shí)開啟十個(gè)子線程來上傳圖片,而且都是耗時(shí)線程,很容易會(huì)ANR的。
最好的解決辦法應(yīng)該是先壓縮圖片,在200k-300k之間,保證圖片不失真,然后一張一張上傳,通過七牛的回調(diào),來判斷上一張圖片是否上傳完成,上傳完成了,再上傳下一張圖片。
好了,話不多說,貼代碼:
1.壓縮圖片
/**
* 質(zhì)量壓縮法
*
* @param image
* @return
*/
public byte[] compressImage(Bitmap image) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
image.compress(Bitmap.CompressFormat.JPEG, 100, baos);//質(zhì)量壓縮方法,這里100表示不壓縮,把壓縮后的數(shù)據(jù)存放到baos中
int options = 100;
while (baos.toByteArray().length / 1024 > 250) { //循環(huán)判斷如果壓縮后圖片是否大于100kb,大于繼續(xù)壓縮
baos.reset();//重置baos即清空baos
image.compress(Bitmap.CompressFormat.JPEG, options, baos);//這里壓縮options%,把壓縮后的數(shù)據(jù)存放到baos中
options -= 10;//每次都減少10
if (options <= 10) {
break;
}
}
byte[] byteArray = baos.toByteArray();
try {
if (baos != null) {
baos.close();
}
} catch (IOException e) {
e.printStackTrace();
}
return byteArray;
}
這個(gè)之前是壓縮到100k的,這個(gè)沒有按比例壓縮,有的圖片尺寸比較大的會(huì)模糊,所以現(xiàn)在調(diào)整到250k,估計(jì)壓縮的圖片大小會(huì)在200-300k左右吧。
2.遞歸上傳圖片
/**
* 遞歸上傳圖片主要方法
* @param picUrl 圖片的本地路徑
* @param picSize 上傳圖片總數(shù)量
* //picNum是計(jì)數(shù)器,用于計(jì)算已上傳圖片的數(shù)目
* //snplMomentAddPhotos.getData().get(picNum)是選擇圖片的開源庫(kù),返回一個(gè)ArrayList<String>類型的圖片路徑
* BitmapUnit.getInstance().compressImage(BitmapUnit.getInstance().getBItmap(picUrl))//壓縮圖片
*
*/
private void upPic(String picUrl, int picSize) {
//根據(jù)七牛上傳圖片的api,封裝的上傳方法
QiniuUtils.getInstance().uploadSmallFile(BitmapUnit.getInstance().
compressImage(BitmapUnit.getInstance().getBItmap(picUrl)),
url -> {
//圖片成功上傳到七牛時(shí)回調(diào)
//當(dāng)前完成上傳的圖片數(shù)量小于總圖片數(shù)量的時(shí)候重新調(diào)用該方法遞歸
if (picNum < picSize) {
upPic(snplMomentAddPhotos.getData().get(picNum), picSize);
Contants.upPicStatus = 1;
if (loadingDialog != null) {
loadingDialog.loadingStatus((picNum + 1) + "/" + picSize + "張圖片");
}
//拼接字符串
if (TextUtils.isEmpty(picUrls)) {
picUrls = url;
} else {
picUrls = picUrls + "," + url;
}
}else {
//結(jié)束遞歸
if (loadingDialog != null) {
loadingDialog.dismiss();
}
Contants.upPicStatus = 200;
WorkManger.getInstance().publishWOrk("1", mClassTimetablesId,
tvTitle.getText().toString(), etName.getText().toString(), picUrls, mCourseId);
}
picNum++;//添加計(jì)數(shù)器,這個(gè)要放到最后,不然會(huì)數(shù)組角標(biāo)溢出
});
}
這個(gè)代碼不難看懂,具體的都寫在注釋里面了,有一些是項(xiàng)目里面用到的,各位看官只要明確在哪里調(diào)用方法進(jìn)行遞歸和在哪里添加計(jì)數(shù)器,在哪里結(jié)束遞歸就可以了。
但是這個(gè)方法有一點(diǎn)小瑕疵,正常我們?cè)谏蟼鲌D片的過程中,都要有加載進(jìn)度條,我發(fā)現(xiàn)加載進(jìn)度條在每次上傳成功的時(shí)候都會(huì)稍微卡一下。初步推斷是因?yàn)閴嚎s圖片引起的,壓縮圖片的時(shí)候也是比較耗能的,而且同在主線程,會(huì)引起卡頓。提出的解決方案是:把圖片壓縮部分提出來,放在子線程中,先壓縮圖片,然后在同意上傳。不過還沒來的及優(yōu)化,當(dāng)然各位如果有什么好的想法,請(qǐng)?zhí)岢鰜?。感激不盡。
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
Flutter彈性布局Flex水平排列Row垂直排列Column使用示例
這篇文章主要為大家介紹了Flutter彈性布局Flex水平排列Row垂直排列Column使用示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-08-08
Android使用Realm數(shù)據(jù)庫(kù)實(shí)現(xiàn)App中的收藏功能(代碼詳解)
這篇文章主要介紹了Android使用Realm數(shù)據(jù)庫(kù)實(shí)現(xiàn)App中的收藏功能,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-03-03
分享安裝Android Studio3.6的經(jīng)驗(yàn)教訓(xùn)
這篇文章主要介紹了Android Studio3.6的安裝錯(cuò)誤問題及解決方法,非常值得大家參考,現(xiàn)把整個(gè)過程分享到腳本之家平臺(tái),需要的朋友參考下吧2020-02-02
Android開發(fā)Input系統(tǒng)觸摸事件分發(fā)
這篇文章主要為大家介紹了Android開發(fā)Input系統(tǒng)觸摸事件分發(fā)示例解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-03-03
Android手機(jī)開發(fā) 控件 TextView文字居中
本文主要介紹Android手機(jī)開發(fā)TextView居中的方法,希望能幫到大家。2016-05-05
Android實(shí)現(xiàn)頁面滑動(dòng)切換動(dòng)畫
這篇文章主要為大家詳細(xì)介紹了Android實(shí)現(xiàn)頁面滑動(dòng)切換動(dòng)畫,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-12-12

