RX系列四 | RxAndroid | 載入圖片 | 提交表單

來源:互聯網
上載者:User

標籤:completed   cep   switch   font   password   override   async   []   break   

RX系列四 | RxAndroid | 載入圖片 | 提交表單

說實話,學RxJava就是為了我們在Android中運用的更加順手一點,也就是RxAndroid,我們還是先一步步來,學會怎麼去用的比較好,之前的三篇算是鋪墊,讓你有一點認識,那Rx在Android中有什麼好處呢?我們先類比一些原始功能和他對比下

一.載入圖片

很多人說Rx出來之後,是編程思想的一種進階,實際上我學習了這種思想之後,確實是覺得有了很大的改變,不過,需要一點學習成本再加上,需要對原先的思想有些改觀,使得我依舊有點不適應,不知道為啥,可能就像用了好幾年的Eclipse,突然讓我用Android Studio的時候的那種感覺,不過,技術在進步,每個人也需要去接受,沒有好壞之分,那我們就在講解Rx之前,我們先把思路,邏輯來做一個鋪墊吧,首先,我們要準備一些東西的,因為涉及了網路請求,下載等功能,所以我們肯定是要去添加下網路許可權

 <!--網路許可權--> <uses-permission android:name="android.permission.INTERNET"/>

然後我們再來說一下,我們現在要乾的事情,先易後難,我們先來載入一張圖片,我們傳統的做法是通過AsyncTask去做,但是這樣的代碼很長很沉悶,而在我們的Activity中,其實上一個Activity的本身他是有很多的工作要做的,這樣導致代碼會很多,不容易重構等,所以才會有現在的MVC,MVP等架構去解耦,所以我們既然Rx編程本身是一套很簡潔的代碼,那我們應該用什麼方法去合理的實現呢?我們來寫個解析的方法,因為需要用到OkHttp,所以請在gradle裡添加

  //OkHttp3  compile ‘com.squareup.okhttp3:okhttp:3.+‘

這樣才好去載入,我們寫個方法吧

   //載入圖片    private Observable<byte[]> lodingImg(String imgPath){        return Observable.create(new Observable.OnSubscribe<byte[]>() {            @Override            public void call(Subscriber<? super byte[]> subscriber) {                if(!subscriber.isUnsubscribed()){                    //解析圖片                    OkHttpClient client = new OkHttpClient();                    Request request = new Request.Builder().url(imgPath).build();                    client.newCall(request).enqueue(new Callback() {                        @Override                        public void onFailure(Call call, IOException e) {                            subscriber.onError(e);                        }                        @Override                        public void onResponse(Call call, Response response) throws IOException {                            if(response.isSuccessful()){                                byte [] bytes = response.body().bytes();                                if(bytes != null){                                    subscriber.onNext(bytes);                                }                            }                            //結束                            subscriber.onCompleted();                        }                    });                }            }        });    }

