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 {
      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的基本用法,其强大毋庸置疑,但要运用好,还需要深入去学习它。它也让我们的代码更简洁。学习永无止境,感谢大佬们给我们提供的那么多好用的框架。

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

(0)

相关推荐

  • Android使用Retrofit仿微信多张图片拍照上传

    Android 仿照微信发说说,既能实现拍照,选图库,多图案上传,使用Retrofit技术. 使用方法:详见http://www.jb51.net/article/103009.htm 项目的运行效果: 服务器端接收文件的action UploadFile.java @Controller public class UploadFile extends ActionSupport { /** * */ private static final long serialVersionUID = 1L

  • Android中Okhttp3实现上传多张图片同时传递参数

    之前上传图片都是直接将图片转化为io流传给服务器,没有用框架传图片. 最近做项目,打算换个方法上传图片. Android发展到现在,Okhttp显得越来越重要,所以,这次我选择用Okhttp上传图片. Okhttp目前已经更新到Okhttp3版本了,用法跟之前相比,也有一些差别.在网上找了很多资料, 并和java后台同事反复调试,终于成功上传多张图片,同时传递一些键值对参数. 以下是我对该过程的封装: private static final MediaType MEDIA_TYPE_PNG =

  • Android 通过webservice上传多张图片到指定服务器详解

    Android 通过webservice上传多张图片到指定服务器详解 当你浏览这个的时候相信你对webservice的基本应用已经有一定的了解了,若是还没有明白的小伙伴,可以看我前面写的文章点击打开链接,这几天在开发一款app,需要上传图片到指定服务器吧,但是我刚开始以为在网上面应该有这样的好文章的吧,结果我在网络上找了好多代码,在传递图片的过程中,遇到各种bug,真是国人的东西就是喜欢复制别人的,自己不动手检验一下代码的正确性,哎,我也是无语了,然后我决定花点时间来填补一下这个空缺,写了这一片

  • Android ksoap调用webservice批量上传多张图片详解

    Android ksoap调用webservice批量上传多张图片详解 这几天一直在开发app,哎呀,什么都是第一接触,想想自己自学Java,然后自学Android,一直没有放弃,曾想放弃的,但是想到爸妈供我上学,不能在宿舍里面玩游戏,加入学校实验室,一天没课就来着里学习,当然这里也有志同道合的人,一起努力一起进步!虽然大学这几年都在努力的学习技术,也没有参加什么活动的,更别说找个女伴了!还是老老实实的敲代码,成功给我带来巨大的潜能,新技术总是吸引着我.自己做项目,哎呀!好像说偏题了,言归正传吧

  • 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:

  • android 使用OkHttp上传多张图片的实现代码

    简述 还是先来说说为啥用OkHttp作为多图片上传的框架,原因有两点: 1.OkHttp可以作为Volley底层传输协议,速度更快 2.使用Xutils和KJFramework上传图片存在一个小问题,首先,可以上传,并且可以上传多张图片,也可以上传其他的参数,那问题在哪里呢?在后台接受参数时很不灵活,Xutlis及KJFramework使用HashMap来上传每个参数,每一张图片也必须有一个唯一的key,上传一张图片就要定义一个参数来接收,上传两张图片就要定义两个参数来接收,当上传的图片数量不确

  • C#实现文件上传及文件下载功能实例代码

    废话不多说了,直接给大家贴代码了,具体代码如下所示: public ActionResult Upload() { // var pathUrl = "http://" + Request.Url.Authority; var file = Request.Files["Filedata"]; var uploadFileName = file.FileName; string filePath = "/File/" + uploadFileNa

  • jQuery多文件异步上传带进度条实例代码

    先给大家展示下效果图: ///作者:柯锦 ///完成时间:2016.08.16 ///多文件异步上传带进度条 (function ($) { function bytesToSize(bytes) { if (bytes === 0) return '0 B'; var k = 1024, // or 1000 sizes = ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'], i = Math.floor(Math.log(bytes)

  • Java文件上传下载、邮件收发实例代码

    文件上传下载 前台: 1. 提交方式:post 2. 表单中有文件上传的表单项: <input type="file" /> 3. 指定表单类型: 默认类型:enctype="application/x-www-form-urlencoded" 文件上传类型:multipart/form-data FileUpload 文件上传功能开发中比较常用,apache也提供了文件上传组件! FileUpload组件: 1. 下载源码 2. 项目中引入jar文件

  • Java FTP上传下载删除功能实例代码

    在没给大家上完整代码之前先给大家说下注意点: FTP上传下载,容易出现乱码,记得转换 package com.yinhai.team.action; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; impo

  • SpringMVC+Ajax实现文件批量上传和下载功能实例代码

    今天做了文件的上传下载,小小总结一下,基本的web项目建立及SpringMVC框架搭建此处不详细写出来了. 上传form: <form id="uploadfiles" enctype="multipart/form-data"> <input type="file" multiple="multiple" id="file_upload" name="file_upload&q

  • AngularJS创建一个上传照片的指令实例代码

    angularJS在近几年发展火热,也无疑是目前市面上来说比较牛逼且成熟的框架,在单页面前端应用当中应该可以说是王者,双向绑定省去了大量的前端代码,控制器在其作用于方面的控制也是相当腻害,今天我们要说的是另外一个比较牛逼的功能,就是angularJS的指令directive,之前没听说过angularJS指令的朋友请自行度娘,随便搜一条文章都比我说的详细,这次用一个我自己写的图片上传的指令来做为案例,详细说明一下实际操作过程中的指令. 之前我们前端的附件上传用的是jqueryFileUpload

  • c# 实现文件上传下载功能的实例代码

    NuGet 安装SqlSugar 1.Model文件下新建 DbContext 类 public class DbContext { public DbContext() { Db = new SqlSugarClient(new ConnectionConfig() { ConnectionString = "server=localhost;uid=root;pwd=woshishui;database=test", DbType = DbType.MySql, InitKeyTy

  • Python使用sftp实现上传和下载功能(实例代码)

    在Python中可以使用paramiko模块中的sftp登陆远程主机,实现上传和下载功能. 1.功能实现 根据输入参数判断是文件还是目录,进行上传和下载 本地参数local需要与远程参数remote类型一致,文件以文件名结尾,目录以\结尾 上传和下载的本地和远程目录需要存在 异常捕获 2.代码实现 #!/usr/bin/python # coding=utf-8 import paramiko import os def sftp_upload(host,port,username,passwo

随机推荐