Discovery

Through KSP and AGP implementation of the Android project between the module to obtain the interface instance object auxiliary tool.

After the @Discoverable annotation is added to the interface, the Discoveries class is used to obtain the instances of the interface from any module in the project, helping developers to access data between modules.

Making: github.com/xiazunyang/…

The principle of

Discovery consists of three modules, namely annotation Processor module based on Kotlin Symbol Processor, plug-in module based on Android Gradle Plugin and a Kotlin library module.

  • Kotlin module

    • Contains aDiscovrableNote, and oneDiscovriesClass.
  • KSP module

    • Before compiling, get all of theDiscoverableAnnotate information about the tagged interface, generate a list and record it.
  • AGP module

    • At compile time, the class files in each module are scanned and the implementation classes of the interfaces in the above list are registered with ASM into the Discoveries class of the Kotlin module.

The installation

  1. Add the following code to the root module’s build.gradle at the appropriate location:

    buildscript {
       repositories {
           google()
           mavenCentral()
           gradlePluginPortal()
       }
       dependencies {
           // Add the Discovery plugin
           classpath("Cn. Numeron: discovery. The plugin: 1.0.0")
           // Add the KSP plug-in
           classpath("Com. Google. Devtools. KSP: com. Its devtools. KSP. Gradle. The plugin: 1.5.21 1.0.0 - beta06")}}Copy the code
  2. Add the following code to the build.gradle file in the module where the @discoverable annotation is required:

    plugins {
        id("com.android.library")...// Apply the KSP plug-in
        id("com.google.devtools.ksp")}... dependencies { ...// Use the Discovery KSP plugin
        ksp("Cn. Numeron: discovery. KSP: 1.0.0")
        // Add the Discovery Library
        implementation("Cn. Numeron: discovery. Library: 1.0.0")}... ksp {// Set the module's unique identifier and the root project's compile directory
        arg("projectName"."module-name")
        arg("rootProjectBuildDir", rootProject.buildDir.absolutePath)
    }
    Copy the code
  3. Add the following code to the build.gradle file of the main module:

    plugins {
        id("com.android.application")...// Apply the Discovery plugin
        id("discovery")}Copy the code

use

  • Get business services for other modules

    1. Used on an interface@Discovrableannotations
    @Discoverable
    interface ISignInService {
    
        /** Check whether you are logged in */
        suspend fun isSignIn(context: Context): Boolean
    
        /** Log in using the user name and password */
        suspend fun signInByPassword(username: String, password: String)
    
    }
    Copy the code
    1. Implemented in any moduleISignInServiceinterface
    class SignInServiceImpl: ISignInService {
    
        override suspend fun isSignIn(context: Context): Boolean {
            TODO("Determine if you are logged in.")}override suspend fun signInByPassword(username: String, password: String) {
            TODO("Log in according to the provided account and password.")}}Copy the code
    1. Pass in the code of any moduleDiscoveriesObtaining an Interface Instance
    lifecycleScope.launch {
        val signInService = Discoveries.getInstance<ISignInService>()
        if(! signInService.isSignIn(requireContext())) {// Do something...}}Copy the code
  • Gets all instances in all modules

    1. Declare the initialization interface in the base module
    @Discoverable
    interface IInitiator {
    
        fun init(application: Application)
    
    }
    Copy the code
    1. Implement the interface in another module
    // Module A to be initialized
    class AModuleInitiator: IInitiator {
        override fun init(application: Application) {
            //init a module}}// Module B that needs to be initialized
    class BModuleInitiator: IInitiator {
        override fun init(application: Application) {
            //init b module}}Copy the code
    1. inApplicationGets all instances in and initializes them
    class MyApplication: Application() {
    
        override fun onCreate(a) {
            // Get all IInitiator implementations and execute the init method
            val initiatorList = Discoveries.getAllInstances<IInitiator>()
            initiatorList.forEach {
                it.init(this)}}}Copy the code