█ 【安卓学习之RxJava】倒计时RxCountDown
█ 相关文章:
-
● 【安卓学习之第三方库】库的使用2-jar类库的使用(以dom4j为例)和升级(以极光推送为例)
█ 读前说明:
-
● 本文通过学习别人写demo,学习一些课件,参考一些博客,’学习相关知识,如果涉及侵权请告知
● 本文只简单罗列相关的代码实现过程
● 涉及到的逻辑以及说明也只是简单介绍,主要当做笔记,了解过程而已
█ 简介:
-
● ReactiveX:
ReactiveX是Reactive Extensions的缩写,一般简写为Rx。Rx是一个编程模型,目标是提供一致的编程接口,帮助开发者更方便的处理异步数据流
它是个编程接口(提供一系列函数样式的方法供快速开发),不同语言提供不同实现。例如Java中的RxJava。
在异步编程设计中使用。例如开启子线程处理耗时的网络请求。
基于可观察的事件流。例如观察者模式(即定义对象间一种一对多的依赖关系,当一个对象改变状态时,则所有依赖它的对象都会被改变)中观察者对被观察者的监听。
● RxJava:
RxJava是ReactiveX的一种Java的实现形式,基于观察者模式实现的异步操作,
可以用它替代AsyncTask和Handler(用于异步操作的原生方法,代码结构混乱,可读性差),使代码更简洁
● 观察者Observer和被观察者模式Observable:
观察者模式:简单来说,当对象A对对象B进行进行了类似“订阅”关系,当对象B的数据发生改变时,就要通知对象A进行相应。
1.观察者需要实现Observer接口,当数据发生改变时,观察者的update()方法就会被调用;
2.被观察者继承Observable类,在数据发生改变时,需要调用setChanged(); this.notifyObservers(obj);这两个方法才可以通知观察者:你想要知道的数据发生了变化了。
█ 倒计时:
-
● 场景:app启动时的广告、首页
● 创建一个RxCountDown.java:
public class RxCountDown {
public static Observable<Integer> countdown(int time) {
if (time < 0) time = 0;
final int countTime = time;
return Observable.interval(0, 1, TimeUnit.SECONDS)// 首次执行延时时间 、 每次轮询间隔时间 、 时间类型
// 线程控制,线程切换
.subscribeOn(AndroidSchedulers.mainThread())// 每个被观察者observable对象即事件产生的线程
.observeOn(AndroidSchedulers.mainThread())// 每个观察者Subscriber(Observer)即事件消费的线程
.map(new Function<Long, Integer>() {
@Override
public Integer apply(Long increaseTime) throws Exception {
return countTime - increaseTime.intValue();// 实现单类型转换,输出倒计时
}
})
.take(time+1);// 控制整个循环的次数time+1
}
}
● 使用:
RxCountDown.countdown(5).doOnSubscribe(new Consumer<Disposable>() {
@Override
public void accept(Disposable disposable) throws Exception {
Log.e("RxCountDown","初始化");
}
}).subscribe(new Consumer<Integer>() {
@Override
public void accept(Integer integer) throws Exception {
Log.e("RxCountDown","倒计时:"+integer + "秒");
// textView.setText(integer + "秒");
}
}, new Consumer<Throwable>() {
@Override
public void accept(Throwable throwable) throws Exception {
Log.e("RxCountDown","异常:"+throwable.getMessage());
}
}, new Action() {
@Override
public void run() throws Exception {
Log.e("RxCountDown","倒计时结束!");
//startActivity(intent);
//finish();
}
});
● replaced with lambda:
RxCountDown.countdown(5)
.doOnSubscribe(disposable -> {
Log.e("RxCountDown","初始化");
})
.subscribe(integer -> {
Log.e("RxCountDown","倒计时:"+integer + "秒");
//textView.setText(integer + "秒");
}, throwable -> {
Log.e("RxCountDown","异常:"+throwable.getMessage());
}, () -> {
Log.e("RxCountDown","倒计时结束!");
//startActivity(intent);
//finish();
});
● 运行结果:
E/RxCountDown: 初始化
E/RxCountDown: 倒计时:5秒
E/RxCountDown: 倒计时:4秒
E/RxCountDown: 倒计时:3秒
E/RxCountDown: 倒计时:2秒
E/RxCountDown: 倒计时:1秒
E/RxCountDown: 倒计时:0秒
E/RxCountDown: 倒计时结束!
`
█ 网络请求应用:
-
● 直接上测试代码:
Log.e("##测试代码", "点击 测试按钮");
// 一次性观察者
Observer<String> observer = new DisposableObserver<String>() {
@Override
public void onNext(String request) {
Log.e("##测试代码", "onNext :"+request);
}
@Override
public void onError(Throwable e) {
Log.e("##测试代码", "onError :"+e.getMessage());
}
@Override
public void onComplete() {
Log.e("##测试代码", "onComplete ");
}
};
Observable
.create((ObservableOnSubscribe<String>) emitter -> {
Log.e("##测试代码", "emitter :发送信息");
emitter.onNext("我是来做测试的。。可以收到吗?");
})
.subscribeOn(Schedulers.newThread())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(observer);
Log.e("##测试代码", "测试按钮 执行中....");
● 运行结果:
E/##测试代码: 点击 测试按钮
E/##测试代码: 测试按钮 执行中....
E/##测试代码: emitter :发送信息
E/##测试代码: onNext :我是来做测试的。。可以收到吗?
`
● 加入网络请求:
Log.e("##测试代码", "点击 测试按钮");
// 一次性观察者
Observer<String> observer = new DisposableObserver<String>() {
@Override
public void onNext(LoginResult loginResult) {
Log.e("##测试代码", "onNext :"+ new Gson().toJson(loginResult));
Toast.makeText(LoginActivity.this, "登录成功", Toast.LENGTH_SHORT).show();
MyApplication.login = true;
MyApplication.account = name;
MyApplication.password = password;
MyApplication.vipDate = loginResult.getExpirationDate();
MyApplication.token = loginResult.getToken();
...跳转到首页...
}
@Override
public void onError(Throwable e) {
Log.e("##测试代码", "onError :"+e.getMessage());
}
@Override
public void onComplete() {
Log.e("##测试代码", "onComplete ");
}
};
Observable.create((ObservableOnSubscribe<String>) emitter -> {
Log.e("##测试代码", "emitter :发送信息");
try {
String requestBody = "username=" + username + "&password=" + password;
requestBody += "&deviceModel=" + android.os.Build.MODEL;
MediaType mediaType = MediaType.parse("application/x-www-form-urlencoded");
RequestBody body = RequestBody.create(mediaType, requestBody);
Request request = new Request.Builder()
.url(LOGIN_URL)
.post(body)
.addHeader("Content-Type", "application/x-www-form-urlencoded")
.build();
OkHttpClient client = new OkHttpClient.Builder()
.readTimeout(8000, TimeUnit.MILLISECONDS)
.writeTimeout(8000, TimeUnit.MILLISECONDS)
.sslSocketFactory(SSLCertificate.SSLSocketFactorygetSSLSocketFactory())
.build();
Response response = client.newCall(request).execute();// 同步请求(不能在UI线程执行网络操作)
if (response.isSuccessful() && response.body() != null) {
String result = response.body().string();
emitter.onNext(new Gson().fromJson(result, LoginResult.class));
}
} catch (Exception e) {
e.printStackTrace();
}
})
.subscribeOn(Schedulers.newThread())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(observer);
Log.e("##测试代码", "测试按钮 执行中....");
● 这边登录请求也可以写成这样:
FormBody formBody = new FormBody.Builder()
.add("username", username)
.add("password", password)
.add("deviceModel", android.os.Build.MODEL).build();
Request request = new Request.Builder()
.url(LOGIN_URL)
.post(formBody)
.build();
OkHttpClient client = new OkHttpClient()
client.newCall(request).enqueue(new Callback() {// 异步请求
@Override
public void onFailure(Call call, IOException e) {
}
@Override
public void onResponse(Call call, Response response) throws IOException {
// 不是UI线程
if (response.isSuccessful()) {
String result = response.body().string();
emitter.onNext(new Gson().fromJson(result, LoginResult.class));
......
} else {
}
}
});
█ 相关资料:
-
● 1.2018.04.06 17:34:32 RxJava——入门篇 - 简书
● 2.2018-01-31 14:22 Android之观察者/被观察者模式Observer/Observable - WidgetBox - 博客园
● 3.2017-03-17 11:07:05 Java定时总结(Rx一行代码解决orz)_菜鸟实验室-CSDN博客
转载请注明出处:
https://blog.csdn.net/ljb568838953/article/details/108821640