开源APP项目代码分析(2)- Owspace和MusicDNA

今天推荐两个开源项目ownspace和MusicDNA

Ownspace

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

二、开源库简单介绍

1)、calligraphy

此处只是简单说明,详细信息详见https://github.com/chrisjenx/Calligraphy

第一步:在asset/font目录下添加字体

添加字体

第二步:在application里面添加配置项

CalligraphyConfig calligraphyConfig =new CalligraphyConfig.Builder()
                .setDefaultFontPath("fonts/PMingLiU.ttf")
                .setFontAttrId(R.attr.fontPath)
                .build();
        CalligraphyConfig.initDefault(calligraphyConfig);

第三步:注入到Context中

@Override
protected void attachBaseContext(Context newBase) {         super.attachBaseContext(CalligraphyContextWrapper.wrap(newBase));
}

第四步:app中的文本就使用配置中的字体作为默认字体使用。

2)、Dagger 2

此处只是针对项目中做简要分析,完整的使用请查看官方文档https://github.com/google/dagger/

第一步:在application中初始化组件

    private NetComponent netComponent;
    private void initNet(){
        netComponent = DaggerNetComponent.builder()
                .netModule(new NetModule())
                .build();
    }

    public NetComponent getNetComponent() {
        return netComponent;
    }

可以看到的是我们直接使用NetComponent生成的类DaggerNetComponent并且生成的方法,完成了对module为netModule的初始化。

第二步:介绍下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标注方法完成了这些对象实例的创建

第三步:在Actitvity中,获取component并且调用inject()方法

如下以欢迎界面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)

Scopes可是非常的有用,Dagger2可以通过自定义注解限定注解作用域。@Singleton是被Dagger预先定义的作用域注解( scope annotation )。没有指定作用域的@Provides方法将会在每次注入的时候都创建新的对象。同样的,你也可以定义自己的Scope注解。

@Scope
public @interface UserScope {
}

一个没有scope的组件component不可以依赖
一个有scope的组件component。子组件和父组件的scope不能相同。我们通常的ApplicationComponent都会使用Singleton注解,也就会是说我们如果自定义component必须有自己的scope

MusicDNA

你可能感兴趣的:(Android)