做app和做网站哪个容易设计师一般放作品的网站

张小明 2026/3/2 21:34:13
做app和做网站哪个容易,设计师一般放作品的网站,郑州seo哪家专业,上海哪个区最好一、路由插件设计思路 Transform在Gradle8.0中被移除了#xff0c;从官方文档《Android Gradle 插件 API 更新》中可知并没有提供直接的替代Api#xff0c;而是区分不同场景提供了几种对应的解决方案。在上篇文章《基于Gradle8.0的插件开发》中#xff0c;基于Gradle8.0最新…一、路由插件设计思路Transform在Gradle8.0中被移除了从官方文档《Android Gradle 插件 API 更新》中可知并没有提供直接的替代Api而是区分不同场景提供了几种对应的解决方案。在上篇文章《基于Gradle8.0的插件开发》中基于Gradle8.0最新版本重新梳理了插件的使用方式和自定义流程最后写了一个模拟页面打点统计的Demo来实现比较简单的基于“转换字节码”场景的插件开发。本文以路由信息收集为例继续阐述如何开发一个针对“基于整个程序分析的转换”场景的插件。该案例专注于插件开发的流程而不会涉及到登录校验、服务发现、跳转拦截器等方面的内容有兴趣的同学可以自行实现。先定义一个注解用来标记页面的路由信息在定义一个路由管理类用来存储路由信息并对外提供跳转功能。在工程中添加hui_aop模块创建HuiRouterPath注解 和 HuiRouterApi路由管理类。在Gradle插件中对HuiRouterApi进行插桩添加插入路由信息的字节码指令在程序运行时插桩的字节码指令执行路由信息被注册到HuiRouterApi内部的路由表中然后外部就可以通过HuiRouterApi进行跳转操作了。​在工程的hui_plugin模块中添加HuiRouterPlugin插件 和 HuiRouterTask任务处理注解扫描、路由表信息收集通过ASM向 HuiRouterApi类中插入生成路由表的字节码指令。修改后所有输入的class 和 jar会重新生成中间产物classes.jar(全路径gradle80-plugin-demo/app/build/intermediates/classes/debug/ALL/debugHuiRouterTask/classes.jar)传递给下个任务继续打包流程最终打出一个可运行的APK包。插件工作流程图二、路由插件实现流程1、新建一个module模块hui_aop2、定义注解HuiRouterPath用于标记路由信息​Target(AnnotationTarget.ANNOTATION_CLASS, AnnotationTarget.CLASS) Retention(AnnotationRetention.BINARY) annotation class HuiRouterPath( val path: String //路由表中的path )3、定义路由管理类HuiRouterApiobject HuiRouterApi { ​ //存储跳转路由表 private val routerPathMap mutableMapOfString, String() ​ /** * 注册跳转路由 */ private fun addRouterPath(key: String?, path: String?) { if (key ! null path ! null) { routerPathMap[key] path } } ​ /** * 页面跳转 */ fun routerPath(context: Context, routerTargetPath: String) { routerPathMap[routerTargetPath]?.takeIf { it.isNotEmpty() }?.run { context.startActivity(Intent(context, Class.forName(this))) } } ​ /** * 打印routerPathMap */ fun printRouterPathMap() { routerPathMap.forEach { entry - Log.e(HuiRouterApi, routerPathMap entry - $entry) } } }​4、定义一个Task任务类HuiRouterTask将输入的jar文件和class文件进行插桩修改并输出到output。扫描过程中收集的路由信息记录到annotationPathMap中abstract class HuiRouterTask : DefaultTask() { ​ //所有的jar文件输入信息 get:InputFiles abstract val allJars: ListPropertyRegularFile ​ //所有的class文件输入信息 get:InputFiles abstract val allDirectories: ListPropertyDirectory ​ //经过插桩修改后的输出信息 get:OutputFile abstract val output: RegularFileProperty ​ //注册带有HuiRouterPath注解的类 private val annotationPathMap HashMapString?, String?() //HuiRouterApi的class对应的Jar包文件 private var routerApiJarFile: File? null ​ TaskAction fun taskAction() { //todo 遍历扫描class文件 } }5、在taskAction方法中扫描遍历所有的jar和class文件收集路由信息查找到HuiRouterApi类并将收集到的路由信息通过插桩的方式添加到HuiRouterApi中TaskAction fun taskAction() { ​ //输出到output的流 val jarOutput JarOutputStream( BufferedOutputStream(FileOutputStream(output.get().asFile)) ) ​ //遍历扫描class allDirectories.get().forEach { directory - ...... ​ scanAnnotationClass(file.inputStream()) ​ ...... } ​ //遍历扫描jar allJars.get().forEach { jarInputFile - ...... ​ if (jarEntry.name.equals(com/znh/aop/api/HuiRouterApi.class)) { routerApiJarFile jarInputFile.asFile } else { scanAnnotationClass(jarFile.getInputStream(jarEntry)) } ​ ...... } ​ //对HuiRouterApi进行插桩修改添加收集到的路由信息 routerApiJarFile?.let { transformJar(it, jarOutput) } ​ //关闭输出流 jarOutput.close() }6、在scanAnnotationClass方法中根据注解信息和目标类信息收集路由信息到annotationPathMap中/** * 扫描有目标注解的类 * * param inputStream */ private fun scanAnnotationClass(inputStream: InputStream) { val classReader ClassReader(inputStream) val classNode ClassNode() classReader.accept(classNode, ClassReader.EXPAND_FRAMES) val annotations classNode.invisibleAnnotations //获取声明的所有注解 if (annotations ! null annotations.isNotEmpty()) { annotations.forEach { aNode - if (Lcom/znh/aop/annotation/HuiRouterPath; aNode.desc) { var pathKey classNode.name if (aNode.values ! null aNode.values.size 1) { pathKey aNode.values[1] as? String } annotationPathMap[pathKey] classNode.name.replace(/, .) } } } inputStream.close() }7、在transformJar方法中将搜集到的annotationPathMap中的路由信息通过ASM插桩操作调用HuiRouterApi的addRouterPath方法添加进去。具体的插桩操作可查看Demo中的HuiRouterCVisitor和HuiRouterMVisitor其中核心的ASM字节码指令操作如下override fun onMethodExit(opcode: Int) { super.onMethodExit(opcode) annotationPathMap?.forEach { entry - mv.visitFieldInsn( GETSTATIC, com/znh/aop/api/HuiRouterApi, INSTANCE, Lcom/znh/aop/api/HuiRouterApi; ) mv.visitLdcInsn(entry.key) mv.visitLdcInsn(entry.value) mv.visitMethodInsn( INVOKEVIRTUAL, com/znh/aop/api/HuiRouterApi, addRouterPath, (Ljava/lang/String;Ljava/lang/String;)V, false ) println(HuiRouterApi - addRouterPath插入$entry) } }​8、在HuiRouterPlugin的apply方法中注册HuiRouterTask任务class HuiRouterPlugin : PluginProject { override fun apply(target: Project) { val androidComponents target.extensions.getByType(AndroidComponentsExtension::class.java) androidComponents.onVariants { variant - val taskProvider target.tasks.register(//注册HuiRouterTask任务 ${variant.name}HuiRouterTask, HuiRouterTask::class.java ) variant.artifacts.forScope(ScopedArtifacts.Scope.ALL) //扫描所有class .use(taskProvider) .toTransform( type ScopedArtifact.CLASSES, inputJars HuiRouterTask::allJars, inputDirectories HuiRouterTask::allDirectories, into HuiRouterTask::output ) } } }9、在hui_pulgin模块的build.gradle.kts中的gradlePlugin中扩展一个对HuiRouterPlugin插件的配置create(routerPlugin) { group com.znh.plugin version 1.0.1 id com.znh.plugin.router implementationClass com.znh.plugin.router.HuiRouterPlugin }10、将插件发布到本地maven中然后使用插件id “com.znh.plugin.router” 应用到项目中具体使用方式跟Page插件一样。然后为页面定义路由进行跳转测试//定义页面路由常量 object HuiConstants { const val ROUTER_PATH_DEMO path/app/DemoActivity const val ROUTER_PATH_FIRST path/app/FirstActivity const val ROUTER_PATH_SECOND path/app/SecondActivity const val ROUTER_PATH_MODULE1 path/module1/Module1Activity } ​ //DemoActivity路由配置 HuiRouterPath(HuiConstants.ROUTER_PATH_DEMO) class DemoActivity : ComponentActivity() { ​ //FirstActivity路由配置 HuiRouterPath(HuiConstants.ROUTER_PATH_FIRST) class FirstActivity : ComponentActivity() { //SecondActivity路由配置 HuiRouterPath(HuiConstants.ROUTER_PATH_SECOND) class SecondActivity : ComponentActivity() { ​ //Module1Activity路由配置 HuiRouterPath(HuiConstants.ROUTER_PATH_MODULE1) class Module1Activity : ComponentActivity() {11、在编译时和运行时可查看日志输出//编译时日志输出 Task :app:debugHuiRouterTask HuiRouterApi的静态代码块执行了 HuiRouterApi - addRouterPath插入path/module1/Module1Activitycom.znh.gradle80.plugin.module1.Module1Activity HuiRouterApi - addRouterPath插入path/app/SecondActivitycom.znh.gradle80.plugin.demo.SecondActivity HuiRouterApi - addRouterPath插入path/app/FirstActivitycom.znh.gradle80.plugin.demo.FirstActivity HuiRouterApi - addRouterPath插入path/app/DemoActivitycom.znh.gradle80.plugin.demo.DemoActivity ​ ​ //运行时log日志输出 HuiRouterApi com.znh.gradle80.plugin.demo E routerPathMap entry - path/module1/Module1Activitycom.znh.gradle80.plugin.module1.Module1Activity HuiRouterApi com.znh.gradle80.plugin.demo E routerPathMap entry - path/app/SecondActivitycom.znh.gradle80.plugin.demo.SecondActivity HuiRouterApi com.znh.gradle80.plugin.demo E routerPathMap entry - path/app/FirstActivitycom.znh.gradle80.plugin.demo.FirstActivity HuiRouterApi com.znh.gradle80.plugin.demo E routerPathMap entry - path/app/DemoActivitycom.znh.gradle80.plugin.demo.DemoActivity12、页面路由配置好后就可以通过HuiRouterApi的routerPath进行页面跳转了//跳转到FirstActivity页面 HuiRouterApi.routerPath(this, HuiConstants.ROUTER_PATH_FIRST) ​ //跳转到SecondActivity页面 HuiRouterApi.routerPath(this, HuiConstants.ROUTER_PATH_SECOND) ​ //跳转到Module1Activity页面 HuiRouterApi.routerPath(this, HuiConstants.ROUTER_PATH_MODULE1) ​ //跳转到DemoActivity页面 HuiRouterApi.routerPath(this, HuiConstants.ROUTER_PATH_DEMO)Demo地址GitHub - huihuigithub/blog_demo_projects: 记录平时学习中写的一些demogradle80-plugin-demo参考文档Android Gradle 插件 API 更新Android Gradle 插件 API 更新 | Android Studio | Android DevelopersAndroid Gradle 插件版本说明Android Gradle 插件 8.4 版本说明 | Android Studio | Android Developers官方Demogradle-recipes/Kotlin/modifyProjectClasses/app/build.gradle.kts at agp-7.4 · android/gradle-recipes · GitHub转自Gradle8.0中Transform的替代方案_gradle transform-CSDN博客
版权声明:本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!

