brick2

Project Url: xiazunyang/brick2
Introduction: 辅助 android 开发者搭建基于 JetPack 组件构建的 MVVM 框架,通过注解自动生成 ViewModel 的 Factory 类、lazy 方法等;支持在项目的任意位置注入 ROOM 的 dao 层接口与 Retrofit 库中的 api 接口和任意无参实例。
More: Author   ReportBugs   
Tags:

当前最新版本号:

多模块示例 android 工程:https://github.com/xiazunyang/Wandroid.git

介绍

辅助 android 开发者搭建基于 JetPack 组件构建 MVVM 框架的注解处理框架。通过注解自动生成 ViewModel 的 Factory 类、lazy 方法等;支持在项目的任意位置注入 ROOM 的 dao 层接口与 Retrofit 库中的 api 接口。

特点

android 开发者可以将brick理解为一个轻量级的注入框架,使用非常简单,使用 4-6 个注解即可工作。brick主要在编译期工作, 不会在App运行时产生任何额外的性能消耗 ,并且只有 1 个注解库会打包到你的android工程中,不用担心体积增大的问题。

适用范围

  1. 使用androidx而非support库。
  2. 使用JetPackViewModel组件。
  3. 使用Retrofit作为网络请求库。
  4. 使用ROOM数据库框架。(可选)
  5. 服务端为多端口、多 IP 的项目。(可选)

