了解Dagger2,Retrofit和MVP设计模式
初始文献
初始文献中给出了源代码的git地址,可以下载哦~
针对初始文献分析的文献
本文主要针对上面两个文献再接再厉
1. DaggerAppComponent 是编译时候生成的,在生成完成后需要重新导入。
2. 另外,在阅读上面的源代码中,首先要了解一点注入的基本知识。自定义注解
如ActivityScope:
@Provides
@ActivityScope
MainActivity provideMainActivity(){
return mainActivity;
}
其中ActivityScope是自己定义的
@Scope
public @interface ActivityScope {
}
@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有描述了。
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;
}
- @Singleton 单例模式。
- Dagger的依赖结构。在参考的文献中说明如下:
Application,在AndroidManifest.xml可以看到这个application是自己定义的,因为在这个application 里面需要调用底层的网络服务。
6.1 AppModule,主要是注册了application,保证application单例。
6.2 AppComponent对象提供了全局的对象,一般是单例对象,方便其他继承这个组件的对象使用,其中调用了AppModule,ApiServiceModule,AppServiceModule.
6.3 AppApplication将AppModule还有AppComponent组织起来。
Retrofit的使用
- 在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模式下
- 上面的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());
}
}
- MainActivity的构建方式如下:
2.1 首先创建了MainActivityComponent对象,这个类似于AppComponent包含了各种需要提供的实例。
2.2 MainActivityModule则提供了相应的方法提供presenter和activity。
2.3 mainActivityPresenter提供了对应的方法来展示数据。
总结
在上面的方法中,分析下来感觉用到的模块比较多,用到了注释的知识,还有retrofit的网络知识获取,还讲到了MVP。 比较重要的应该是Dagger2的注释了,这个可以重点关注下。 MVP这个结构没有MVC清楚,后面还需要更进一步讨论。