当前位置: 首页 > news >正文

收集链接 做网站西安做网站缑阳建

收集链接 做网站,西安做网站缑阳建,合肥住房城乡建设部的网站,搜索引擎关键词推广【KRouter】一个简单且轻量级的Kotlin Routing框架 KRouter#xff08;Kotlin-Router#xff09;是一个简单而轻量级的Kotlin路由框架。 具体来说#xff0c;KRouter是一个通过URI来发现接口实现类的框架。它的使用方式如下#xff1a; val homeScreen KRouter.routeKotlin-Router是一个简单而轻量级的Kotlin路由框架。 具体来说KRouter是一个通过URI来发现接口实现类的框架。它的使用方式如下 val homeScreen KRouter.routeScreen(screen/home?namezhangke)之所以这样做是因为在使用Voyager一段时间后我发现模块之间的通信不够灵活需要一些配置而且使用DeepLink有点奇怪所以我更喜欢使用路由来实现模块之间的通信于是我开发了这个库。 这个库主要通过KSP、ServiceLoader和反射来实现。 使用方法 上述代码基本上就是使用的全部内容。 如前所述这是用于发现接口实现类并通过URI匹配目标的库因此我们首先需要定义一个接口。 interface Screen然后我们有一个包含许多独立模块的项目这些模块实现了这个接口每个模块都不同我们需要通过它们各自的路由即URI来区分它们。 // HomeModule Destination(screen/home) class HomeScreen(Router val router: String ) : Screen// ProfileModule Destination(screen/profile) class ProfileScreen : Screen {Routerlateinit var router: String }现在我们有两个独立的模块它们各自拥有自己的屏幕Screens并且它们都有自己的路由地址。 val homeScreen KRouter.routeScreen(screen/home?namezhangke) val profileScreen KRouter.routeScreen(screen/profile?namezhangke)现在您可以通过KRouter获取这两个对象并且这些对象中的路由属性将被分配给对KRouter.route的特定调用的路由。 现在您可以在HomeScreen和ProfileScreen中获取通过URI传递的参数并且可以使用这些参数进行一些初始化和其他操作。 Destination Destination 注解用于标记目的地Destination包含两个参数 route目的地的唯一标识路由地址必须是 URI 类型的字符串不需要包含查询参数。type目的地的接口。如果类只有一个父类或接口您无需设置此参数它可以自动推断。但如果类有多个父类或接口您需要通过 type 参数明确指定。 需要特别注意的是被 Destination 注解标记的类必须包含一个无参数构造函数否则 ServiceLoader 无法创建对象。对于 Kotlin 类您还需要确保构造函数的每个输入参数都具有默认值。 Router Router 注解用于指定目的地类的哪个属性用于接收传入的路由参数该属性必须是字符串类型。 使用此注解标记的属性将自动分配一个值或者您可以不设置注解。例如在上述示例中当创建 HomeScreen 对象时其 router 字段的值将自动设置为 screen/home?namezhangke。 特别要注意如果被Router注解的属性不在构造函数中那么该属性必须声明为可修改的即在 Kotlin 中应为 var 修饰的可变属性。 KRouter 是一个 Kotlin Object 类它只包含一个函数 inline fun reified T : Any route(router: String): T?此函数接受一个泛型类型和一个路由地址。路由地址可以包含或不包含查询参数但在匹配目的地时查询参数将被忽略。匹配成功后将使用此 URI 构造对象并将 URI 传递给目标对象中的 router 注解字段。 集成 首先您需要在项目中集成 KSP。 https://kotlinlang.org/docs/ksp-overview.html 然后添加以下依赖项 // 模块的 build.gradle.kts implementation(com.github.0xZhangKe.KRouter:core:0.1.5) ksp(com.github.0xZhangKe.KRouter:compiler:0.1.5)由于使用了 ServiceLoader您还需要设置 SourceSet。 // 模块的 build.gradle.kts kotlin {sourceSets.main {resources.srcDir(build/generated/ksp/main/resources)} }可能还需要添加 JitPack 仓库 maven { setUrl(https://jitpack.io) }工作原理 正如前面所提到的KRouter 主要通过 ServiceLoader KSP 反射来实现。 这个框架由两个主要部分组成编译阶段和运行时阶段。 KSP 插件 与 KSP 插件相关的代码位于编译器模块中。 KSP 插件的主要任务是根据 Destination 注解生成 ServiceLoader 的服务文件。 KSP 代码的其余部分基本相同主要工作包括首先配置服务文件然后根据注解获取类最后通过 Visitor 进行迭代。您可以直接查看 KRouterVisitor 来了解更多细节。 override fun visitClassDeclaration(classDeclaration: KSClassDeclaration, data: Unit) {val superTypeName findSuperType(classDeclaration)writeService(superTypeName, classDeclaration) }visitClassDeclaration 方法主要有两个主要功能第一是获取父类第二是编写或创建服务文件。 流程首先是获取指定类型的父类如果没有父类且只有一个父类时可以直接返回否则会引发异常。 // find super-type by type parameter val routerAnnotation classDeclaration.requireAnnotationDestination() val typeFromAnnotation routerAnnotation.findArgumentTypeByName(type)?.takeIf { it ! badTypeName }// find single-type if (classDeclaration.superTypes.isSingleElement()) {val superTypeName classDeclaration.superTypes.iterator().next().typeQualifiedName?.takeIf { it ! badSuperTypeName }if (!superTypeName.isNullOrEmpty()) {return superTypeName} }一旦获取到父类我们需要创建一个文件其文件名以接口或抽象类的权限作为所需的 ServiceLoader 文件名。 然后我们将已实现类的权限名称写入该文件。 val resourceFileName ServicesFiles.getPath(superTypeName) val serviceClassFullName serviceClassDeclaration.qualifiedName!!.asString() val existsFile environment.codeGenerator.generatedFile.firstOrNull { generatedFile -generatedFile.canonicalPath.endsWith(resourceFileName)} if (existsFile ! null) {val services existsFile.inputStream().use { ServicesFiles.readServiceFile(it) }services.add(serviceClassFullName)existsFile.outputStream().use { ServicesFiles.writeServiceFile(services, it) } } else {environment.codeGenerator.createNewFile(dependencies Dependencies(aggregating false, serviceClassDeclaration.containingFile!!),packageName ,fileName resourceFileName,extensionName ,).use {ServicesFiles.writeServiceFile(setOf(serviceClassFullName), it)} }KRouter主要有三个关键功能 通过ServiceLoader获取接口的所有实现类。将特定的目标类与URI进行匹配。从URI构建目标类对象。 第一件事非常简单 inline fun reified T findServices(): ListT {val clazz T::class.javareturn ServiceLoader.load(clazz, clazz.classLoader).iterator().asSequence().toList() }一旦你获取到它你就可以开始与URL进行匹配。 这个匹配的方式是获取每个目标类的Destination注解中的路由字段然后将其与路由进行比较。 fun findServiceByRouter(serviceClassList: ListAny,router: String, ): Any? {val routerUri URI.create(router).baseUrival service serviceClassList.firstOrNull {val serviceRouter getRouterFromClassAnnotation(it::class)if (serviceRouter.isNullOrEmpty().not()) {val serviceUri URI.create(serviceRouter!!).baseUriserviceUri routerUri} else {false}}return service }private fun getRouterFromClassAnnotation(targetClass: KClass*): String? {val routerAnnotation targetClass.findAnnotationDestination() ?: return nullreturn routerAnnotation.router }匹配策略是忽略查询字段只需通过baseUri进行匹配即可。 接下来的步骤是创建对象。有两种情况需要考虑 第一种情况是Router注解位于构造函数中在这种情况下需要再次使用构造函数创建对象。 第二种情况是Router注解位于普通属性中。在这种情况下可以直接使用ServiceLoader创建的对象然后将值分配给它。 如果Router注解位于构造函数中您可以首先获取routerParameter然后使用PrimaryConstructor重新创建对象。 private fun fillRouterByConstructor(router: String, serviceClass: KClass*): Any? {val primaryConstructor serviceClass.primaryConstructor?: throw IllegalArgumentException(KRouter Destination class must have a Primary-Constructor!)val routerParameter primaryConstructor.parameters.firstOrNull { parameter -parameter.findAnnotationRouter() ! null} ?: return nullif (routerParameter.type ! stringKType) errorRouterParameterType(routerParameter)return primaryConstructor.callBy(mapOf(routerParameter to router)) }如果它是一个普通的变量属性首先获取属性然后进行一些类型权限和其他检查然后调用setter方法分配值。 private fun fillRouterByProperty(router: String,service: Any,serviceClass: KClass*, ): Any? {val routerProperty serviceClass.findRouterProperty() ?: return nullfillRouterToServiceProperty(router router,service service,property routerProperty,)return service }private fun KClass*.findRouterProperty(): KProperty*? {return declaredMemberProperties.firstOrNull { property -val isRouterProperty property.findAnnotationRouter() ! nullisRouterProperty} }private fun fillRouterToServiceProperty(router: String,service: Any,property: KProperty*, ) {if (property !is KMutableProperty*) throw IllegalArgumentException(Router property must be non-final!)if (property.visibility ! KVisibility.PUBLIC) throw IllegalArgumentException(Router property must be public!)val setter property.setterval propertyType setter.parameters[1]if (propertyType.type ! stringKType) errorRouterParameterType(propertyType)property.setter.call(service, router) }上面是关于KRouter的全部内容希望对你有所帮助 GitHub https://github.com/0xZhangKe/KRouter
http://www.zqtcl.cn/news/544117/

