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

學習RxJava有一段時間了,一直在考慮怎么使用,如何在項目中合理運用它。在android很多項目中,都會存在圖片上傳,下面我介紹如何用Rxjava異步上傳多張圖片。

一,用到的框架

    compile 'top.zibin:Luban:1.0.9'//圖片壓縮
    compile 'org.xutils:xutils:3.3.34'//網(wǎng)絡請求
    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中需要初始化網(wǎng)絡請求框架,否定會無法進行網(wǎng)絡請求。

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地址,如果不進行壓縮,圖片都是很大的,一般拍照的圖片都有幾百KB或者幾M,所以為了節(jié)省流量與服務器的承載負擔,需要進行壓縮。壓縮后的圖片大小僅在幾十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,進行異步處理,我們需要創(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ā)的同事會進行異步網(wǎng)絡請求,進行上傳圖片至服務器,并返回服務器所存儲的url圖片地址:

/**
     * 圖片上傳服務器
     *
     * @param file 文件
     */
    public void uploadImg(File file) {
        Log.i(tag, "網(wǎng)絡請求上傳圖片");
        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() {

            }
        });
    }

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

 /**
     * 直接上傳所選圖片圖片
     */
    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的基本用法,其強大毋庸置疑,但要運用好,還需要深入去學習它。它也讓我們的代碼更簡潔。學習永無止境,感謝大佬們給我們提供的那么多好用的框架。

最后編輯于
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容