携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第19天,点击查看活动详情
接上文我们完成了注解处理器的编写,还有个扫尾的工作需要完成。
注册注解处理器
我们需要在processor模块中注册我们的注解处理器。
创建文件processor/src/main/resources/META-INF/services/com.google.devtools.ksp.processing.SymbolProcessorProvider
文件内容为com.holderzone.store.processor.BuilderProcessorProvider,即SymbolProcessorProvider实现类的包名。
第三步创建XRouter模块
在模块的build.gradle.kts中加入以下代码:
plugins {
id("com.android.library")
id("org.jetbrains.kotlin.android")
}
android {
compileSdk = 32
defaultConfig {
minSdk = 21
targetSdk = 32
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
isMinifyEnabled = false
proguardFiles(
getDefaultProguardFile("proguard-android-optimize.txt"),
"proguard-rules.pro"
)
}
}
compileOptions {
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
}
kotlinOptions {
jvmTarget = "1.8"
}
}
dependencies {
implementation("androidx.core:core-ktx:1.3.2")
implementation("androidx.appcompat:appcompat:1.2.0")
implementation("com.google.android.material:material:1.3.0")
implementation("androidx.constraintlayout:constraintlayout:2.0.4")
api(project(":annotation"))
}
由于使用到了Intent所以要使用com.android.library,另外注意这里使用的api来引入annotation依赖,这样app在使用XRouter时就不需要再次引入annotation模块了。
反射调用loadInfo
object XRouter {
val hashMap = HashMap<String,Class<Any>>()
var mContext:Context? = null
fun init(context: Application){
mContext = context
val claName = "com.example.xrouter.XRouterPathCollector"
val clazz = Class.forName(claName)
val ob = clazz.newInstance()
val collectMethod = clazz.getMethod("loadInfo", hashMap.javaClass)
collectMethod.invoke(ob, hashMap)
}
public fun navigation(route:String) {
if (mContext == null) return
if (!hashMap.containsKey(route)) return;
val intent = Intent(mContext, hashMap.get(route))
intent.addFlags(FLAG_ACTIVITY_NEW_TASK)
ActivityCompat.startActivity(mContext!!, intent,null )
}
}
XRouter的实现很简单,在init时传入Application context,另外使用反射调用XRouterPathCollector的loadInfo方法,将路由信息加载到hashMap中。
当调用navigation方法时,去hashMap中找到对应的路由信息,构建Intent类,实现跳转。
使用
在app的build.gradle.kts中加入以下代码:
plugins {
id ("com.android.application")
id ("kotlin-android")
id ("com.google.devtools.ksp") version ("1.5.31-1.0.0")
}
dependencies {
...
ksp(project(":processor"))
implementation(project(":xrouter"))
}
在Application进行初始化:
class App: Application() {
override fun onCreate() {
super.onCreate()
XRouter.init(this)
}
}
在对应Activity添加Route注解:
@Route(route = "Main")
class MainActivity : AppCompatActivity() {
}
@Route(route = "Second")
public class SecondActivity extends AppCompatActivity {
}
到这一步我们可以先重新编译一次代码,不出意外的话在app/build/generated/ksp/debug/kotlin/com/example/xrouter目录下会生成如下代码:
package com.example.xrouter
import android.app.Activity
import java.lang.Class
import java.util.HashMap
import kotlin.String
import kotlin.Unit
public class XRouterPathCollector {
public fun loadInfo(map: HashMap<String, Class<out Activity>>): Unit {
map["Main"] = com.holderzone.store.ksptest.MainActivity::class.java
map["Second"] = com.holderzone.store.ksptest.SecondActivity::class.java
}
}
如果没有生成,那就得好好看一下ksp的log,分析是哪步出错了。
想要跳转到第二个Activity时,只需要使用XRouter.navigation("Second")即可完成跳转。ok我们的XRouter写到这里就算完成了,当然有很多地方可以完善补充,例如KSP采用增量编译、添加传参跳转功能、将XRouter和processor发布到maven等等。
本文只是介绍了ksp是什么以及怎么用,没有过多的介绍它的API,它是可以拿到所有类、方法、属性的注解等信息的。更多细节及用法请参考官网。