今天推荐两个开源项目ownspace和MusicDNA
ownspace是一款高仿单读的APP,模仿得非常精美,基于MVP+Dagger2+Retrofit2.0+Rxjava。今天推荐这个APP是因为里面经常会推荐一些有深度的文章、一些有代表性的歌曲和一些精美的视频讲解。第一步还是先看一下开发者用到那些好的开源库
表格如下图:
库名 | 简介 |
---|---|
io.reactivex:rxjava io.reactivex:rxandroid | rxjava和rxandroid开发基本库 |
com.squareup.retrofit2:retrofit com.squareup.retrofit2:adapter-rxjava com.squareup.retrofit2:converter-gson | retrofit相关库 |
com.squareup.okhttp3:okhttp com.squareup.okhttp3:logging-interceptor | okhttp3相关库 |
net.danlew:android.joda | Joda-Time提供了一组Java类包用于处理包括ISO8601标准在内的date和time |
com.squareup.sqlbrite:sqlbrite | SQLBrite:一个响应式的数据查询框架,完美解决数据库和UI的同步更新 |
com.github.bumptech.glide:glide | google开源图片加载库 |
com.orhanobut:logger | 日志打印库 |
com.elyeproj.libraries:loaderviewlibrary | 类似于facebook的内容预加载效果,先闪烁显示内容占据的区域,等加载完成后显示实际内容 |
in.srain.cube:ultra-ptr | 下拉刷新库 |
org.jsoup:jsoup | jsoup 是一款Java 的HTML解析器,可直接解析某个URL地址、HTML文本内容 |
pub.devrel:easypermissions | Easypermissions简化了Android M的运行时权限的申请、结果处理、判断等步骤 |
com.wang.avi:library | AVLoadingIndicatorView是一个实现了各种各样加载效果的库,每一种效果都很精美 |
fm.jiecao:jiecaovideoplayer | android 节操视频播放器 |
com.google.dagger:dagger com.google.dagger:dagger-compiler | google dagger2依赖注入库 |
org.glassfish:javax.annotation | 解决dagger2 提示javax.annotation不存在问题 |
uk.co.chrisjenx:calligraphy | Android自定义字体库 |
SildeMenulibrary | 滑动菜单 |
ObservableScrollView | 在滚动的视图观测滚动事件的Android库:Android-ObservableScrollView |
此处只是简单说明,详细信息详见https://github.com/chrisjenx/Calligraphy
CalligraphyConfig calligraphyConfig =new CalligraphyConfig.Builder()
.setDefaultFontPath("fonts/PMingLiU.ttf")
.setFontAttrId(R.attr.fontPath)
.build();
CalligraphyConfig.initDefault(calligraphyConfig);
@Override
protected void attachBaseContext(Context newBase) { super.attachBaseContext(CalligraphyContextWrapper.wrap(newBase));
}
第四步:app中的文本就使用配置中的字体作为默认字体使用。
此处只是针对项目中做简要分析,完整的使用请查看官方文档https://github.com/google/dagger/
private NetComponent netComponent;
private void initNet(){
netComponent = DaggerNetComponent.builder()
.netModule(new NetModule())
.build();
}
public NetComponent getNetComponent() {
return netComponent;
}
可以看到的是我们直接使用NetComponent生成的类DaggerNetComponent并且生成的方法,完成了对module为netModule的初始化。
@Module
public class NetModule {
@Provides
@Singleton
public OkHttpClient provideOkHttpClient() {
HttpLoggingInterceptor loggingInterceptor = new HttpLoggingInterceptor();
loggingInterceptor.setLevel(BuildConfig.DEBUG ? HttpLoggingInterceptor.Level.BODY : HttpLoggingInterceptor.Level.NONE);
OkHttpClient okhttpClient = new OkHttpClient.Builder()
.connectTimeout(30, TimeUnit.SECONDS)
.connectTimeout(20, TimeUnit.SECONDS)
.readTimeout(20,TimeUnit.SECONDS)
.addInterceptor(loggingInterceptor)
.build();
return okhttpClient;
}
@Provides
@Singleton
public Retrofit provideRetrofit(OkHttpClient okhttpClient) {
Retrofit retrofit = new Retrofit.Builder()
.client(okhttpClient)
.baseUrl("http://xxxx.xxx.xx/")
.addConverterFactory(StringConverterFactory.create())
.addConverterFactory(GsonConverterFactory.create(EntityUtils.gson))//
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
.build();
return retrofit;
}
@Provides
@Singleton
public ApiService provideApiService(Retrofit retrofit){
return retrofit.create(ApiService.class);
}
}
可以看到我们通过@Module标注类,@Provide和@Singleton标注方法完成了这些对象实例的创建
如下以欢迎界面splashActivity调用方法为例说明
component声明
@UserScope
@Component(modules = SplashModule.class,dependencies = NetComponent.class)
public interface SplashComponent {
void inject(SplashActivity splashActivity);
}
module声明
@Module
public class SplashModule {
private SplashContract.View view;
public SplashModule(SplashContract.View view) {
this.view = view;
}
@Provides
public SplashContract.View provideView(){
return view;
}
}
MVP模式中的view接口声明
public interface SplashContract {
interface Presenter {
void getSplash(String deviceId);
}
interface View {
}
}
在Dagger2 中 ,注入类(injector class)被称作组件(Component),我们通过inject方法传递activity,service或者fragment对象到注入类component中。比如上面component声明类。我们通过@Component注解当前类,并且把两个模块SplashModule.class, NetModule.class也添加到component中。( Components从根本上来说就是一个注入器,也可以说是@Inject和@Module的桥梁。)
在activity里面inject注入
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
DaggerSplashComponent.builder() .netComponent(OwspaceApplication.get(this).getNetComponent())
.splashModule(new SplashModule(this))
.build().inject(this);
initStatus();
}
Dagger2中很重要的一点就是它会为@Component注解的类生成代码。它会在类的前面添加上Dagger前缀(比如上面的类就会生成DaggerSplashComponent .java),也就是这个类负责初始化依赖关系(依赖表 dependency graph)中的实例,并为注解了@Inject 的字段执行注入操作。
Scopes可是非常的有用,Dagger2可以通过自定义注解限定注解作用域。@Singleton是被Dagger预先定义的作用域注解( scope annotation )。没有指定作用域的@Provides方法将会在每次注入的时候都创建新的对象。同样的,你也可以定义自己的Scope注解。
@Scope
public @interface UserScope {
}
一个没有scope的组件component不可以依赖
一个有scope的组件component。子组件和父组件的scope不能相同。我们通常的ApplicationComponent都会使用Singleton注解,也就会是说我们如果自定义component必须有自己的scope