How to write an Android Studio plugin

I have almost completed a project where I need to develop an Android Studio plugin for my work. At the beginning, it was very hard to get started because I did not find many tutorials or documents which I could refer to. Therefore, I decided to share with you my experience with Android Studio plugin. In this post, I will show you how to set up and write a very simple Android Studio plugin. You will find its source code at the end of this post.

1. Setup

You need IntelliJ IDEA as the IDE to write plugins since Android Studio is based on JetBrains’ IntelliJ IDEA. Further more, you should also download IntelliJ IDEA community source code in case you need to look at them to understand specific API usages. All the general steps to set up a plugin development are described on IntelliJ Dev Guide.

For Android plugins specifically, you have to add some more dependencies (also depending on the purpose of your plugin, in my case I used all the dependencies bellow e.g groovy, junit …), hence I need to add all of them to my project SDK, otherwise I can’t build or run my plugin.

Adding Android dependencies to your project

2. Create your plugin

Again, you can follow IntelliJ’s instruction, to create the plugin, the only remaining thing you need to do is to declare some dependencies on your plugin configuration file (plugin.xml) located at project-folder/resources/META-INF. As it is for Android Studio, we need at least Android and Gradle dependencies

<depends>org.jetbrains.android</depends>
<depends>org.jetbrains.plugins.gradle</depends>

3. Write code for your plugin

Everything has been set up, we can now try to write a “Hello world” plugin. Let’s say we will write a plugin that highlights the unused variables in your code, from now on we call it “UnsedHighlighting”. Link to the source code is at the end of this post.

-Since we want to check developer’s code for unused variables, we need to have an “inspection”. For this project, we will create a local inspection that will inspect developer’s code as they write. Let’s call it UnsedInspection, it extends the java class: BaseJavaLocalInspectionTool to inspect java related events. Further more, we only check java field (including local variables). Hence, our JavaElementVisitor will only visit fields:

public class UnusedInspection  extends BaseJavaLocalInspectionTool {
    public PsiElementVisitor buildVisitor(@NotNull final ProblemsHolder holder, final boolean isOnTheFly) {
        return new JavaElementVisitor() {
            public void visitField(PsiField field) {

            }
        };
    }
}

From now on, whenever developers declare a variable, method visitField will be called, so we need to write code that checks if a declared variable is used or not.

public void visitField(PsiField field) {
    ReferencesSearch.SearchParameters searchParameters = new ReferencesSearch.SearchParameters(
            field, field.getUseScope(), true);
    final Collection<PsiReference> variableUsaages = ReferencesSearch.search(searchParameters).findAll();
    if(variableUsaages.size() == 0){
        //variable is not used
    }
}

The code above searches for the usages of the declared filed, if the list has more than 1 items, it means that the declared variable is actually used, otherwise it is not (or it is unused). The last thing we need to do is to highlight the unused variable:

if(variableUsaages.size() == 0){
    //variable is not used
    String variableName = field.getName();
    String message = String.format("%s is not used", variableName);
    holder.registerProblem(field, message, ProblemHighlightType.GENERIC_ERROR_OR_WARNING);
}

 

4. Running your plugin to test

To successfully run the plugin, we need to register our implemented inspection with IntelliJ IDEA, we do that on the plugin.xml file

<extensions defaultExtensionNs="com.intellij>
  <!-- Add your extensions here -->
  <localInspection displayName="Unused Variable"
                   language="JAVA" enabledByDefault="true"
                   implementationClass="UnusedInspection"/>
</extensions>

Everything has been done, we now can run our plugin by clicking on the run button on the right top corner (green buttons: run and debug respectively)

Run or debug your plugin

A simulated Android Studio instance will be run as a separate application, you will have to create an Android Studio project to write code in order to test your inspection (UnusedHighlighting).

Here is the result when I declare a variable and it is unused:

How UnusedHighlighting works

 

5. Deploy your plugin to Android Studio

Since you have successfully developed a plugin, we want to run it on Android Studio (not the simulated on that IntelliJ IDEA created), we need to deploy our plugin. Fortunately, IntelliJ helps us do that easily: You can choose “Build” -> “Prepare Module Plugin xyz for Deployment”. IntelliJ will export your plugin source code into a zip or jar file which you could install on your Android Studio (Settings -> Plugins -> Install Plugin from disk). On the other hand you can also upload your plugin to IntelliJ plugin repository so other people could also use it.

6. How do I know which APIs to call and use

You may wonder, how to I know which exact API to call (i.e to find if a variable is used or not), where exactly I need to register an Inspection?

I had to read the IntelliJ IDE source code, read the built-in plugin source code and also check out their basic documents. However, I must admit that it really takes time.

Conclusion

I hope you find this post useful. Pleases comment down bellow if you want to read more about Android Studio plugin, the problems that you encounter, you would like to request another plugin for your daily development or you simply want to share your opinion on this post.

Source code: UnusedHighlighting Source Code

Leave a Reply

Your email address will not be published. Required fields are marked *