可能很多朋友对Rxjava并不陌生,也有很多朋友会用,但是却不懂很多原理和意思,只是停留在使用,在实际项目开发中可能遇到了一些问题, 就有点不知道是什么原因了。 好了废话不多说了,接下来进行正文。 先说一下用于创建Observable的操作符
用于创建Observable的操作符
Create
通过调用观察者的方法从头创建一个Observable
Empty/Never/Throw
创建行为受限的特殊Observable
Defer
在观察者订阅之前不创建这个Observable,为每一个观察者创建一个新的Observable
Just
将对象或者对象集合转换为一个会发射这些对象的Observable
From
将其它的对象或数据结构转换为Observable
Range
创建发射指定范围的整数序列的Observable,range操作符,发射从start开始的count个数
Interval
间隔一定时间发送一个数字,从0开始.本身运行在Schedulers.computation() 线程内
Repeat
Repeat作用在Observable上,会对其重复发射count次
Timer
Timer会在指定时间后发射一个数字0,注意其也是运行在computation Scheduler
先说下实际项目开发中用到的比较多的,举几个简单的例子来说明一下。我们每个应用都会有推送升级新版本功能,当然也少不了去服务器下载新版本,如果使用Rxjava来实现,你会发现非常优雅简介 话不多说,先上代码
public static ObservabledownloadApkFile(final String url, final String version) { return Observable.defer(new Func0 >() { @Override public Observable call() { try { return Observable.just(Engine.getInstance().getDownloadApi().downloadFile(url).execute().body().byteStream()); } catch (Exception e) { return Observable.error(e); } } }).map(new Func1 , File>() { @Override public File call(InputStream inputStream) { return StorageUtil.saveApk(inputStream, version); } }).subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()); }
在这里我们看到我们defer 在观察者订阅之前不创建这个Observable,为每一个观察者创建一个新的Observable
在这个call里面我们去联网下载新版文件 在这里我们用just 将对象或者对象集合转换为一个会发射这些对象的Observable
然后在下载完成之后 我们用map操作符 映射,通过对序列的每一项都应用一个函数变换Observable发射的数据,实质是对序列中的每一项执行一个函数,函数的参数就是这个数据项,在call里面保存我们刚才下载好的apk文件 ,这里的
subscribeOn指定Observable应该在哪个调度程序上执行 前面都是在io线程执行操作。
observeOn指定Subscriber的调度程序(工作线程)最后我们转换到ui线程可以进行界面提示,或者其它逻辑
在这里我们可以
Util.downloadApkFile(mApkUrl, mNewVersion) .compose(this.bindToLifecycle()) .subscribe(new Subscriber () { @Override public void onStart() { showDownloadingDialog(); } @Override public void onCompleted() { dismissDownloadingDialog(); } @Override public void onError(Throwable e) { dismissDownloadingDialog(); } @Override public void onNext(File apkFile) { Util.installApk(apkFile); } });
直接在需要下载apk的时候调用我们刚才写的那个方法,在onStart时候可以用于展示我们下载的进度条,在onCompleted和onError里面隐藏我们的进度条,最后在onNext成功里面进行我们的apk安装,整个过程行云流水
最后附上 安装apk代码 ,注意要进行判断,因为在7.0系统上安装可能会出现问题
/** * 安装 apk 文件 * * @param apkFile */ public static void installApk(File apkFile) { Intent installApkIntent = new Intent(); installApkIntent.setAction(Intent.ACTION_VIEW); installApkIntent.addCategory(Intent.CATEGORY_DEFAULT); installApkIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); if (Build.VERSION.SDK_INT > Build.VERSION_CODES.M) { installApkIntent.setDataAndType(FileProvider.getUriForFile(sApp, PermissionUtil.getFileProviderAuthority(), apkFile), MIME_TYPE_APK); installApkIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); } else { installApkIntent.setDataAndType(Uri.fromFile(apkFile), MIME_TYPE_APK); } if (sApp.getPackageManager().queryIntentActivities(installApkIntent, 0).size() > 0) { sApp.startActivity(installApkIntent); } }
getFileProviderAuthority
这段代码
/** * 获取FileProvider的auth * * @return */ static String getFileProviderAuthority() { try { for (ProviderInfo provider : sApp.getPackageManager().getPackageInfo(sApp.getPackageName(), PackageManager.GET_PROVIDERS).providers) { if (FileProvider.class.getName().equals(provider.name) && provider.authority.endsWith(".bga_update.file_provider")) { return provider.authority; } } } catch (PackageManager.NameNotFoundException ignore) { } return null; }
整个过程就是这样简洁明了 ,Rxjava在你逻辑更复杂的情况,他的简洁性更明了,下一篇,我会接下来再讲解其它操作符在实际开发中的应用
我也是新手一个 O(∩_∩)O哈哈~ 以上不对的地方请指教出来,我好及时改进, 如果觉得对你有用的话 点个赞吧O(∩_∩)