时间:2021-05-20
学习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 { enabled true }compileOptions { targetCompatibility JavaVersion.VERSION_1_8 sourceCompatibility JavaVersion.VERSION_1_8 }初始化配置,在自己的Application的onCreate中需要初始化网络请求框架,否定会无法进行网络请求。
public class APP extends Application { private static APP instance; public static synchronized APP getInstance() { return instance; } @Override public void onCreate() { super.onCreate(); x.Ext.init(this); x.Ext.setDebug(org.xutils.BuildConfig.DEBUG); instance = this; }}二,图片压缩与上传
这里为了演示用法与图片上传只是模拟请求所以手动创建了三个数组用来缓存图片选择后和处理后的url。
private List<String> mImageList; private List<String> mReduceImageList; private List<String> mImageUrl; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mImageUrl = new ArrayList<>(); mImageList = new ArrayList<>(); mReduceImageList = new ArrayList<>(); mImageList.add("content://media/external/images/media/573778"); mImageList.add("content://media/external/images/media/573778"); mImageList.add("content://media/external/images/media/573778"); Button button = (Button) findViewById(R.id.button1); button.setOnClickListener(v -> setImage()); }图片上传大部分是根据拍照或者图库选择的多张Uri地址,如果不进行压缩,图片都是很大的,一般拍照的图片都有几百KB或者几M,所以为了节省流量与服务器的承载负担,需要进行压缩。压缩后的图片大小仅在几十KB左右。
/** * 根据uri查询位置图片 * * @param selectedImage */ private void sendPicByUri(Uri selectedImage) { Cursor cursor = getContentResolver().query(selectedImage, null, null, null, null); String st8 = "没有找到图片"; if (cursor != null) { cursor.moveToFirst(); int columnIndex = cursor.getColumnIndex("_data"); String picturePath = cursor.getString(columnIndex); cursor.close(); if (picturePath == null || picturePath.equals("null")) { Toast toast = Toast.makeText(this, st8, Toast.LENGTH_SHORT); toast.setGravity(Gravity.CENTER, 0, 0); toast.show(); return; } sendPicture(picturePath); } else { File file = new File(selectedImage.getPath()); if (!file.exists()) { Toast toast = Toast.makeText(this, st8, Toast.LENGTH_SHORT); toast.setGravity(Gravity.CENTER, 0, 0); toast.show(); return; } sendPicture(file.getAbsolutePath()); } } /** * 压缩图片 * * @param filePath */ private void sendPicture(final String filePath) { Log.i(tag, "压缩图片"); Luban .get(this) .load(new File(filePath)) .putGear(Luban.THIRD_GEAR) .setCompressListener(new OnCompressListener() { @Override public void onStart() { } @Override public void onSuccess(File file) { Log.i(tag, "压缩后的图片==》"); uploadImg(file); } @Override public void onError(Throwable e) { } }) .launch(); setResult(RESULT_OK); }为了优化代码和这些耗时操作用到的RxJava,进行异步处理,我们需要创建RxJava的写法:
/** * 分发url 接收者 */ private Func1<List<String>, Observable<String>> mOneLetterFunc = Observable::from; private Action1<String> mImageUrlAction = s -> uploadImg(new File(s)); private Action1<String> mAddContent = s -> sendPicByUri(Uri.parse(s)); /** * 分发压缩图片 */ private void setImage() { Log.i(tag, "开始分发获取的url"); Observable.just(mImageList) .subscribeOn(Schedulers.io()) // 指定 subscribe() 发生在 IO 线程 .observeOn(AndroidSchedulers.mainThread()) .flatMap(mOneLetterFunc) .subscribe(mAddContent); }分发的同事会进行异步网络请求,进行上传图片至服务器,并返回服务器所存储的url图片地址:
/** * 图片上传服务器 * * @param file 文件 */ public void uploadImg(File file) { Log.i(tag, "网络请求上传图片"); RequestParams params = new RequestParams("这里是上传到服务器的Http地址"); params.addBodyParameter("imgContent", file); params.setMultipart(true); x.http().post(params, new Callback.ProgressCallback<String>() { @Override public void onWaiting() { } @Override public void onStarted() { } @Override public void onLoading(long total, long current, boolean isDownloading) { } @Override public void onSuccess(String result) { try { JSONObject jsonObject = new JSONObject(result); JSONObject data = jsonObject.getJSONObject("data"); mImageUrl.add(data.getString("src")); if (mImageList.size() == mImageUrl.size()) { Log.i("上传完成==", mImageUrl.toString()); } } catch (JSONException e) { e.printStackTrace(); } } @Override public void onError(Throwable ex, boolean isOnCallback) { Log.i("上传出错==", ex.getMessage()); } @Override public void onCancelled(CancelledException cex) { } @Override public void onFinished() { } }); }为了节约时间,也可以在添加图片时就进行压缩图片等操作。上传时,只进行上传的网络操作
/** * 直接上传所选图片图片 */ private void uploadingImage() { Log.i(tag, "开始上传图片"); if (mReduceImageList.size() > 0) { Observable.just(mReduceImageList) .subscribeOn(Schedulers.io()) // 指定 subscribe() 发生在 IO 线程 .observeOn(AndroidSchedulers.mainThread()) .flatMap(mOneLetterFunc) .subscribe(mImageUrlAction); } }三,小结
这里只是简单的演示Rxjava的基本用法,其强大毋庸置疑,但要运用好,还需要深入去学习它。它也让我们的代码更简洁。学习永无止境,感谢大佬们给我们提供的那么多好用的框架。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
声明:本页内容来源网络,仅供用户参考;我单位不保证亦不表示资料全面及准确无误,也不保证亦不表示这些资料为最新信息,如因任何原因,本网内容或者用户因倚赖本网内容造成任何损失或损害,我单位将不会负任何法律责任。如涉及版权问题,请提交至online#300.cn邮箱联系删除。
本文实例为大家分享了angularjs上传多张图片并预览的具体代码,供大家参考,具体内容如下directive.js/**多图片上传及预览指令(需指定图片类名)
本文实例为大家分享了js实现上传图片到服务器的具体代码,供大家参考,具体内容如下HTML//多张图片上传multiple//原生提交按钮javascript//
本文实例讲述了PHP结合jqueryajax实现上传多张图片,并限制图片大小操作。分享给大家供大家参考,具体如下:php用jquery-ajax上传多张图片限制
本文实例为大家分享了RXjava网络获取图片数据的具体代码,供大家参考,具体内容如下RXjava//Anhighlightedblockimage=findVi
本文实例为大家分享了微信小程序实现同时上传多张图片的具体代码,供大家参考,具体内容如下1.图片选择后,路径已经存入list中:data:{images:[],/