Android Studio插件开发 - Dora SDK的IDE插件

IDE插件开发简介

Android Studio是一种常用的集成开发环境(IDE),用于开发Android应用程序。它提供了许多功能和工具,可以帮助开发人员更轻松地构建和调试Android应用程序。

如果你想开发Android Studio插件,以下是一些基本步骤:

  1. 确保你已经安装了最新版本的Android Studio。你可以从官方网站(https://developer.android.com/studio)下载并安装它。
  2. 了解Android Studio插件的基本结构和原理。Android Studio插件是基于IntelliJ平台构建的,因此你可以通过学习IntelliJ插件开发来了解Android Studio插件的开发。
  3. 创建一个新的插件项目。在Android Studio中,选择"File" -> “New” -> “New Project”,然后选择"IntelliJ Platform Plugin"作为项目类型。
  4. 定义你的插件。你可以通过插件描述文件(plugin.xml)来指定插件的名称、版本、依赖项等信息。
  5. 实现插件的功能。根据你的需求,你可以使用Java或Kotlin编写插件的代码。你可以使用IntelliJ平台提供的API来访问和操作Android Studio的功能和组件。
  6. 编译和运行插件。在Android Studio中,选择"Run" -> "Run ‘plugin_name’"来编译和运行你的插件。这将启动一个新的实例,并加载你的插件。
  7. 测试和调试插件。你可以使用Android Studio的调试功能来调试你的插件代码。在开发过程中,确保测试你的插件在各种情况下的行为和兼容性。
  8. 打包和发布插件。一旦你完成了插件的开发和测试,你可以将插件打包为一个JAR文件,并上传到Android Studio的插件市场(https://plugins.jetbrains.com/androidstudio)或其他适当的位置。

这只是一个简单的概述,帮助你入门Android Studio插件开发。要深入了解插件开发的详细内容,你可以查阅Android Studio和IntelliJ平台的官方文档,并参考一些示例代码和教程。祝你成功开发自己的Android Studio插件!

Dora SDK的Android Studio插件介绍

Dora SDK
https://github.com/dora4/dora ,是由Dora开发的,没错,就是我,一款高效开发Android App的基础架构。而Dora Android Studio Plugin则提供了快捷使用Dora SDK的功能,即以图形化界面的方式,创建继承自dora.BaseActivity的Activity类和继承自dora.BaseFragment的Fragment类。这样就方便了大家高效地使用Dora SDK开发很多很多的界面啦!

product.png

依赖Dora SDK的Android Studio插件

使用步骤其实也很简单,总共就下载和安装两步。

install-jar.png

使用Dora SDK的Android Studio插件创建模板代码

创建模板代码也是只有简简单单的两步。

step1.png

step2.png

通过插件源码编译适合自己Android Studio版本使用的插件包

敲黑板,重点来了。通常情况下,我们使用的Android Studio版本是不一致的,除非我们心灵相通,比较默契,是吧!首先你要查看你当前使用的Android Studio的版本。

截屏2023-05-20 02.46.08.png

截屏2023-05-20 02.47.41.png
把AI后面的这一串数字复制下来。IDEA有很多分支变体版本,AI就代表我们的Android Studio。

然后修改gradle的配置,

compileKotlin {
    kotlinOptions.jvmTarget = 你的jdk版本
}

compileTestKotlin {
    kotlinOptions.jvmTarget = 你的jdk版本
}

// See https://github.com/JetBrains/gradle-intellij-plugin/
intellij {
    plugins = ['Kotlin', 'android']
    version.set("你的Android Studio版本,如213.7172.25.2113.9123335")
    // Android Studio的代号是AI
    type.set("AI")
}

JDK的版本在[File] - [Project Structure]中配置。我们还要配置一下我们项目的类型为Gradle项目。点击[Edit Configrations],选择Gradle,点OK,然后就可以编译插件了。编译后的插件生成目录为dora-studio-plugin/build/libs/,然后照着本文前面所提到的本地安装插件的步骤就可以了。

插件源码讲解

最后,我觉得还是有必要简单讲解下插件的源码。

截屏2023-05-20 02.55.46.png

目录结构大概是这样的。插件代码在kotlin目录下,资源则在resources目录下。我们先从resources/META-INF/plugin.xml看起,里面配置了插件的一些基本信息,重要的是这个入口。

<extensions defaultExtensionNs="com.android">
    <!-- Add your extensions here -->
    <tools.idea.wizard.template.wizardTemplateProvider
        implementation="com.dorachat.templates.recipes.DoraTemplateWizardProvider"/>
</extensions>

这里配置了一个模板向导提供者。

package com.dorachat.templates.recipes

import com.android.tools.idea.wizard.template.WizardTemplateProvider

class DoraTemplateWizardProvider: WizardTemplateProvider() {
    override fun getTemplates() = listOf(MVVMActivityTemplate, MVVMFragmentTemplate)
}

因为我们总共有两套模板,所以这里列出这两套模板的类名。以MVVMActivityTemplate为例。

package com.dorachat.templates.recipes

import com.android.tools.idea.wizard.template.*
import com.android.tools.idea.wizard.template.impl.activities.common.MIN_API
import java.io.File

object MVVMActivityTemplate : Template {
    override val category: Category
        get() = Category.Activity
    override val constraints: Collection<TemplateConstraint>
        get() = emptyList()     //AndroidX, kotlin
    override val description: String
        get() = "创建一个dora.MVVMActivity,来自https://github.com/dora4/dora"
    override val documentationUrl: String?
        get() = null
    override val formFactor: FormFactor
        get() = FormFactor.Mobile
    override val minSdk: Int
        get() = MIN_API
    override val name: String
        get() = "MVVM Activity"
    override val recipe: Recipe
        get() = {
            mvvmActivityRecipe(
                    it as ModuleTemplateData,
                    activityClassInputParameter.value,
                    activityTitleInputParameter.value,
                    layoutNameInputParameter.value,
                    packageName.value
            )
        }
    override val uiContexts: Collection<WizardUiContext>
        get() = listOf(WizardUiContext.ActivityGallery, WizardUiContext.MenuEntry, WizardUiContext.NewProject, WizardUiContext.NewModule)
    override val useGenericInstrumentedTests: Boolean
        get() = false
    override val useGenericLocalTests: Boolean
        get() = false
    override val widgets: Collection<Widget<*>>
        get() = listOf(
                TextFieldWidget(activityTitleInputParameter),
                TextFieldWidget(activityClassInputParameter),
                TextFieldWidget(layoutNameInputParameter),
                PackageNameWidget(packageName),
                LanguageWidget()
        )

    override fun thumb(): Thumb {
        return Thumb { findResource(this.javaClass, File("template_mvvm_activity.png")) }
    }

    val activityClassInputParameter = stringParameter {
        name = "Activity Name"
        default = "MainActivity"
        help = "The name of the activity class to create"
        constraints = listOf(Constraint.CLASS, Constraint.UNIQUE, Constraint.NONEMPTY)
        suggest = { layoutToActivity(layoutNameInputParameter.value) }
    }

    var layoutNameInputParameter: StringParameter = stringParameter {
        name = "Layout Name"
        default = "activity_main"
        help = "The name of the layout to create for the activity"
        constraints = listOf(Constraint.LAYOUT, Constraint.UNIQUE, Constraint.NONEMPTY)
        suggest = { activityToLayout(activityClassInputParameter.value) }
    }

    val activityTitleInputParameter = stringParameter {
        name = "Title"
        default = "Main"
        help = "The name of the activity. For launcher activities, the application title"
        visible = { false }
        constraints = listOf(Constraint.NONEMPTY)
        suggest = { buildClassNameWithoutSuffix(activityClassInputParameter.value, "Activity") }
    }
    val packageName = defaultPackageNameParameter
}

这里是不是配置了一些创建模板的信息?包括编译的最低sdk版本,有哪些输入框等等。这些输入控件需要指定输入类型的参数,如stringParameter。suggest表示输入的建议,简单的说,就是让别的输入框的内容跟当前输入的内容联动。还有一个重点就是这个recipe,它决定了这个模板代码怎么去生成。

package com.dorachat.templates.recipes

import com.android.tools.idea.wizard.template.*
import com.android.tools.idea.wizard.template.impl.activities.common.generateManifest
import com.dorachat.templates.recipes.app_package.res.layout.mvvmActivityXml
import com.dorachat.templates.recipes.app_package.res.layout.mvvmFragmentXml
import com.dorachat.templates.recipes.app_package.src.mvvmActivity
import com.dorachat.templates.recipes.app_package.src.mvvmActivityKt
import com.dorachat.templates.recipes.app_package.src.mvvmFragment
import com.dorachat.templates.recipes.app_package.src.mvvmFragmentKt
import java.lang.StringBuilder

fun RecipeExecutor.mvvmActivityRecipe(
        moduleData: ModuleTemplateData,
        activityClass: String,
        activityTitle: String,
        layoutName: String,
        packageName: String
) {
    val (projectData, srcOut, resOut) = moduleData


    generateManifest(
            moduleData = moduleData,
            activityClass = activityClass,
//            activityTitle = activityTitle,
            packageName = packageName,
            isLauncher = false,
            hasNoActionBar = false,
            generateActivityTitle = false,

    )

    if (projectData.language.equals(Language.Kotlin)) {
        save(mvvmActivityKt(projectData.applicationPackage ?: packageName, packageName, activityClass,
                buildBindingName(layoutName), layoutName), srcOut.resolve("${activityClass}.${projectData.language.extension}"))
    }
    if (projectData.language.equals(Language.Java)) {
        save(mvvmActivity(projectData.applicationPackage ?: packageName, packageName, activityClass,
                buildBindingName(layoutName), layoutName), srcOut.resolve("${activityClass}.${projectData.language.extension}"))
    }
    save(mvvmActivityXml(packageName, activityClass), resOut.resolve("layout/${layoutName}.xml"))

    open(resOut.resolve("layout/${layoutName}.xml"))

}

如果要考虑比较周全,肯定是Java和Kotlin语言开发的项目代码都要能生成,然后创建Activity类的同时也把对应的布局xml文件也创建了,并且打开给使用者看一下,便于直接添加到git版本控制。

总结

有兴趣的同学可以参阅插件项目的源代码,https://github.com/dora4/dora-studio-plugin 和Dora SDK的源代码https://github.com/dora4/dora 。另外,我的开发套件三驾马车分别是dora、dcache和dview,你也可以称为“三剑客”。这是使用Android Studio插件开发代码生成模板的一个案例,插件开发还可以完全自定义功能,本文篇幅有限,就不细说了,大概是通过Action作菜单按钮和Java Swing作为图形界面,开发任意Java能实现的内容。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/673833.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

MyBatis框架-开发方式+参数传递+#{}、${}+返回值处理+查询结果封装为对象+resultType

一、开发方式 MyBatis-Dao层Mapper接口化开发 二、注意事项 1、Mapper接口与Mapper.xml映射文件要满足4个对应 &#xff08;1&#xff09;Mapper接口的全类名必须与Mapper映射文件中的namespace相同 &#xff08;2&#xff09;Mapper接口中的每一个方法名在Mapper映射文件…

密码加密及验证

目录 为什么需要加密&#xff1f; 密码算法分类 对称密码算法 非对称密码算法 摘要算法 DigestUtils MD5在线解密工具原理 实现用户密码加密 代码实现 为什么需要加密&#xff1f; 在MySQL数据库中&#xff0c;我们常常需要对用户密码、身份证号、手机号码等敏感信息进…

pod 控制器介绍

一 pod 控制器相关理论介绍 1&#xff0c;Pod控制器 是什么 Pod控制器&#xff0c;又称之为工作负载&#xff08;workload&#xff09;&#xff0c;是用于实现管理pod的中间层&#xff0c;确保pod资源符合预期的状态&#xff0c;pod的资源出现故障时&#xff0c;会尝试进行…

使用modbus-serial 库搭配 modbus slave 通过 modbus tcp client 协议来 写入 modbus 寄存器值

使用modbus-serial 库对modbus slave 写入寄存器值 modbus tcp client 代码 目标电脑&#xff08;启动modbus slave 的电脑&#xff09;ip为 192.168.3.46&#xff0c;端口502 // 读取另一台电脑&#xff0c;192.168.3.46:502 Modbus TCP // create an empty modbus client c…

2005NOIP普及组真题 4. 循环

线上OJ&#xff1a; 【05NOIP普及组】循环 核心思想&#xff1a;高精度 1、本题用到了标准的高精度乘法模板 void init(int a[]) //传入一个数组 {string s; cin >> s; //读入字符串s a[0] s.length(); //用a[0]计算字符串s的位数 for(i 1; i < a[0]; i) a[i] …

颠覆与重塑|AI助力汽车开发,汽车智能势不可挡

汽车行业深受人工智能的影响&#xff0c;人工智能正在为我们创造全新的出行方式。随着智能化的加速普及&#xff0c;越来越多的消费者开始关注汽车的智能化。智能化的水平已经成为众多消费者购车的参考因素&#xff0c;也成了车企竞争的主赛道&#xff0c;汽车行业也已经成为人…

高校科研信息管理系统的设计

管理员账户功能包括&#xff1a;系统首页&#xff0c;个人中心&#xff0c;公告管理&#xff0c;反馈管理&#xff0c;操作日志管理&#xff0c;科研项目管理&#xff0c;通知管理 科研人员账户功能包括&#xff1a;系统首页&#xff0c;个人中心&#xff0c;反馈管理&#xff…

[SQL-SERVER:数据库安全及维护]:MSSM工具对用户进行用户授权和角色授权操作

文章目录 直接为用户授权&#xff08;20分&#xff09;1. 创建登录TLogin&#xff0c;自行指定登录密码服务器层面选择 安全性 > 点击 登录名 > 点击右键 > 点击 新建登录名 > 选择sqlserver验证 > 关闭强制登录更改密码异常解决&#xff1a;sqlserver 配置管理…

【最新鸿蒙应用开发】——什么是应用开发模型?Stage模型

在应用程序开发时通常需要使用应用模型来提供必备的组件和运行机制&#xff0c;有了应用模型&#xff0c;开发者可以基于一套统一的模型进行应用开发&#xff0c;使应用开发更简单、高效。接下来谈谈鸿蒙应用开发当中的两种模型&#xff1a; Stage模型&#xff1a; HarmonyOS …

过滤器、监听器、拦截器的区别

过滤器、监听器、拦截器的区别 过滤器&#xff08;filter&#xff09;、监听器&#xff08;Listener&#xff09;是JavaWeb的三大组件。而拦截器&#xff08;Interceptor&#xff09;是Spring框架中的。 我们主要是要分清除过滤器和拦截器的区别&#xff1a; 实现原理&#…

晶体(二):差分晶振

一、定义 差分晶振是一种有源晶体振荡器&#xff0c;输出差分信号&#xff08;由两个相位相反、幅度相等的信号组成&#xff09;&#xff0c;从而消除了共模噪声&#xff0c;具有抗干扰能力强、对参考电平完整性要求较弱、抑制串扰、EMI 能力强、功耗小、速率高、不受温度和电压…

【Ubuntu常用命令】终端个人常用命令总结

【Ubuntu常用命令】终端常用命令总结 查看硬盘挂载情况查看内存占用情况移动或重命名文件和目录复制文件或目录conda安装本地文件 查看硬盘挂载情况 mount 命令会列出当前系统上所有已挂载的文件系统。它会显示挂载点、文件系统类型、挂载选项等信息 mount df 命令用于显示文…

MySQL学习——影响选项文件处理的命令行选项和程序选项修改器

大多数支持选项文件的MySQL程序都处理以下选项。因为这些选项会影响选项文件的处理&#xff0c;所以必须在命令行上给出&#xff0c;而不是在选项文件中给出。为了正常工作&#xff0c;这些选项中的每一个都必须先于其他选项给出&#xff0c;但以下情况除外&#xff1a; -prin…

AK F.*ing leetcode 流浪计划之费马小定理与组合数取模

欢迎关注更多精彩 关注我&#xff0c;学习常用算法与数据结构&#xff0c;一题多解&#xff0c;降维打击。 费马小定理与证明 参考 https://zhuanlan.zhihu.com/p/594859227 费马小定理&#xff1a;如果p是一个质数&#xff0c;而正整数a不是p的倍数&#xff0c;那么a(p-1)≡…

继承的基本语法

自学python如何成为大佬(目录):https://blog.csdn.net/weixin_67859959/article/details/139049996?spm1001.2014.3001.5501 在编写类时&#xff0c;并不是每次都要从空白开始。当要编写的类和另一个已经存在的类之间存在一定的继承关系时&#xff0c;就可以通过继承来达到代…

AI早班车6.3

1.蚂蚁技术日&#xff1a;支付宝三大「AI 管家」亮相。 2.百度赵世奇&#xff1a;百度搜索&#xff0b;文心智能体平台&#xff0c;助力智能体人人可用。 3.腾讯&#xff1a;发布大模型App腾讯元宝。 4.AFAC2024金融智能创新大赛启动&#xff0c;让高质量金融服务人人可用 …

Docker笔记-解决非交互式运行python时print不输出的问题

换句话来说就是在docker中如何不会python的print 只需要在启动时&#xff0c;不让python缓冲其输出。 关键命令如下&#xff1a;PYTHONUNBUFFERED1 如下&#xff1a; docker run -e PYTHONUNBUFFERED1 <your_image> 下面解释下-e "-e"选项的全称是"…

lux和ffmpeg进行下载各大主流自媒体平台视频

1、lux下载&#xff0c;链接&#xff1a;https://pan.baidu.com/s/1WjGbouL3KFTU6LeqZmACpA?pwdagpp 提取码&#xff1a;agpp 2、ffmpeg下载&#xff0c;跟lux放在同一个目录&#xff1b; 3、为lux、ffmpeg设置环境变量&#xff1b; 4、WINR&#xff0c;打开运行&#xff0…

Love-Yi情侣网站3.0存在SQL注入漏洞

目录 1. 前言 2. 网站简介 3. 寻找特征点 3.1 第一次尝试 3.2 第二次尝试 4.资产搜索 5.漏洞复现 5.1 寻找漏洞点 5.2 进行进一步测试 5.2.1 手动测试 1.寻找字段 2.寻找回显位 3.查询当前用户 5.2.2 sqlmap去跑 6.总结 1. 前言 朋友说自己建了一个情侣网站,看到…

chat4-Server端保存聊天消息到mysql

本文档描述了Server端接收到Client的消息并转发给所有客户端或私发给某个客户端 同时将聊天消息保存到mysql 服务端为当前客户端创建一个线程&#xff0c;此线程接收当前客户端的消息并转发给所有客户端或私发给某个客户端同时将聊天消息保存到mysql 本文档主要总结了将聊天…