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

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,332评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,508评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,812评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,607评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,728评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,919评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,071评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,802评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,256评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,576评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,712评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,389评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,032评论 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,798评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,026评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,473评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,606评论 2 350

推荐阅读更多精彩内容