這個方法可以看到我們傳回值是一個byte位元組數組參數的被觀察者Observable,然後傳遞一個地址,我們就直接return回去一個Observable,在Observable裡面,我們做了什麼事情呢?其實我們就直接用OkHttp去解析了一張圖片,拿到了byte之後,通過subscriber.onNext(bytes)傳遞給了觀察者,讓他去做操作,當然,別忘了調用onCompleted去告知觀察者已經結束了操作,而在觀察者這邊,你需要做什麼呢?

    @Override    public void onClick(View v) {        switch (v.getId()) {            case R.id.btn_download:                lodingImg(IMG_PATH)                        //網路訪問                        .observeOn(Schedulers.io())                        //UI線程                        .observeOn(AndroidSchedulers.mainThread())                        //訂閱                        .subscribe(new Observer<byte[]>() {                    @Override                    public void onCompleted() {                        Log.i(TAG,"onCompleted");                    }                    @Override                    public void onError(Throwable e) {                        Log.i(TAG,e.toString());                    }                    @Override                    public void onNext(byte[] bytes) {                        Bitmap bitmap = BitmapFactory.decodeByteArray(bytes,0,bytes.length);                        img.setImageBitmap(bitmap);                    }                });                break;        }    }

其實可以看到,我們直接就去訂閱了一個subscribe,在onNext裡面,通過BitmapFactory的方法轉換成一個Bitmap,這就是Rx載入的處理方式,這種方式將對我們產生很大的影響,我們最起碼現在懂得了他的一點套路了,我們來看下運行結果

OK,也是很順利的載入出來了

二.提交表單

如果說載入圖片是get的話,那提交表單就是post了,我們來看一下提交表單該怎麼寫,我們假設是做一個登陸註冊的功能,那就很簡單了,我們看下我們這次要做的代碼

   //登入    private Observable<String> fromLogin(String url, Map<String,String> params){        return Observable.create(new Observable.OnSubscribe<String>() {            @Override            public void call(Subscriber<? super String> subscriber) {                if(!subscriber.isUnsubscribed()){                    OkHttpClient client = new OkHttpClient();                    FormBody.Builder builder = new FormBody.Builder();                    if(params!=null && !params.isEmpty()){                        for (Map.Entry<String, String>entry:params.entrySet()){                            builder.add(entry.getKey(),entry.getValue());                        }                    }                    RequestBody requestBody = builder.build();                    //構建post請求                    Request request = new Request.Builder().url(url).post(requestBody).build();                    client.newCall(request).enqueue(new Callback() {                        @Override                        public void onFailure(Call call, IOException e) {                            subscriber.onError(e);                        }                        @Override                        public void onResponse(Call call, Response response) throws IOException {                            if(response.isSuccessful()){                                subscriber.onNext(response.body().string());                            }                            //訪問結束                            subscriber.onCompleted();                        }                    });                }            }        });    }

這段代碼裡面,我們可用看到,我們定義了一個方法,傳回值是一個String類型的被觀察者Observable,而傳遞的參數就是登陸的地址和一個Map索引值對,我們直接return一個Observable即可,在裡面我們使用OkHTTP提交表單,最後通過onNext返回結果,通過onCompleted告知結束操作,而在我們的觀察者裡面我們應該怎麼做?

    @Override    public void onClick(View v) {        switch (v.getId()) {            case R.id.btn_login:                String name = et_name.getText().toString().trim();                String password = et_password.getText().toString().trim();                if (!TextUtils.isEmpty(name)) {                    if(!TextUtils.isEmpty(password)){                        Map<String,String> params = new HashMap<>();                        params.put("name",name);                        params.put("password",password);                        fromLogin(LOGIN_URL,params)                                //網路訪問                                .observeOn(Schedulers.io())                                //UI線程                                .observeOn(AndroidSchedulers.mainThread())                                .subscribe(new Observer<String>() {                                    @Override                                    public void onCompleted() {                                        Log.i(TAG,"onCompleted");                                    }                                    @Override                                    public void onError(Throwable e) {                                        Log.i(TAG,e.toString());                                    }                                    @Override                                    public void onNext(String s) {                                        Log.i(TAG,s);                                    }                                });                    }else {                        Toast.makeText(this, "密碼不可為空", Toast.LENGTH_SHORT).show();                    }                }else {                    Toast.makeText(this, "帳號不可為空", Toast.LENGTH_SHORT).show();                }                break;        }    }

在這個點擊事件裡,我們可用看到直接把參數塞進去後通過subscribe訂閱拿到結果,這樣如果登入成功就跳轉了,這就是一整套的邏輯,這裡沒有地址,就不示範了,到這裡,我相信大家對基本的使用應該是沒什麼問題了,一句話概括,就是非同步,讓我們的代碼邏輯性更強,當然, 現在的例子還不能友好的表達出精髓,大家有興趣的可以接著後續的系列

Sample下載:系列最後一篇提供有興趣的可以加群:555974449

RX系列四 | RxAndroid | 載入圖片 | 提交表單

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.