There is no royal road to learning

p5.jpg

p1.jpg

p2.jpg

p3.jpg

p4.jpg

框架学习

1.RxJava

RxJava的GitHub托管地址
RxAndroid的GitHub托管地址

RxJavad 使用方面的简单总结:

1、RxJava的基本概念: Observable(可观察者,即被观察者)、Observer (观察者)、subscribe (订阅)、事件。ObservableObserver通过 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(调度器)设置SubscriberObservable运行线程

在 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()的原理是这样的:
  1. 使用传入的事件对象创建一个 Observable对象;
  2. 并不发送这个 Observable, 而是将它激活,于是它开始发送事件;
  3. 每一个创建出来的 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在Github上的托管地址
Retrofit官网

** 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 配置

3.RxJava + Retrofit

RxJava + Retrofit

4.事件总线
(1)EventBus

EventBus在github上的托管地址
EventBus官网

5. SnappyDB
6. FaceBook推出的Stetho

借助Stetho在Chrome上调试Android网络&数据库

7.图片加载框架

Glide的github托管地址

React Native

微信小程序

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 157,924评论 4 360
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 66,902评论 1 290
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 107,716评论 0 239
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,783评论 0 203
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,166评论 3 286
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,510评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,784评论 2 311
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,476评论 0 196
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,196评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,459评论 2 243
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,978评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,321评论 2 252
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,964评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,046评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,803评论 0 193
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,530评论 2 271
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,420评论 2 265

推荐阅读更多精彩内容