Android上传多张图片的实例代码(RxJava异步分发)
学习RxJava有一段时间了,一直在考虑怎么使用,如何在项目中合理运用它。在android很多项目中,都会存在图片上传,下面我介绍如何用Rxjava异步上传多张图片。
一,用到的框架
compile'top.zibin:Luban:1.0.9'//图片压缩 compile'org.xutils:xutils:3.3.34'//网络请求 compile'io.reactivex:rxandroid:1.1.0'//rxandroid compile'io.reactivex:rxjava:1.1.0'//rxjava
另外Rxjava与Lambda表达式非常契合,便引入了Lambda的配置,在gradle中需要支持java8的特性:
jackOptions{ enabledtrue } compileOptions{ targetCompatibilityJavaVersion.VERSION_1_8 sourceCompatibilityJavaVersion.VERSION_1_8 }
初始化配置,在自己的Application的onCreate中需要初始化网络请求框架,否定会无法进行网络请求。
publicclassAPPextendsApplication{ privatestaticAPPinstance; publicstaticsynchronizedAPPgetInstance(){ returninstance; } @Override publicvoidonCreate(){ super.onCreate(); x.Ext.init(this); x.Ext.setDebug(org.xutils.BuildConfig.DEBUG); instance=this; } }
二,图片压缩与上传
这里为了演示用法与图片上传只是模拟请求所以手动创建了三个数组用来缓存图片选择后和处理后的url。
privateListmImageList; privateList mReduceImageList; privateList mImageUrl; @Override protectedvoidonCreate(BundlesavedInstanceState){ super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mImageUrl=newArrayList<>(); mImageList=newArrayList<>(); mReduceImageList=newArrayList<>(); mImageList.add("content://media/external/images/media/573778"); mImageList.add("content://media/external/images/media/573778"); mImageList.add("content://media/external/images/media/573778"); Buttonbutton=(Button)findViewById(R.id.button1); button.setOnClickListener(v->setImage()); }
图片上传大部分是根据拍照或者图库选择的多张Uri地址,如果不进行压缩,图片都是很大的,一般拍照的图片都有几百KB或者几M,所以为了节省流量与服务器的承载负担,需要进行压缩。压缩后的图片大小仅在几十KB左右。
/** *根据uri查询位置图片 * *@paramselectedImage */ privatevoidsendPicByUri(UriselectedImage){ Cursorcursor=getContentResolver().query(selectedImage,null,null, null,null); Stringst8="没有找到图片"; if(cursor!=null){ cursor.moveToFirst(); intcolumnIndex=cursor.getColumnIndex("_data"); StringpicturePath=cursor.getString(columnIndex); cursor.close(); if(picturePath==null||picturePath.equals("null")){ Toasttoast=Toast.makeText(this,st8,Toast.LENGTH_SHORT); toast.setGravity(Gravity.CENTER,0,0); toast.show(); return; } sendPicture(picturePath); }else{ Filefile=newFile(selectedImage.getPath()); if(!file.exists()){ Toasttoast=Toast.makeText(this,st8,Toast.LENGTH_SHORT); toast.setGravity(Gravity.CENTER,0,0); toast.show(); return; } sendPicture(file.getAbsolutePath()); } } /** *压缩图片 * *@paramfilePath */ privatevoidsendPicture(finalStringfilePath){ Log.i(tag,"压缩图片"); Luban .get(this) .load(newFile(filePath)) .putGear(Luban.THIRD_GEAR) .setCompressListener(newOnCompressListener(){ @Override publicvoidonStart(){ } @Override publicvoidonSuccess(Filefile){ Log.i(tag,"压缩后的图片==》"); uploadImg(file); } @Override publicvoidonError(Throwablee){ } }) .launch(); setResult(RESULT_OK); }
为了优化代码和这些耗时操作用到的RxJava,进行异步处理,我们需要创建RxJava的写法:
/** *分发url接收者 */ privateFunc1,Observable
>mOneLetterFunc=Observable::from; privateAction1 mImageUrlAction=s->uploadImg(newFile(s)); privateAction1 mAddContent=s->sendPicByUri(Uri.parse(s)); /** *分发压缩图片 */ privatevoidsetImage(){ Log.i(tag,"开始分发获取的url"); Observable.just(mImageList) .subscribeOn(Schedulers.io())//指定subscribe()发生在IO线程 .observeOn(AndroidSchedulers.mainThread()) .flatMap(mOneLetterFunc) .subscribe(mAddContent); }
分发的同事会进行异步网络请求,进行上传图片至服务器,并返回服务器所存储的url图片地址:
/** *图片上传服务器 * *@paramfile文件 */ publicvoiduploadImg(Filefile){ Log.i(tag,"网络请求上传图片"); RequestParamsparams=newRequestParams("这里是上传到服务器的Http地址"); params.addBodyParameter("imgContent",file); params.setMultipart(true); x.http().post(params,newCallback.ProgressCallback(){ @Override publicvoidonWaiting(){ } @Override publicvoidonStarted(){ } @Override publicvoidonLoading(longtotal,longcurrent,booleanisDownloading){ } @Override publicvoidonSuccess(Stringresult){ try{ JSONObjectjsonObject=newJSONObject(result); JSONObjectdata=jsonObject.getJSONObject("data"); mImageUrl.add(data.getString("src")); if(mImageList.size()==mImageUrl.size()){ Log.i("上传完成==",mImageUrl.toString()); } }catch(JSONExceptione){ e.printStackTrace(); } } @Override publicvoidonError(Throwableex,booleanisOnCallback){ Log.i("上传出错==",ex.getMessage()); } @Override publicvoidonCancelled(CancelledExceptioncex){ } @Override publicvoidonFinished(){ } }); }
为了节约时间,也可以在添加图片时就进行压缩图片等操作。上传时,只进行上传的网络操作
/** *直接上传所选图片图片 */ privatevoiduploadingImage(){ Log.i(tag,"开始上传图片"); if(mReduceImageList.size()>0){ Observable.just(mReduceImageList) .subscribeOn(Schedulers.io())//指定subscribe()发生在IO线程 .observeOn(AndroidSchedulers.mainThread()) .flatMap(mOneLetterFunc) .subscribe(mImageUrlAction); } }
三,小结
这里只是简单的演示Rxjava的基本用法,其强大毋庸置疑,但要运用好,还需要深入去学习它。它也让我们的代码更简洁。学习永无止境,感谢大佬们给我们提供的那么多好用的框架。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。