引入

  1. 在你的android工程的根目录下的build.gradle文件中的适当的位置添加以下代码: ``` buildscript { ... repositories {
    ...
    maven { url 'https://jitpack.io' }
    
    } dependencies {
    classpath 'com.gitee.numeron.brick:plugin:0.3.4'
    
    } }

allprojects { repositories { ... maven { url 'https://jitpack.io' } } }

2. 在要启用`brick`的模块中找到`build.gradle`文件,在所有的`apply`下面添加一行:

apply plugin: 'com.android.application' ... //添加下面这行 apply from: 'https://gitee.com/numeron/brick/raw/master/brick.gradle'

3. 如果想加快编译速度,可以把该脚本下载下来放在与`settings.gradle`相同的文件夹里,然后把`apply`改为:

apply from: '../brick.gradle'


**注:第 2 步和第 3 步任选其一即可配置 brick。**  
### 使用

#### **一、 @Provide 注解的使用方法:** 
 1. 在你编写好的 ViewModel 子类上添加@Provide 注解

@Provide class WxAuthorViewModel: ViewModel() { ... }

 2. 有 3 种方式让`brick`注解处理器开始工作:
 * 在`Terminal`终端上输入`gradlew :[ModuleName]:kaptDebugKotlin`运行脚本;
 * 在`AndroidStudio`右侧`Gradle`扩展栏中依次找到`[PrjectName] -> [ModuneName] -> Tasks -> other -> kaptDebugKotlin`并双击运行脚本;
 * `Ctrl + F9`编译整个项目。  
 **以上三种方式任选其一即可运行`brick`注解处理器。** 
 3. 脚本运行结束后,会生成两个包级方法:
 * `lazyWxAuthorViewModel()`扩展方法,在`Activity`或`Fragment`中直接调用即可。
 * `getWxAuthorViewModel()`方法,在不方便使用`lazy`方法时,可使用此方法获取`ViewModel`的实例。  
 **注:`lazyWxAuthorViewModel`方法就是对`getWxAuthorViewModel()`方法的包装。**     
直接使用生成的方法,即可创建对应的`ViewModel`实例:

private val wxAuthorViewModel by lazyWxAuthorViewModel()

 或在`onCreate()`之后,通过`getWxAuthorViewModel`创建:

private lateinit var wxAuthorViewModel: WxAuthorViewModel

override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) wxAuthorViewModel = getWxAuthorViewModel(this) }


#### **二、 @Inject 注解的使用方法**   

 -2. **(必需)** 在获取`Retrofit`实例的方法上添加`@RetrofitInstance`,如:

@RetrofitInstance val retrofit: Retrofit by lazy(LazyThreadSafetyMode.SYNCHRONIZED) { Retrofit.Builder() .client(okHttpClient) .baseUrl(WANDROID_BASE_URL) .addConverterFactory(MoshiConverterFactory.create()) .build() }

val okHttpClient: OkHttpClient by lazy(LazyThreadSafetyMode.SYNCHRONIZED) { val logInterceptor = HttpLoggingInterceptor() logInterceptor.level = HttpLoggingInterceptor.Level.BODY OkHttpClient.Builder() .addInterceptor(logInterceptor) .callTimeout(15, TimeUnit.SECONDS) .readTimeout(60, TimeUnit.SECONDS) .writeTimeout(60, TimeUnit.SECONDS) .connectTimeout(15, TimeUnit.SECONDS) .build() }

 **注:`@RetrofitInstance`注解只能标记在`public`修饰的`val`属性上或方法上,`val`属性上或方法可以在`object 单例`或`companion object`中,也可以是包级属性/方法。**   

 -1. **(可选)** 在获取`RoomDatabase`实例的属性或方法上标记`@RoomInstance`,如:

@RoomInstance val wandroidDatabase: WandroidDatabase by lazy(LazyThreadSafetyMode.SYNCHRONIZED) { Room.databaseBuilder(CONTEXT, WandroidDatabase::class.java, "wandroid.db") .build() }

 **注:`@RoomInstance`注解只能标记在`public`修饰的`val`属性上或方法上,`val`属性上或方法可以在`object 单例`或`companion object`中,也可以是包级属性/方法。**  

 0. 假设已有`Retrofit Api`接口和`WxAuthorRepo`类

interface WxAuthorApi { @GET("wxarticle/chapters/json ") suspend fun getWxAuthorList(): List }

class WxAuthorRepo { ... }


 1. 在 WxAuthorRepo 中添加`lateinit var`修饰的`WxAuthorApi`字段,并用`@Inject`标记:

class WxAuthorRepo {

@Inject
lateinit var wxAuthorApi: WxAuthorApi

}


 2. 在 ViewModel 中创建`lateinit var`修饰的`WxAuthorRepo`字段,并用`@Inject`标记:

@Provide class WxAuthorViewModel: ViewModel() { @Inject private lateinit var wxAuthorRepo: WxAuthorRepo }

标记后,继续编写业务代码即可,所有被`@Inject`标记的字段,都会在编译期自动获取或创建实例,无需担心它们在何时被赋值。   
 **注:虽然是`lateinit var`修饰的字段,但是不要尝试为它们赋值,这会导致致命的错误。**   
 **注:`@Inject`可以注入的类型只有`Retrofit`的`api`接口和`ROOM`的`dao`接口、以及有无参构造的类。**   

#### **三、 多服务器或多端口的处理方法:**   
假设有另一个 Retrofit api 接口,它的访问地址或端口与`baseUrl`中的不一样,此时,可以在`Retrofit`的`api`接口上添加`@Port`和`@Url`注解来设置它们的 url 或 port。  

 1. `@Port`的使用:

@Port(1080) interface ArticleApi {

@GET("wxarticle/list/{chapterId}/{page}/json")
suspend fun getArticleList(@Path("chapterId") chapterId: Int, @Path("page") page: Int): Paged<Article>

}

添加此注解后,brick 会在编译期根据`@RetrofitInstance`注解标记的`Retrofit`实例和`@Port`的端口号,重新创建一个`Retrofit`实例,并使用新的`Retrofit`实例创建`ArticleApi`的实例。  

 2. `@Url`的使用:

@Url("http://www.wanandroid.com:1080/") interface ArticleApi { @GET("wxarticle/list/{chapterId}/{page}/json") suspend fun getArticleList(@Path("chapterId") chapterId: Int, @Path("page") page: Int): Paged

} `` 与@Port`的使用基本一致,实现的原理也是一样的。

Apps
About Me
GitHub: Trinea
Facebook: Dev Tools