学习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 mImageList;  private List mReduceImageList;  private List 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, Observable> mOneLetterFunc = Observable::from;  private Action1 mImageUrlAction = s -> uploadImg(new File(s));  private Action1 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() {      @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的基本用法,其强大毋庸置疑,但要运用好,还需要深入去学习它。它也让我们的代码更简洁。学习永无止境,感谢大佬们给我们提供的那么多好用的框架。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

更多相关文章

  1. android轮播图示例
  2. Android中实现图片的拖拽显示
  3. android图片加载处理
  4. Android(安卓)APP终极瘦身指南
  5. AndroidQuery 开源项目
  6. Android给图片加文字和图片水印
  7. android拍照获得图片及获得图片后剪切设置到ImageView
  8. Android(安卓)sqlite数据库简单使用(创建和插入,查询数据)
  9. android 视频图片轮播

随机推荐

  1. 添加一个新变量能使以前不显著的变量变得
  2. 线索二叉树(C语言)
  3. 谷歌、脸书、魔兽世界都在用!InnoDB是什么
  4. 从1997投稿到2021年被Top5刊接受, 从不惑
  5. 加入其他控制变量后, 估计系数的符号相反
  6. 封禁TikTok?这次美国政府恐怕不能再为所欲
  7. 估计工具变量回归时, 是否必须将所有外生
  8. 如何教AI吃鸡?
  9. 寻找真相, 中国的经济增长真的可以用晋升
  10. 什么是数字孪生体?来自西门子、PTC、北航