Dagger2, Retrofit和MVP设计模式案例分析

了解Dagger2,Retrofit和MVP设计模式

初始文献
初始文献中给出了源代码的git地址,可以下载哦~
针对初始文献分析的文献

本文主要针对上面两个文献再接再厉
1. DaggerAppComponent 是编译时候生成的,在生成完成后需要重新导入。
2. 另外,在阅读上面的源代码中,首先要了解一点注入的基本知识。自定义注解
如ActivityScope:

@Provides
    @ActivityScope
    MainActivity provideMainActivity(){
        return mainActivity;
    }

其中ActivityScope是自己定义的

@Scope
public @interface ActivityScope {
}
  1. Dagger2 的@Component 方法也与之前有所变化,参考链接1
    具体可以参考dagger下面的component.java中的注释。
@ActivityScope
@Component(modules = MainActivityModule.class, dependencies = AppComponent.class)
public interface MainActivityComponent{
    MainActivity inject(MainActivity mainActivity);
    MainActivityPresenter presenter();
}

上面是个接口MainActivityComponent,最后会生成DaggerMainActivityComponent.class,然后在MainActivity被调用,可以看到这里@component()中的参数是builder中的参数并且需要传入。其中inject是上面component定义的方法。

DaggerMainActivityComponent.builder()
                .appComponent(appComponent)
                .mainActivityModule(new MainActivityModule(this))
                .build()
                .inject(this)

可以查看DaggerMainActivityComponent生成的内容在参考链接1有描述了。

  1. 在data中有如下文件,其中@GET是retrofit中定义的方法,这个retrofit的版本是1.9参考链接
    具体的retrofit使用见后面,这里仅介绍注释的语法。
public interface ApiService {
    @GET("/users")
    public void getUsers(Callback<List<User>> callback);
}

在retrofit中定义如下,
@Documented 表明这个注解应该被 javadoc工具记录

@Target(METHOD) 元注解即不能再被注解,用ElementType中定义的枚举来说明当前定义的是什么
ElementType包含如下:TYPE,FIELD,METHOD,PARAMETER,CONSTRUCTOR,LOCAL_VARIABLE,ANNOTATION_TYPE,PACKAGE
这里method表明是用于方法

@Retention 元注解,用RetentionPolicy定义的SOURCE(仅保留在class),CLASS(保留在class和dex),RUNTIME(放在dex,运行时也会读取)表明该注解在什么时候被使用。

String value() 定义了变量为value,可以认为是传入的参数“/users”,这个是在自定义Annotation里面定义的格式。
其他类名/标准单元类 变量名() default 默认值;

@RestMethod(“GET”) 是这个GET的注解,具体见后面。

/** Make a GET request to a REST path relative to base URL. */
@Documented 
@Target(METHOD)
@Retention(RUNTIME)
@RestMethod("GET")
public @interface GET {
  String value();
}

RestMethod的注解,value是传入的”GET”,boolean变量hasBody默认值是false.

@Documented
@Target(ANNOTATION_TYPE)
@Retention(RUNTIME)
public @interface RestMethod {
  String value();
  boolean hasBody() default false;
}
  1. @Singleton 单例模式。
  2. Dagger的依赖结构。在参考的文献中说明如下:
    Application,在AndroidManifest.xml可以看到这个application是自己定义的,因为在这个application 里面需要调用底层的网络服务。
    6.1 AppModule, 主要是注册了application,保证application单例。
    6.2 AppComponent对象提供了全局的对象,一般是单例对象,方便其他继承这个组件的对象使用,其中调用了AppModule,ApiServiceModule, AppServiceModule.
    6.3 AppApplication将AppModule还有AppComponent组织起来。

Retrofit的使用

  1. 在ApiServiceModule中定义了okHttpClient,并将client传入给provideRestAdapter,用来构建RestAdpater。
@Provides
    @Singleton
    RestAdapter provideRestAdapter(Application application, OkHttpClient okHttpClient){
        RestAdapter.Builder builder = new RestAdapter.Builder();
        builder.setClient(new OkClient(okHttpClient))
                .setEndpoint(ENDPOINT);
        return builder.build();
    }

在生成好接口后就需要去生成那个具体的实例类如下

@Provides
    @Singleton
    ApiService provideApiService(RestAdapter restAdapter){
        return restAdapter.create(ApiService.class);
    }

了解了上面的注释后,需要集中注意在MVP模式下

  1. 上面的data 和model合起来提供了Application,其中的数据是从底层retrofit获取的。然后看下这里的View应该是MainActivity提供。
    这里同样@InjectView是Butterknife给textView赋值
    @Inject是javax注入,等待presenter实例准备好。主要的代码是onCreate中的presenter.showUserName()完成了代码呈现。

public class MainActivity extends BaseActivity {

    @InjectView(R.id.tv)
    TextView textView;

    @Inject
    MainActivityPresenter presenter;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ButterKnife.inject(this);
        presenter.showUserName();
    }
    @Override
    protected void setupActivityComponent(AppComponent appComponent) {
        DaggerMainActivityComponent.builder()
                .appComponent(appComponent)
                .mainActivityModule(new MainActivityModule(this))
                .build()
                .inject(this);
    }
    public void setTextView(String username){
        textView.setText(username);
    }
}

但是这里presenter里面调用了MainActivity里面的方法,因为那个textView等UI的更新只能在View层进行,所以presenter里面有MainActivity的实例化。这就是在上面MainActivity里面需要等待这个presenter准备好。

public class MainActivityPresenter {

    private MainActivity mainActivity;
    private User user;

    public MainActivityPresenter(MainActivity mainActivity, User user) {
        this.mainActivity = mainActivity;
        this.user = user;
    }

    public void showUserName(){
        mainActivity.setTextView(user.getName());
    }
}
  1. MainActivity的构建方式如下:
    2.1 首先创建了MainActivityComponent对象,这个类似于AppComponent包含了各种需要提供的实例。
    2.2 MainActivityModule则提供了相应的方法提供presenter和activity。
    2.3 mainActivityPresenter提供了对应的方法来展示数据。

总结

在上面的方法中,分析下来感觉用到的模块比较多,用到了注释的知识,还有retrofit的网络知识获取,还讲到了MVP。
比较重要的应该是Dagger2的注释了,这个可以重点关注下。
MVP这个结构没有MVC清楚,后面还需要更进一步讨论。

猜你喜欢

转载自blog.csdn.net/xsjyahoo/article/details/51470967
今日推荐