{"id":19525459,"url":"https://github.com/xiazunyang/discovery","last_synced_at":"2025-10-13T04:05:55.643Z","repository":{"id":57716046,"uuid":"393386887","full_name":"xiazunyang/discovery","owner":"xiazunyang","description":"辅助Android开发者在多模块工程间跨模块获取接口(或抽象类)的实现类的开源库，可实现模块的顺序初始化、业务的动态组合等实现。基于AGP和ASM开发。","archived":false,"fork":false,"pushed_at":"2023-12-02T01:44:36.000Z","size":225,"stargazers_count":54,"open_issues_count":0,"forks_count":10,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-04-26T10:36:03.655Z","etag":null,"topics":["android","arouter","asm","dag-init","gradle","like-router","modularization","multiple-modules","spi"],"latest_commit_sha":null,"homepage":"","language":"Kotlin","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/xiazunyang.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2021-08-06T13:33:51.000Z","updated_at":"2024-05-29T02:51:54.000Z","dependencies_parsed_at":"2025-04-26T10:40:59.005Z","dependency_job_id":null,"html_url":"https://github.com/xiazunyang/discovery","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/xiazunyang/discovery","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xiazunyang%2Fdiscovery","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xiazunyang%2Fdiscovery/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xiazunyang%2Fdiscovery/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xiazunyang%2Fdiscovery/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/xiazunyang","download_url":"https://codeload.github.com/xiazunyang/discovery/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xiazunyang%2Fdiscovery/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":279013599,"owners_count":26085389,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-10-13T02:00:06.723Z","response_time":61,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["android","arouter","asm","dag-init","gradle","like-router","modularization","multiple-modules","spi"],"created_at":"2024-11-11T01:04:33.296Z","updated_at":"2025-10-13T04:05:55.612Z","avatar_url":"https://github.com/xiazunyang.png","language":"Kotlin","funding_links":[],"categories":[],"sub_categories":[],"readme":"### 中文 | [English](README_EN.md)\n\n## Discovery\n\n通过`AGP`实现的在`Android`工程多模块之间获取接口或抽象类的实现类的实例的辅助工具。  \n通过在接口或抽象类上添加`@Discoverable`注解、并在实现类上添加`@Implementation`\n注解，就可以在工程中的任意模块中通过`Discoveries`类获取该接口或抽象类的实例，辅助开发者在模块之间访问数据。\n\n相比`ARouter`等路由框架，`Discovery`主要功能在编译期间工作，有更好的性能；并且只提供服务发现功能，开发者可实现更丰富的功能。  \n相比`ServiceLoader`，`Discovery`支持抽象类，以及可以获取实现类的`class`对象，可以适配更丰富的其它框架。\n\n演示工程：https://github.com/xiazunyang/DiscoveryDemo.git\n\n### 原理\n\n`Discovery`会在编译时扫描每个类文件，并将所有标记的类的信息通过`ASM`注册到`Discoveries`类中。\n\n### 安装\n\n当前最新版本：[![Maven Central](https://maven-badges.herokuapp.com/maven-central/cn.numeron/discovery.library/badge.svg)](https://mvnrepository.com/artifact/cn.numeron/discovery.library)\n\n1. 在`android`工程`app`模块的`build.gradle`的适当位置添加以下代码：\n    ```kotlin\n    plugins {\n        ...\n        id(\"cn.numeron.discovery\") version \"2.0.0\"        \n    }\n    ```\n\n2. 在`android`工程中基础模块的`build.gradle`文件中添加以下代码：\n    ```kotlin\n    dependencies {\n        ...\n        api(\"cn.numeron:discovery.library:2.0.0\")\n    }\n    ```    \n\n### 使用\n\n- 获取其它模块的业务服务\n\n    1. 声明接口时标记`@Discovrable`注解\n\n    ```kotlin\n    @Discoverable\n    interface ISignInService {\n    \n        /** 判断当前是否已登录 */\n        suspend fun isSignIn(context: Context): Boolean\n    \n        /** 通过用户名和密码进行登录 */\n        suspend fun signInByPassword(username: String, password: String)\n  \n  }\n    ```\n\n    2. 在任意模块中实现该接口，要求拥有无参构造方法，并标记`Implementation`注解\n\n    ```kotlin\n    @Implementation\n    class SignInServiceImpl: ISignInService {\n    \n        override suspend fun isSignIn(context: Context): Boolean {\n            TODO(\"判断是否已经登录\")\n        }\n    \n        override suspend fun signInByPassword(username: String, password: String) {\n            TODO(\"根据提供的账号密码进行登录\")\n        }\n    \n    }\n    ```\n\n    3. 在任意模块的代码中通过`Discoveries`获取接口实例\n    ```kotlin\n    lifecycleScope.launch {\n        val signInService = Discoveries.getInstance\u003cISignInService\u003e()\n        if (!signInService.isSignIn(requireContext())) {\n            //未登录， do something...\n        }\n    }\n    ```\n\n- 获取所有模块中的所有实例\n\n    1. 在基础模块中声明初始化接口\n\n    ```kotlin\n    @Discoverable\n    interface IInitializer {\n    \n        fun init(application: Application)\n    \n    }\n    ```\n\n    2. 在其它模块中实现该接口\n\n    ```kotlin\n    //需要初始化的A模块\n    @Implementation(order = 0)\n    class AModuleInitializer: IInitializer {\n        override fun init(application: Application) {\n            //init a module\n        }\n    }\n    \n    //需要初始化的B模块\n    @Implementation(order = 10)\n    class BModuleInitializer: IInitializer {\n        override fun init(application: Application) {\n            //init b module\n        }\n    }\n    ```\n\n    3. 在`Application`中获取所有实例并初始化\n    ```kotlin\n    class MyApplication: Application() {\n    \n        override fun onCreate() {\n            //获取所有IInitiator的实现，并执行init方法\n            val initializerList = Discoveries.getAllInstances\u003cIInitializer\u003e()\n            initializerList.forEach {\n                //order数值小的实现类优先调用\n                it.init(this)\n            }\n        }\n    \n    }\n    ```\n\n### 版本更新记录\n- **2.0.0**\n    * gradle版本更新至8.0。\n    \n\n- 1.4.2    \n    * 修复无法获取继承自抽象类的实现类的问题。\n    * [查看旧文档](README_1.4.2.md)\n    \n- 1.4.1\n    * `Implementation`注解中添加`order`属性，用于给实现类排序。\n\n- 1.4.0\n    * 添加抽象类的支持，不再强制要求参数是接口。\n    * 不强制要求实现类拥有无参构造，但是`Discovery`不再参与创建这一类实现类的实例。\n    * `Discoveries`中新增两个方法用于获取实现类的`Class`，方便用户自己创建它们的实例。\n\n- 1.3.3\n    * 当`getAllInstances`没有获取到任何实例的时候，不再抛出异常，改为返回一个空的列表。\n\n- 1.3.2\n    * `ASM`的`Option`降级至`ASM7`。\n\n- 1.3.1\n    * 修复`ASM`织入了错误的代码的问题。\n\n- ~~1.3.0~~\n    * **存在致命错误，请使用`1.3.1`版本**\n    * 去除注解处理器模块，使配置简化。[查看之前的配置流程](README_1.2.2.md)\n    * 修复增量编译的一些问题。\n\n- 1.2.2\n    * 使用字符串作为配置名称，不再需要冗长的导包。\n    * 编译时检查`Implementation`标记的类，要求必需拥有无参构造方法。\n\n- 1.2.1\n    * 当`Implementation`注解标记的类实现了多个接口时，会忽略掉未被`Discovrable`注解标记的接口。\n\n- 1.2.0\n    * 新增`Discovery`的配置选项，可配置实现类的处理方式。\n    * 默认为`Scan`模式，即全局扫描，可配置为`Mark`模式，需要使用`Implementation`注解标记实现类，可免去扫描过程，以节省编译时间。\n\n- 1.1.0\n    * 注解处理器新增`APT`的实现，兼容`java`项目，与`KSP`任选其一即可。\n\n- 1.0.0\n    * 正式发布，由`KSP`和`AGP`实现主要功能。\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fxiazunyang%2Fdiscovery","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fxiazunyang%2Fdiscovery","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fxiazunyang%2Fdiscovery/lists"}