相关文章:

  • 做网站不赚钱了网站关键词排行查询
  • 印度人通过什么网站做国际贸易三门峡做网站
  • 网站排名快速提升工具招远建网站首选公司
  • 手机网站格式商城网游开发公司
  • 手机怎样创建网站长春网站建设哪家专业
  • 做pop网站定制开发教程
  • 成都响应式网站建报告问题
  • 做设计找素材的+网站有哪些建立平台什么意思
  • 网站设置在哪里找宁德网站建设制作
  • logo网站设计素材品牌高端网站建设公司
  • 芙蓉区乡建设局网站郑州网站建设qicaizz
  • 网站建设的缺陷个人网站制作图片
  • 四川省建设厅注册管理中心网站设计上海2021门票
  • 帝国cms做微网站人力资源公司怎么开
  • 网站建设学徒松江品划做网站公司
  • 灯饰网站需要这么做深圳专业网站设计公司
  • 政务网站设计wordpress 嵌入html5
  • 移动网站 pc网站的区别吗网站建设工厂
  • 有意义网站织梦圈子如何调用网站默认模板
  • 南京公司网站模板建站网页制作中的网站维护
  • 微信分享 淘宝网站 怎么做wordpress访问慢
  • 网站后台制作沈阳营销型网站制作技术
  • 微页制作平台网站建设wordpress文章显示数量
  • 望野古诗王绩seo优化系统
  • 网站设计大概流程惠城区龙丰街道
  • 游戏平台十大排名南宁seo优化公司
  • 佛山外贸网站建设方案企业管理控制系统
  • 分类信息网站如何做排名品牌建设卓有成效
  • 企业网站报价方案模板下载营销软件crm
  • 湛江网站开发哪家专业东莞营销型手机网站建设