满堂花醉三千客,一剑霜寒十四州。这篇文章主要讲述RX系列四 | RxAndroid | 加载图片 | 提交表单相关的知识,希望能为你提供帮助。
RX系列四 | Rxandroid | 加载图片 | 提交表单
说实话,
学Rxjava就是为了我们在Android中运用的更加顺手一点,
也就是RxAndroid,
我们还是先一步步来,
学会怎么去用的比较好,
之前的三篇算是铺垫,
让你有一点认识,
那Rx在Android中有什么好处呢?
我们先模拟一些原始功能和他对比下
一.加载图片 【RX系列四 | RxAndroid | 加载图片 | 提交表单】很多人说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
推荐阅读
- 继续坑坑坑(关于购买的证书 若不添加中级证书 安卓出现无法发起请求)
- android Studio 百度KEY获得发布版 SHA1 的方法
- Android Touch事件传递机制详解
- 锤子T1(Smartisan T1 4G)版刷成3G版,即sm705运行sm701的CM11 Android 4.4.4ROM     
- android 获取屏幕宽度和高度
- Android如何做到应用程序图标隐藏,由第三方程序启动
- Activity详解生命周期(Android)
- Android开发之InstanceState详解
- 在Android项目中引入MuPdf