RX系列四 | RxAndroid | 加载图片 | 提交表单
2017-01-02 21:50
288 查看
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 | 加载图片 | 提交表单
- Android 图像系列: 将本地图片加载到Drawable
- Android优化系列——控件优化(ListView 异步加载图片优化,SoftReference)
- Android加载/处理超大图片神器!SubsamplingScaleImageView(subsampling-scale-image-view)【系列1】
- RxAndroid和RxJava结合OkGo示例请求网络图片加载到不同ImageView
- Android开发系列:异步加载图片(一)
- Android批量图片加载经典系列——Volley框架实现多布局的新闻列表
- 网络图片加载的封装-(从零开始搭建android框架系列(4))
- 基于Http原理实现Android的图片上传和表单提交
- Android 上传图片、上传文件、提交表单 工具类
- Android批量图片加载经典系列——采用二级缓存、异步加载网络图片
- Android加载/处理超大图片神器!SubsamplingScaleImageView(subsampling-scale-image-view)【系列1】
- Android批量图片加载经典系列——使用xutil框架缓存、异步加载网络图片
- 网络图片加载的封装【从零开始搭建android框架系列(4)】
- 内存异常系列之Android解决加载大图片时内存溢出的问题
- Android批量图片加载经典系列——采用二级缓存、异步加载网络图片
- Android批量图片加载经典系列——afinal框架实现图片的异步缓存加载
- Android批量图片加载经典系列——使用二级缓存、异步网络负载形象
- 网络图片加载的封装-(从零开始搭建android框架系列(4))
- 网络图片加载的封装【从零开始搭建android框架系列(4)】