How to Develop an Android Studio Plugin Using the IntelliJ Platform SDK
This article guides readers from zero to one in creating Android Studio plugins by explaining the IntelliJ IDE plugin development workflow, required tools, project setup, core files like build.gradle and plugin.xml, implementing actions, wizards, tool windows, UI creation, data persistence, and packaging for distribution.
This tutorial introduces the complete workflow for developing IntelliJ IDE plugins, focusing on Android Studio as the target IDE. It starts with an overview of what IDE plugins are and why they are useful for reducing user learning cost and improving efficiency.
Prerequisites : Install IntelliJ IDEA from the JetBrains website and ensure the Android Studio version matches the IntelliJ version used for development.
Project Setup : Create a new plugin project via the Gradle wizard. The generated build.gradle must specify the IntelliJ version, localPath to Android Studio, and required plugins.
intellij {
version '2020.1.4'
localPath '/Applications/Android Studio.app/Contents'
plugins = ['Kotlin', 'android', 'git4idea']
}The core configuration files are build.gradle and plugin.xml . In plugin.xml you declare dependencies, extensions, and actions:
<idea-plugin>
...
<depends>com.intellij.modules.platform</depends>
<depends>org.jetbrains.android</depends>
<depends>com.intellij.modules.androidstudio</depends>
<extensions defaultExtensionNs="com.intellij">
<!-- add extensions here -->
</extensions>
<actions>
<!-- add actions here -->
</actions>
</idea-plugin>Creating an Action : Implement a class extending AnAction and override actionPerformed . Example in Kotlin shows a simple notification:
class HelloWorldAction : AnAction() {
override fun actionPerformed(event: AnActionEvent) {
val notificationGroup = NotificationGroup(
displayId = "myActionId",
displayType = NotificationDisplayType.BALLOON
)
notificationGroup.createNotification(
title = "chentao Demo",
content = "Hello World",
type = NotificationType.INFORMATION
).notify(event.project)
}
}Register the action in plugin.xml :
<actions>
<group id="ChentaoDemo.TopMenu" text="ChentaoDemo Plugin" description="Demo Plugin in top menu">
<action class="com.chentao.demo.actions.HelloWorldAction"
id="DemoAction"
text="Hello World Action"
description="This is a test action">
<keyboard-shortcut first-keystroke="control alt p" keymap="$default"/>
<add-to-group group-id="CutCopyPasteGroup" anchor="last"/>
</action>
</group>
<add-to-group group-id="MainMenu" anchor="last"/>
</actions>Wizard UI : Use ModelWizard and its steps ( ModelWizardStep , SkippableWizardStep ) to build multi‑page dialogs. Example Kotlin wizard class:
class CreateNewProjectAction : AnAction() {
override fun actionPerformed(e: AnActionEvent) {
StudioWizardDialogBuilder(
ModelWizard.Builder().addStep(NewProjectStep()).build(),
"Create New MARS Project"
).build().show()
}
}Tool Window : Implement ToolWindowFactory to lazily create UI panels.
public class MyToolWindowFactory implements ToolWindowFactory {
@Override
public void createToolWindowContent(@NotNull Project project, @NotNull ToolWindow toolWindow) {
MyToolWindow myToolWindow = new MyToolWindow(project, toolWindow);
ContentFactory contentFactory = ContentFactory.SERVICE.getInstance();
Content content = contentFactory.createContent(myToolWindow.getContent(), "", false);
toolWindow.getContentManager().addContent(content);
}
}Register the tool window declaratively in plugin.xml :
<extensions defaultExtensionNs="com.intellij">
<toolWindow id="MyToolWindow" secondary="true" anchor="right" factoryClass="com.volcengine.plugin.toolwindow.MyToolWindowFactory"/>
</extensions>Data Persistence : Use PropertiesComponent for simple key‑value storage or implement PersistentStateComponent for complex objects. Example of a persistent component:
@State(name = "DemoConfiguration", storages = [Storage("demoConfiguration.xml")])
class DemoComponent : ApplicationComponent, PersistentStateComponent
, Serializable {
var version = 1
var localVersion = 0
private fun isNewerVersion() = localVersion < version
private fun updateVersion() { localVersion = version }
override fun initComponent() { if (isNewerVersion()) updateVersion() }
override fun getState(): DemoComponent? = this
override fun loadState(state: DemoComponent) { XmlSerializerUtil.copyBean(state, this) }
}Packaging and Distribution : Run the Gradle assemble task to generate a ZIP file, install locally via Android Studio’s plugin manager, or publish to the JetBrains Marketplace following the standard submission process.
Conclusion : The article walks through the essential steps—environment setup, project configuration, action and UI creation, persistence, and packaging—providing a practical foundation for developers to build and distribute Android Studio plugins.
ByteDance Terminal Technology
Official account of ByteDance Terminal Technology, sharing technical insights and team updates.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.