Android比较流行框架学习

    xiaoxiao2021-03-25  121

    Retrofit+RxJava+Dagger学习使用记录。

    1.搭建服务端请求接口模块。

    a) 导入OKhttp相关jar

    compile 'com.squareup.okhttp3:okhttp:3.6.0'

    compile 'com.squareup.okio:okio:1.11.0'

    b) 导入Retrofit相关jar

    compile 'com.squareup.retrofit2:retrofit:2.2.0'

    c) 导入fastjson,测试时使用fastjson解析

    d) 增加代码:

    i. 添加HttpLoggingInterceptor方便我查看log。

    ii. 添加FastJsonConverterFactory方便我加入fastjson解析,因为Retrofit官方没有提供fastjson的解析方式,所以需要自己特别添加。

    iii. 从Retrofit2.0开始,必须添加RxJava2CallAdapterFactoryCallAdapterFactory,否则抛异常。(可以理解为Retroifit2.0已经把RxJava当作标配了)

    iv. 注意相关代码的依赖。如果没有把demo中的io/org/retrofit2中的包下的所有的代码引入工程可能会出现ClassNotFound的异常,因为虽然类在,但是类所实现的接口却不再RxJava中,所以这里一定要注意添加相关的类文件。所有的代码在这个阶段都已经拷贝至learnsumer01.rar。

     

     

    2.通过RxJava实现线程切换与中间的值的操作变换

    a) Retrofit中定义的接口返回值为Observable

    b) android中使用首先需要确定线程切换。subscribeOn(),observeOn前者指定该接口调用之前的所有的操作符运行线程,后者指定从该接口调用开始以后的操作符运行线程。通过自线程通过Schedulers.io()指定,主线程通过AndroidSchedulers.mainThread()方式指定。

    c) Map和flatMap操作符是使用比较多的两个操作符,可以在任务序列的传递过程中对值进行修改。Map和flatMap最大的区别在于map是转化后返回一个对象,而flatMap则是将传入的Observable转化为一个Observable,便于后期继续传递事件处理。

    d) 事件接收者通过subscribeWith方式注入。在Android中使用DisposableObserver创建接收者,这样返回的DisposableObserver可以通过CompositeDisposable添加至集合中,便于后期统一释放资源。

    e) 对于不使用Retrofit,自定义发射器方式的使用。

    i. 以下的这种方法是不支持背压的,发射器发送事件是没有限制的,如果接收者处理不了也照发不误,直接后果就是导致内存增大,可能OOM。

    ii. 使用Observable静态create ObservableEmitter,而后emitter调用onNext和onComplete发射事件,接收者接收。注意接收规则:

    1. 调用顺序:

    a) 接收者的onSubscribe方法

    b) 发射器的subscribe方法

    c) onNext/onComplete/onError方法,注意onCompleteonError调用互斥。

    2.接收者中可以通过dispose方式中断调用。但是上游依然会不断调用onNext这些方法,但下游不会再接收到。

    f) 对于直接使用Publisher及其子类创建的情况与上面有些不同。直接注册的是Subsciber即Pushlisher的子类。使用这种方式是支持背压的。接口上的不同是必须显示声明Buffer,onSubscribe方法中的Subscription必须调用request。而且有时候存在onNext方法调用时机在request方法之前的情况,所以初始化工作必须要在request方法之前完成。Request的参数会限制onNext/onComplete方法最大调用的次数。

    当前阶段代码earnsumer02.rar。

    3.Dagger的实现依赖的注入

    a) 首先在工程的build.gradle中,在

    dependencies{classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8'

    }加入这个插件的类路径。

    b) 在对应的Modulebuild.gradle下声明这个插件

    apply plugin: 'com.neenbedankt.android-apt'

    c) 在对应的Module的build.gradle下的dependencies下声明 compile 'com.google.dagger:dagger:2.2'

         apt 'com.google.dagger:dagger-compiler:2.2'

         compile 'org.glassfish:javax.annotation:10.0-b28' // Java标注

    d) @Inject @Component

    @Inject确定依赖和被依赖的对象。可以注解属性和方法。注解过的对象只有在使用时才会被生成相关源码,否则即使注解,但是没有使用过也不会生成任何源码。

    @Compent是连接被注入对象和依赖对象的桥梁,如果在要注入依赖的类中通过@Inject方式声明了对象,那么,除非是通过dependencies的方式依赖了其他的Component,否则,在当前的Component中必须通过接口返回对应对象类的方式声明。

    e) @Module @Provides@Module类似代理作用,解决需要被依赖对象(三方SDK或抽象/接口)无法通过构造函数初始化问题。@Provides指定创建被依赖的对象的方法。注意,如果在@Provides的方法中声明了Scope,那么在Component中也必须声明。而且如果Component存在互相依赖的关系,那么不能注解同一个Scope,需要再自定义后注解依赖其他component的那个component

    f) @Scope也是比较重要的注解,Dagger2可以通过自定义注解限定注解作用域。

    @SingletonJsr中定义的,用于标识单例,如果Module中提供的对象用Singleton注解了,则Component必须用@Singleton注解,如果该Component被其他Component依赖,则依赖的Component必须用其他Scope注解,从设计层面讲单例不能互相引用,所以在这里定义Scope可以帮助我编译过去。另外一个层面,当前我对此理解不深:如果定义Scope,则在DaggerxxxCompoenent即编译过程中生成的代码将所有的ModuleProvider都用ScopeProvider给装饰起来,这个ScopeProvider是单例模式的,而且内部保存着ModuleProvider通过@Provides方法提供的那个对象,在给多个对象做注入的时候,会将同一个依赖的对象实体注入。如果不用ScopeProvider装饰,那么在给多个对象赋值的时候,多次调用ModuleProvider的provide方法,就会导致初始话多个对象,所以从这个意义讲:在编译生成的代码范围内,使用Scope确实为我们实现了局部单例。

    g) 剩下的几个注解比较简单,使用的时候再查吧。

    这一部分对应的代码是learnsumer03.rar

     

    通过初步学习这三个框架,发现确实可以提高编程效率,优化代码,解耦模块。但是付出的代价是代码量暴增,方法数超过64k非常容易,所以要根据自己项目的需要确定技术选型。以当前我的水平以及经历来讲,我还是比较喜欢RxJava,对其他两个暂时不感冒。

     

     文章本身用word编辑,相关代码已上传(http://download.csdn.net/download/lilinwang1990/9774756)

     

     

    转载请注明原文地址: https://ju.6miu.com/read-7717.html

    最新回复(0)