java是一种可以撰写跨平台应用软件的面向对象的程序设计语言,是由Sun Microsystems公司于1995年5月推出的Java程序设计语言和Java平台(即JavaEE, JavaME, JavaSE)的总称。本站提供基于Java框架struts,spring,hibernate等的桌面应用、web交互及移动终端的开发技巧与资料

保持永久学习的心态,将成就一个优秀的你,来 继续搞起java知识。

第一次写博客,如果写的不好希望大家理解。 在了解rxjava多线程的,我们先来一个单线程下载网络图片并显示progress的。先贴出代码:

@Override
public void onClick(View v) {
     final ProgressDialog pd = new ProgressDialog(this);
    Observable.create(new Observable.OnSubscribe<String>() {
        @Override
        public void call(Subscriber<? super String> subscriber) {
            subscriber.onNext("http://img1.imgtn.bdimg.com/it/u=1225257463,1229468910&fm=21&gp=0.jpg");
            subscriber.onCompleted();
        }
    })
            .subscribeOn(Schedulers.io())
            .doOnSubscribe(new Action0() {
                @Override
                public void call() {
                    pd.show();
                }
            })
            .subscribeOn(AndroidSchedulers.mainThread())
            .map(new Func1<String, Bitmap>() {
                @Override
                public Bitmap call(String s) {
                    return getImageBitmap(s);
                }
            })
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(new Subscriber<Bitmap>() {
                @Override
                public void onCompleted() {
                    if (pd.isShowing()) {
                        pd.dismiss();
                    }
                }

                @Override
                public void onError(Throwable e) {
                    if (pd.isShowing()) {
                        pd.dismiss();
                    }
                }

                @Override
                public void onNext(Bitmap bitmap) {
                    iv1.setImageBitmap(bitmap);
                }
            });
}

private Bitmap getImageBitmap(String url){
    URL imgUrl = null;
    Bitmap bitmap = null;
    try {
        imgUrl = new URL(url);
        HttpURLConnection conn = (HttpURLConnection)imgUrl.openConnection();
        conn.setDoInput(true);
        conn.connect();
        InputStream is = conn.getInputStream();
        bitmap = BitmapFactory.decodeStream(is);
        is.close();
    } catch (MalformedURLException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }catch(IOException e){
        e.printStackTrace();
    }
    return bitmap;
}

上面代码其实不难理解,下面简单解释一下:rxjava主要需要理解两个概念:观察者(

Observer

)和被观察者(

Observable

),RxJava 的异步实现,是通过一种扩展的观察者模式来实现的。观察者和被观察者通过订阅(Subscribe)关系建立联系的。 我们看看以上的代码的异步是怎么实现的。答案是通过subscribeOn(Schedulers.io())这句话实现的。

Schedulers.io();是rxjava自己提供的线程调度器,用来读写文件、读写数据库、网络信息交互等。rxjava还
有<pre class='brush:plain;'>Schedulers.immediate();Schedulers.newThread();Schedulers.computation();等。对此我就不做过多的解释了。这里我
特别提一下

AndroidSchedulers.mainThread()这个是rxandroid提供的android的ui线程。 也许有人会问为什么会有2个subscribeOn();其中第二

是作用在doOnSubscribe()方法上的,让doOnSubscribe运

行在ui线程上。Observable.doOnSubscribe()是在Subscribe发生后而且在事件发送前执行的,所以他是可以指定线程
的。

