There is no royal road to learni
p1.jpg
p2.jpg
p3.jpg
p4.jpg
框架学习
1.RxJava
RxJavad 使用方面的简单总结:
1、RxJava的基本概念:
Observable
(可观察者,即被观察者)、Observer
(观察者)、subscribe
(订阅)、事件。Observable
和Observer
通过subscribe()
方法实现订阅关系,从而Observable
可以在需要的时候发出事件来通知Observer
。
2、观察者模式:
Observable
(可观察者,即被观察者)、Observer
(观察者)的创建,以及两者之间订阅关系的建立。
Observer
的创建:
/** * 观察者,用于监听被观察者 */
Observer<String> observer = new Observer<String>() {
@Override
public void onCompleted() {
//事件队列完结时候调用;
}
@Override
public void onError(Throwable e) {
// 事件队列异常的时候调用 }
@Override
public void onNext(String s) {
// 事件发出时,调用。需要触发 onCompleted() 方法作为标志。
}
};
实际使用中并观察者用的一般是`Observer`的子类`Subscriber`。`Subscriber`除了具备`Observer`的几个方法外,还增加一些新的特性。如加入了`onStart()`方法。在这个方法里面可以做一些准备工作等等。更主要的一点是,Observer在 subscribe()过程中最终会被转换成 Subscriber对象
Subscriber
的创建:
- 订阅者(Subscriber实现了Observer观察者,处理能力比Observer更完善。推荐使用)
*/
Subscriber<String> subscriber = new Subscriber<String>() {
@Override
public void onStart() {
super.onStart();
}
@Override
public void onCompleted() {
}
@Override
public void onError(Throwable e) {
}
@Override
public void onNext(String s) {
}
};
>`Observable`(可观察者,即被观察者)的创建方式有�三种方式
>
>第一种方式,通过`Observable`的`create()`方法创建:
> ```
> Observable observable = Observable.create(new Observable.OnSubscribe<String>() {
@Override
public void call(Subscriber<? super String> subscriber) {
subscriber.onNext("Hello");
subscriber.onNext("RxJava");
subscriber.onCompleted();
}
});
> ```
>第二种方式,通过`Observable`的`�just()`方法创建:
> ```
Observable observable = Observable.just("Hello", "RxJava") ;
第三种方式,通过
Observable
的�from()
方法创建:
// 方式三,将传入的数组拆分成单个对象发送出去
String[] content = {"Hello","RxJava"};
Observable observable = Observable.from(content);
`Observer`(或者`Subscriber`)与`Observable`之间订阅关系的建立:
observable.subscribe(observer);或者observable.subscribe(subscriber);
> 事件的订阅看上去好像是颠倒了对象关系。被观察者通过订阅绑定了观察者。上述这种方式是采用的流式 API 的设计方式。如果采用常规的逻辑实现订阅,会对流式 API 的设计造成影响,比较起来明显是得不偿失的。
>
> 除了 subscribe(Observer)和 subscribe(Subscriber),subscribe()还支持不完整定义的回调,RxJava 会自动根据定义创建出Subscriber。形式如下:
>```
Action1<String> onNextAction = new Action1<String>() {
// onNext()
@Override
public void call(String s) {
Log.d(tag, s);
}
};
Action1<Throwable> onErrorAction = new Action1<Throwable>() {
// onError()
@Override
public void call(Throwable throwable) {
// Error handling
}
};
Action0 onCompletedAction = new Action0() {
// onCompleted()
@Override public void call() {
Log.d(tag, "completed");
}
};
// 自动创建 Subscriber ,并使用 onNextAction 来定义
onNext()observable.subscribe(onNextAction);
>
// 自动创建 Subscriber ,并使用 onNextAction 和 onErrorAction 来定义 onNext() 和 onError()
observable.subscribe(onNextAction, onErrorAction);
>
// 自动创建 Subscriber ,并使用 onNextAction、 onErrorAction 和
// onCompletedAction 来定义 onNext()、 onError() 和 onCompleted()
observable.subscribe(onNextAction, onErrorAction, onCompletedAction);
3、Scheduler(调度器)设置
Subscriber
和Observable
运行线程在 RxJava 的默认规则中,事件的发出和消费都是在同一个线程的。也就是说,如果只用上面的方法,实现出来的只是一个同步的观察者模式。观察者模式本身的目的就是『后台处理,前台回调』的异步机制,因此异步对于 RxJava 是至关重要的。而要实现异步,则需要用到 RxJava 的另一个概念: Scheduler。
在不指定线程的情况下, RxJava 遵循的是线程不变的原则,即:在哪个线程调用 subscribe(),就在哪个线程生产事件;在哪个线程生产事件,就在哪个线程消费事件。如果需要切换线程,就需要用到 Scheduler(调度器)。
RxJava 已经内置了几个 Scheduler,它们已经适合大多数的使用场景:Schedulers.immediate(): 直接在当前线程运行,相当于不指定线程。这是默认的 Scheduler。
- **Schedulers.newThread(): **总是启用新线程,并在新线程执行操作。
- Schedulers.io(): I/O 操作(读写文件、读写数据库、网络信息交互等)所使用的 Scheduler。行为模式和 newThread()差不多,区别在于 io()的内部实现是是用一个无数量上限的线程池,可以重用空闲的线程,因此多数情况下 io()比 newThread()更有效率。不要把计算工作放在 io()中,可以避免创建不必要的线程。
-
Schedulers.computation(): 计算所使用的 Scheduler。这个计算指的是 CPU 密集型计算,即不会被 I/O 等操作限制性能的操作,例如图形的计算。这个 Scheduler使用的固定的线程池,大小为 CPU 核数。不要把 I/O 操作放在 computation()中,否则 I/O 操作的等待时间会浪费 CPU。
另外, Android 还有一个专用的 AndroidSchedulers.mainThread(),它指定的操作将在 Android 主线程运行。
有了这几个 Scheduler,就可以使用 subscribeOn()和 observeOn()两个方法来对线程进行控制了。
- **subscribeOn(): **指定subscribe()所发生的线程即 Observable.OnSubscribe被激活时所处的线程。或者叫做事件产生的线程。
- **observeOn(): **指定Subscriber所运行在的线程。或者叫做事件消费的线程。
代码示例:
Observable observable = Observable.create(new Observable.OnSubscribe<String>() {
@Override
public void call(Subscriber<? super String> subscriber) {
subscriber.onNext("Hello");
subscriber.onNext("RxJava");
subscriber.onCompleted();
}
}).subscribeOn(Schedulers.io())//observable 被观察者运行在I/O线程
.observeOn(AndroidSchedulers.mainThread());//Subscriber的回调运行在UI线程,即主线程
**4、变换** RxJava 提供了对事件序列进行变换的支持,这是它的核心功能之一,也是大多数人说『RxJava 真是太好用了』的最大原因。**所谓变换,就是将事件序列中的对象或整个序列进行加工处理,转换成不同的事件或事件序列。也就是在事件发生和事件消费之间,将事件序列中的对象进行转换**。 **①**通过`map()`进行转换: 代码示例:
observable.just("images/logo.png") // 输入类型 String
.map(new Func1<String, Bitmap>() {//String 是传入的参数类型,Bitmap返回参数类型
@Override
public Bitmap call(String filePath) { // 参数类型 String
return getBitmapFromPath(filePath); // 返回类型 Bitmap
}
}).subscribe(new Action1<Bitmap>() {
@Override
public void call(Bitmap bitmap) { // 参数类型 Bitmap
showBitmap(bitmap);
}
});
② `flatMap()` flatMap()的原理是这样的:
- 使用传入的事件对象创建一个 Observable对象;
- 并不发送这个 Observable, 而是将它激活,于是它开始发送事件;
- 每一个创建出来的 Observable发送的事件,都被汇入同一个 Observable,而这个 Observable负责将这些事件统一交给 Subscriber的回调方法。这三个步骤,把事件拆成了两级,通过一组新创建的 Observable将初始的对象『铺平』之后通过统一路径分发了下去。而这个『铺平』就是 flatMap()
所谓的 flat。
主要作用就是嵌套处理事件对象
** 关于线程切换的问题**
可以通过observeOn()
在map()
之前调用来切换map()
运行的线程。如果调用subscribeOn()
设置,则无需关心放的位置,subscribeOn()
只会执行一次,并且设置了subscribeOn()
之后不通过observeOn()
切换的话,事件的发出和map()
变化都是在subscribeOn()
设置的线程中运行。
Observable.just(1, 2, 3, 4) // IO 线程,由 subscribeOn() 指定
.subscribeOn(Schedulers.io())
.observeOn(Schedulers.newThread())
.map(mapOperator) // 新线程,由 observeOn() 指定
.observeOn(Schedulers.io())
.map(mapOperator2) // IO 线程,由 observeOn() 指定
.observeOn(AndroidSchedulers.mainThread)
.subscribe(subscriber); // Android 主线程,由 observeOn() 指定
算了篇幅太大,下面内容还是详看[给 Android 开发者的 RxJava 详解](http://toutiao.io/shares/609182/url)吧
RxJava的管理组件的生命周期,防止内存泄露
RxLifecycle
RxBus:利用RxJava实现事件总线
2.Retrofit / OKHttp3
** Retrofit注解**
** 方法注解,包含@GET、@POST、@PUT、@DELETE、@PATH、@HEAD、@OPTIONS、@HTTP。
** 标记注解,包含@FormUrlEncoded、@Multipart、@Streaming。
** 参数注解**,包含@Query,@QueryMap、@Body、@Field,@FieldMap、@Part,@PartMap。
其他注解,@Path、@Header,@Headers、@Url
@Path
作用:用于替换Url路径中的变量字符
示例:
@GET(“/unableape/url/{name}/get”)
Call getUnableApeName(@Header(“Authorization”) String authorization,@Path(“name”) String name );
@Query
作用:用于拼接在Url路径后的查询参数,但相对于直接在Url后拼接,@Query则是添加一个变量
示例:
@GET(“/unableape/url/get?name=”unableape”)
Call getUnableApeName(@Header(“Authorization”) String authorization);
等同于
@GET(“/unableape/url/get)
Call getUnableApeName(@Header(“Authorization”) String authorization,@Query(“name”) String name);
@QueryMap
作用:效果等同于多个@Query 参数为Map类型
示例:
@GET(“/unableape/url/get”)
Call getUnableApeOther(@QueryMap Map String, String> options);
@Body
请求方式:POST
所用:可以指定一个对象作为HTTP请求体
示例:
@Body @POST(“/unableape/post”)
Call createUser(@Body Name name);
@FormUrlEncoded/@Field
请求方式:POST
作用:@FormUrlEncoded修饰表单域,每个表单域子件key-value采用@Field修饰
示例:
@FormUrlEncoded
@POST(“/user/edit”)
Call updateUnableApeName(@Field(“first_name”) String first, @Field(“last_name”) String last);
@Part,@PartMap
请求方式:POST
作用:文件上传。其中@Part MultipartBody.Part代表文件,@Part(“key”) RequestBody代表参数。需要添加@Multipart表示支持文件上传的表单,Content-Type: multipart/form-data
示例:
@Multipart
@POST("upload")
Call<ResponseBody> upload(@Part("description") RequestBody description,
@Part MultipartBody.Part file);
@Header
作用:header处理,不能被互相覆盖,用于修饰参数,
示例:
//动态设置Header值
@GET("user")
Call<User> getUser(@Header("Authorization") String authorization)
等同于
//静态设置Header值
@Headers("Authorization: authorization")//这里authorization就是上面方法里传进来变量的值
@GET("widget/list")
Call<User> getUser()
@HTTP
可以替代其他方法的任意一种
/**
* method 表示请的方法,不区分大小写
* path表示路径
* hasBody表示是否有请求体
*/
@HTTP(method = "get", path = "users/{user}", hasBody = false)
Call<ResponseBody> getFirstBlog(@Path("user") String user);
@Url
作用:使用全路径复写baseUrl,适用于非统一baseUrl的场景。
示例:
@GET
Call<ResponseBody> v3(@Url String url);
@Streaming
作用:用于下载大文件
示例:
@Streaming
@GET
Call<ResponseBody> downloadFileWithDynamicUrlAsync(@Url String fileUrl);
ResponseBody body = response.body();
long fileSize = body.contentLength();
InputStream inputStream = body.byteStream();
//编译RxJava
compile 'io.reactivex:rxjava:1.1.6'
//编译RxAndroid
compile 'io.reactivex:rxandroid:1.2.1'
//编译Retrofit及其相关库,包括Gson
compile 'com.squareup.okhttp3:okhttp:3.3.1'
compile 'com.squareup.retrofit2:retrofit:2.1.0'
compile 'com.squareup.retrofit2:converter-gson:2.1.0'
compile 'com.squareup.retrofit2:adapter-rxjava:2.1.0'
compile 'com.squareup.okhttp3:logging-interceptor:3.3.1'
注:有关Retrofit的gradle依赖参考Square官网的Retrofit
Retrofit 2.0: The biggest update yet on the best HTTP Client Library for Android
Retrofit最佳实践
Retrofit 2.0 + OkHttp 3.0 配置
- Android 初识Retrofit
- Android Retrofit 实现文字(参数)和多张图片一起上传
- Retrofit2.0使用总结及注意事项
- Retrofit系列文章翻译
- Retrofit笔记
- 揭开Retrofit的神秘面纱
- Android 你必须了解的网络框架Retrofit2.0
3.RxJava + Retrofit
4.事件总线
(1)EventBus
5. SnappyDB
6. FaceBook推出的Stetho
借助Stetho在Chrome上调试Android网络&数据库