戒赌网站怎么做ui设计一个页面多少钱

电镀加工5大坑,千万避开最后1个!在塑胶、五金等制造业中,电镀加工是提升产品外观、增强耐腐蚀性和实现特定功能的关键工艺。然而,对于寻求外协加工的厂商而言,选择不当的电镀供应商可能带来一系列问题,轻则…

张小明 2026/1/14 0:16:48 网站建设

液压产品做哪个网站好汕头网站搭建

第一章:Open-AutoGLM 任务成功率错误恢复对比在评估 Open-AutoGLM 框架的稳定性与智能决策能力时,任务成功率及其错误恢复机制成为关键指标。该框架通过动态上下文感知和多轮推理优化,在复杂任务执行中展现出较强的容错能力。错误类型与恢复策…

张小明 2026/1/14 0:14:47 网站建设

网站平台策划书平顶山专业做网站公司

还记得那个让你对着电脑屏幕眯起眼睛的下午吗?Windows系统默认的字体渲染总是让人感觉模糊不清,文字边缘发虚,长时间阅读后眼睛酸涩疲惫。今天我要分享的就是如何用MacType彻底改变这一现状,让你的Windows字体清晰锐利如macOS。 【…

张小明 2026/1/14 0:12:46 网站建设

电商网站建设实训步骤做图文网站要什么配置的服务器

在多媒体内容爆炸式增长的时代,如何快速获取优质视频资源成为众多用户关注的重点。yt-dlp-gui作为一款基于知名命令行工具yt-dlp开发的图形界面应用程序,为Windows平台用户带来了直观便捷的视频下载体验。本文将从技术架构、功能特性到实际操作进行全面剖…

张小明 2026/3/2 10:46:56 网站建设

做网站公司报价中国工程造价信息网官网

💡实话实说:CSDN上做毕设辅导的都是专业技术服务,大家都要生活,这个很正常。我和其他人不同的是,我有自己的项目库存,不需要找别人拿货再加价。我就是个在校研究生,兼职赚点饭钱贴补生活费&…

张小明 2026/3/2 12:30:54 网站建设

社交网站源代码室内设计自学软件

痛点 • 数据中心 48 V 机架散热&#xff0c;要求风扇 500 W/m 功率密度&#xff0c;MOSFET 占板面积 < 30 mm&#xff0c;Rdson 高 0.1 mΩ 就多 1 W 热&#xff0c;噪音2 dB。 • 24 V 电池瞬态 40 V&#xff0c;BVDSS 余量不足直接击穿。矽普器件• 我们的中低压MOS产品覆…

张小明 2026/1/14 0:04:41 网站建设