最后使用observeOn(AndroidSchelers.mainThread())指定观察者运行ui线程,所以我可以在onNext()中设置ImageView的图片,在onError和onCompleted中隐藏progress。 好了,上面简单讲了一下一个线程下载图片,并在主线程设置图片了,我们来谈论下多线程并行运行下载图片,并且将它在imageview显示出来。而且在图片都下载完了之后弹出一个土司告知用户。先贴一种实现方式的代码:private void moreThread() {
final ProgressDialog pd = new ProgressDialog(this);
Observable
.just("http://img1.imgtn.bdimg.com/it/u=1225257463,1229468910&fm=21&gp=0.jpg")
.map(new Func1>() {
@Override
public Map call(String s) {
Map map = new HashMap();
map.put(1, getImageBitmap(s));
return map;
}
})
.subscribeOn(Schedulers.io())
.mergeWith(Observable.just("http://pic1a.nipic.com/2008-11-26/200811268173650_2.jpg")
.map(new Func1>() {
@Override
public Map call(String s) {
Map map = new HashMap();
map.put(2, getImageBitmap(s));
return map;
}
}).subscribeOn(Schedulers.io()))
.mergeWith(Observable
.just("http://pic13.nipic.com/20110415/1347158_132411659346_2.jpg")
.map(new Func1>() {
@Override
public Map call(String s) {
Map map = new HashMap();
map.put(3, getImageBitmap(s));
return map;
}
}).subscribeOn(Schedulers.io()))
.mergeWith(Observable
.just("http://img4.3lian.com/sucai/img6/230/29.jpg")
.map(new Func1>() {
@Override
public Map call(String s) {
Map map = new HashMap();
map.put(4, getImageBitmap(s));
return map;
}
}).subscribeOn(Schedulers.io()))
.mergeWith(Observable
.just("http://img1.imgtn.bdimg.com/it/u=2493205512,407054761&fm=21&gp=0.jpg")
.map(new Func1>() {
@Override
public Map call(String s) {
Map map = new HashMap();
map.put(5, getImageBitmap(s));
return map;
}
}).subscribeOn(Schedulers.io()))
.doOnSubscribe(new Action0() {
@Override
public void call() {
pd.show();
}
})
.subscribeOn(AndroidSchedulers.mainThread())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Subscriber>() {
@Override
public void onCompleted() {
if (pd.isShowing()) {
pd.dismiss();
}
Toast.makeText(SiyActivity.this,"5张图片下载完毕",0).show();
} @Override
public void onError(Throwable e) {
if (pd.isShowing()) {
pd.dismiss();
}
} @Override
public void onNext(Map integerBitmapMap) {
Set set = integerBitmapMap.keySet(); for (Integer key : set) {
switch (key) {
case 1:
iv1.setImageBitmap(integerBitmapMap.get(1));
break;
case 2:
iv2.setImageBitmap(integerBitmapMap.get(2));
break;
case 3:
iv3.setImageBitmap(integerBitmapMap.get(3));
break;
case 4:
iv4.setImageBitmap(integerBitmapMap.get(4));
break;
case 5:
iv5.setImageBitmap(integerBitmapMap.get(5));
break;
} }
}
});}

<pre class='brush:plain;'>

代码比较长但是逻辑并不复杂。


下面我们慢慢看并解释。首先我们得搞明白同步下载5张图片需要5个observable,因为当使用了多个subscribeOn() 的时候,只有第一个

subscribeOn()

起作用,所以我们不能在同一observable上多次指定被观察者的线程。还有就是我们使用了3个操作符。just()可以简化我们observable的创建,

map()

方法将参数中的

String

对象转换成一个

Bitmap

对象后回,

mergeWith()

操作符,两个或更多同类型的 Observable 可以合并到一起去创建一个 Observable,最后指定合并后的Observable的观察者在ui线程设置图片,弹出土司。 再给一种实现方式:

