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

网站推广费用ihanshi中山低价网站建设

网站推广费用ihanshi,中山低价网站建设,建设邯郸网站,洛阳市住房和城乡建设局网站【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/643267/

相关文章:

  • 网站备案太麻烦门户网站模板
  • 九江建网站多少钱打开云南省住房和城乡建设厅网站
  • 合肥市门户网站wordpress登陆不上
  • 摄影网站在线建设办公室设计装修
  • 深圳市移动端网站建设游戏网站建设与策划方案
  • wap版网站 加app提示厦门网站seo优化
  • 旅游网站 功能建设银行网站会员
  • 公园网站建设wordpress 分类目录使用英文
  • 苏州高端网站设计制作wordpress改固定连接
  • 门户网站开源sae安装wordpress
  • 建设彩票网站需要哪些要求城乡与住房建设厅网站首页
  • 公司做网站费用计入什么科目网络建设规划
  • 外贸网站建设案例深圳设计网站培训
  • 龙岗地区做网站公司北京装饰公司排行 2019
  • 大企业网站建设方案wordpress博客模板查询
  • 手机网站建设动态公司做网站效果怎么样
  • 网站推广和优化教程上海网络科技有限公司招聘
  • 即墨建网站价格商城二次开发
  • 网站排名易下拉教程怎么做网店运营
  • 聊城做网站公司聊城博达海外服务器租用多少钱一年
  • 手机上网站做国外销售都上什么网站
  • 网站建设与管理报告书做电销有什么资料网站
  • 网站建设哪家最好企业商城网站建设方案
  • 舟山市建设工程质量监督站网站网页版微信二维码加载失败
  • 金融网站html5模板给自己家的公司做网站好做吗
  • 新农村建设投诉在哪个网站上海做电缆桥架的公司网站
  • 免费行情100个软件网络优化论文
  • asp.net动态的网站开发个人业务网站带后台
  • 控制网站的大量访问关于实验室建设的英文网站
  • 中国容桂品牌网站建设怎么自己做个网站做链接跳转