Android上傳多張圖片(RxJava異步分發(fā))

學(xué)習(xí)RxJava有一段時間了打月,一直在考慮怎么使用,如何在項目中合理運(yùn)用它湿硝。在android很多項目中薪前,都會存在圖片上傳,下面我介紹如何用Rxjava異步上傳多張圖片关斜。

一示括,用到的框架

    compile 'top.zibin:Luban:1.0.9'//圖片壓縮
    compile 'org.xutils:xutils:3.3.34'//網(wǎng)絡(luò)請求
    compile 'io.reactivex:rxandroid:1.1.0'//rxandroid
    compile 'io.reactivex:rxjava:1.1.0'//rxjava

另外Rxjava與Lambda表達(dá)式非常契合,便引入了Lambda的配置痢畜,在gradle中需要支持java8的特性:

 jackOptions {
            enabled true
        }

compileOptions {
        targetCompatibility JavaVersion.VERSION_1_8
        sourceCompatibility JavaVersion.VERSION_1_8
    }

初始化配置垛膝,在自己的Application的onCreate中需要初始化網(wǎng)絡(luò)請求框架鳍侣,否定會無法進(jìn)行網(wǎng)絡(luò)請求。

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;
    }
}

二吼拥,圖片壓縮與上傳

這里為了演示用法與圖片上傳只是模擬請求所以手動創(chuàng)建了三個數(shù)組用來緩存圖片選擇后和處理后的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());
    }

圖片上傳大部分是根據(jù)拍照或者圖庫選擇的多張Uri地址,如果不進(jìn)行壓縮扔罪,圖片都是很大的秉沼,一般拍照的圖片都有幾百KB或者幾M,所以為了節(jié)省流量與服務(wù)器的承載負(fù)擔(dān)矿酵,需要進(jìn)行壓縮唬复。壓縮后的圖片大小僅在幾十KB左右。

/**
     * 根據(jù)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);
    }

為了優(yōu)化代碼和這些耗時操作用到的RxJava全肮,進(jìn)行異步處理敞咧,我們需要創(chuàng)建RxJava的寫法:

 /**
     * 分發(fā)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));

 /**
     * 分發(fā)壓縮圖片
     */
    private void setImage() {
        Log.i(tag, "開始分發(fā)獲取的url");
        Observable.just(mImageList)
                .subscribeOn(Schedulers.io()) // 指定 subscribe() 發(fā)生在 IO 線程
                .observeOn(AndroidSchedulers.mainThread())
                .flatMap(mOneLetterFunc)
                .subscribe(mAddContent);
    }

分發(fā)的同事會進(jìn)行異步網(wǎng)絡(luò)請求,進(jìn)行上傳圖片至服務(wù)器辜腺,并返回服務(wù)器所存儲的url圖片地址:

/**
     * 圖片上傳服務(wù)器
     *
     * @param file 文件
     */
    public void uploadImg(File file) {
        Log.i(tag, "網(wǎng)絡(luò)請求上傳圖片");
        RequestParams params = new RequestParams("這里是上傳到服務(wù)器的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() {

            }
        });
    }

為了節(jié)約時間休建,也可以在添加圖片時就進(jìn)行壓縮圖片等操作。上傳時评疗,只進(jìn)行上傳的網(wǎng)絡(luò)操作

 /**
     * 直接上傳所選圖片圖片
     */
    private void uploadingImage() {
        Log.i(tag, "開始上傳圖片");
        if (mReduceImageList.size() > 0) {
            Observable.just(mReduceImageList)
                    .subscribeOn(Schedulers.io()) // 指定 subscribe() 發(fā)生在 IO 線程
                    .observeOn(AndroidSchedulers.mainThread())
                    .flatMap(mOneLetterFunc)
                    .subscribe(mImageUrlAction);
        }

    }

三测砂,小結(jié)

這里只是簡單的演示Rxjava的基本用法,其強(qiáng)大毋庸置疑百匆,但要運(yùn)用好砌些,還需要深入去學(xué)習(xí)它。它也讓我們的代碼更簡潔加匈。學(xué)習(xí)永無止境存璃,感謝大佬們給我們提供的那么多好用的框架。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末雕拼,一起剝皮案震驚了整個濱河市纵东,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌啥寇,老刑警劉巖偎球,帶你破解...
    沈念sama閱讀 222,104評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異辑甜,居然都是意外死亡甜橱,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,816評論 3 399
  • 文/潘曉璐 我一進(jìn)店門栈戳,熙熙樓的掌柜王于貴愁眉苦臉地迎上來岂傲,“玉大人,你說我怎么就攤上這事子檀∧饕矗” “怎么了乃戈?”我有些...
    開封第一講書人閱讀 168,697評論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長亩进。 經(jīng)常有香客問我症虑,道長,這世上最難降的妖魔是什么归薛? 我笑而不...
    開封第一講書人閱讀 59,836評論 1 298
  • 正文 為了忘掉前任谍憔,我火速辦了婚禮,結(jié)果婚禮上主籍,老公的妹妹穿的比我還像新娘习贫。我一直安慰自己,他們只是感情好千元,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,851評論 6 397
  • 文/花漫 我一把揭開白布苫昌。 她就那樣靜靜地躺著,像睡著了一般幸海。 火紅的嫁衣襯著肌膚如雪祟身。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,441評論 1 310
  • 那天物独,我揣著相機(jī)與錄音袜硫,去河邊找鬼。 笑死挡篓,一個胖子當(dāng)著我的面吹牛父款,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播瞻凤,決...
    沈念sama閱讀 40,992評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼世杀!你這毒婦竟也來了阀参?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,899評論 0 276
  • 序言:老撾萬榮一對情侶失蹤瞻坝,失蹤者是張志新(化名)和其女友劉穎蛛壳,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體所刀,經(jīng)...
    沈念sama閱讀 46,457評論 1 318
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡衙荐,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,529評論 3 341
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了浮创。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片忧吟。...
    茶點(diǎn)故事閱讀 40,664評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖斩披,靈堂內(nèi)的尸體忽然破棺而出溜族,到底是詐尸還是另有隱情讹俊,我是刑警寧澤,帶...
    沈念sama閱讀 36,346評論 5 350
  • 正文 年R本政府宣布煌抒,位于F島的核電站仍劈,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏寡壮。R本人自食惡果不足惜贩疙,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,025評論 3 334
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望况既。 院中可真熱鬧这溅,春花似錦、人聲如沸坏挠。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,511評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽降狠。三九已至对竣,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間榜配,已是汗流浹背否纬。 一陣腳步聲響...
    開封第一講書人閱讀 33,611評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留蛋褥,地道東北人临燃。 一個月前我還...
    沈念sama閱讀 49,081評論 3 377
  • 正文 我出身青樓,卻偏偏與公主長得像烙心,于是被迫代替她去往敵國和親膜廊。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,675評論 2 359

推薦閱讀更多精彩內(nèi)容