private void moreThread_2(){<br/>    final ProgressDialog pd = new ProgressDialog(SiyActivity.this);<br/>    Single.merge(Single.create(new Single.OnSubscribe<String>() {<br/>                @Override<br/>                public void call(SingleSubscriber<? super String> singleSubscriber) {<br/>                    singleSubscriber.onSuccess("http://img1.imgtn.bdimg.com/it/u=1225257463,1229468910&fm=21&gp=0.jpg");<br/>                }<br/>            }).map(new Func1<String, Map<Integer, Bitmap>>() {<br/>                @Override<br/>                public Map<Integer, Bitmap> call(String s) {<br/>                    Map<Integer, Bitmap> map = new HashMap<Integer, Bitmap>();<br/>                    map.put(1, getImageBitmap(s));<br/>                    return map;<br/>                }<br/>            }).subscribeOn(Schedulers.io()),<br/>            Single.create(new Single.OnSubscribe<String>() {<br/>                @Override<br/>                public void call(SingleSubscriber<? super String> singleSubscriber) {<br/>                    singleSubscriber.onSuccess("http://pic1a.nipic.com/2008-11-26/200811268173650_2.jpg");<br/>                }<br/>            }).map(new Func1<String, Map<Integer, Bitmap>>() {<br/>                @Override<br/>                public Map<Integer, Bitmap> call(String s) {<br/>                    Map<Integer, Bitmap> map = new HashMap<Integer, Bitmap>();<br/>                    map.put(2, getImageBitmap(s));<br/>                    return map;<br/>                }<br/>            }).subscribeOn(Schedulers.io()),<br/>            Single.create(new Single.OnSubscribe<String>() {<br/>                @Override<br/>                public void call(SingleSubscriber<? super String> singleSubscriber) {<br/>                    singleSubscriber.onSuccess("http://pic13.nipic.com/20110415/1347158_132411659346_2.jpg");<br/>                }<br/>            }).map(new Func1<String, Map<Integer, Bitmap>>() {<br/>                @Override<br/>                public Map<Integer, Bitmap> call(String s) {<br/>                    Map<Integer, Bitmap> map = new HashMap<Integer, Bitmap>();<br/>                    map.put(3, getImageBitmap(s));<br/>                    return map;<br/>                }<br/>            }).subscribeOn(Schedulers.io()),<br/>            Single.create(new Single.OnSubscribe<String>() {<br/>                @Override<br/>                public void call(SingleSubscriber<? super String> singleSubscriber) {<br/>                    singleSubscriber.onSuccess("http://img4.3lian.com/sucai/img6/230/29.jpg");<br/>                }<br/>            }).map(new Func1<String, Map<Integer, Bitmap>>() {<br/>                @Override<br/>                public Map<Integer, Bitmap> call(String s) {<br/>                    Map<Integer, Bitmap> map = new HashMap<Integer, Bitmap>();<br/>                    map.put(4, getImageBitmap(s));<br/>                    return map;<br/>                }<br/>            }).subscribeOn(Schedulers.io()),<br/>            Single.create(new Single.OnSubscribe<String>() {<br/>                @Override<br/>                public void call(SingleSubscriber<? super String> singleSubscriber) {<br/>                    singleSubscriber.onSuccess("http://img1.imgtn.bdimg.com/it/u=1225257463,1229468910&fm=21&gp=0.jpg");<br/>                }<br/>            }).map(new Func1<String, Map<Integer, Bitmap>>() {<br/>                @Override<br/>                public Map<Integer, Bitmap> call(String s) {<br/>                    Map<Integer, Bitmap> map = new HashMap<Integer, Bitmap>();<br/>                    map.put(5, getImageBitmap(s));<br/>                    return map;<br/>                }<br/>            }).subscribeOn(Schedulers.io()))<br/>         .doOnSubscribe(new Action0() {<br/>             @Override<br/>             public void call() {<br/>                 pd.show();<br/>             }<br/>         })<br/>            .subscribeOn(AndroidSchedulers.mainThread())<br/>            .observeOn(AndroidSchedulers.mainThread())<br/>            .subscribe(new Subscriber<Map<Integer, Bitmap>>() {<br/>                @Override<br/>                public void onCompleted() {<br/>                    if (pd.isShowing()) {<br/>                        pd.dismiss();<br/>                    }<br/>                    Toast.makeText(SiyActivity.this,"5张图片下载完毕",Toast.LENGTH_SHORT).show();<br/>                }                @Override<br/>                public void onError(Throwable e) {<br/>                    if (pd.isShowing()) {<br/>                        pd.dismiss();<br/>                    }<br/>                }                @Override<br/>                public void onNext(Map<Integer, Bitmap> integerBitmapMap) {<br/>                    Set<Integer> set = integerBitmapMap.keySet();                    for (Integer key : set) {<br/>                        switch (key) {<br/>                            case 1:<br/>                                iv1.setImageBitmap(integerBitmapMap.get(1));<br/>                                break;<br/>                            case 2:<br/>                                iv2.setImageBitmap(integerBitmapMap.get(2));<br/>                                break;<br/>                            case 3:<br/>                                iv3.setImageBitmap(integerBitmapMap.get(3));<br/>                                break;<br/>                            case 4:<br/>                                iv4.setImageBitmap(integerBitmapMap.get(4));<br/>                                break;<br/>                            case 5:<br/>                                iv5.setImageBitmap(integerBitmapMap.get(5));<br/>                                break;<br/>                        }                    }<br/>                }<br/>            });<br/>}

这种方法使用的是RxJava的Single 类实现的。主要思想和知识与上述方法相同,就不做解释了。 第一次写博客,水平有限,有不足之处,欢迎指出。 参考文章:给 Android 开发者的 RxJava 详解RxJava 入门
rxandroidrxjava多线程博客响应式编程

因为水平有限,难免有疏忽或者不准确的地方,希望大家能够直接指出来,我会及时改正。一切为了知识的分享。

后续会有更多的精彩的内容分享给大家。