多module开发时module模板插件开发

作者: a49f87ef5d4f | 来源:发表于2018-12-03 21:04 被阅读0次

    0.前言

    现在app比较流行的一种开发方式就是组件化开发,之前我曾经写过一篇文章
    Kotlin搭建组件化应用模板,介绍如何进行组件化开发的,但是这其中有个问题,每次建立业务module都需要重新修改androidmanifest文件、build文件,创建各种包,感觉及其麻烦,所以我打算写一个插件来自动生成模板module。

    1.需求

    制作插件,根据module名和包名生成对应的module模板

    2.代码

    2.1下载Intellij Idea

    2.2创建Plugin项目

    image

    2.3定义plugin.xml配置文件

    <idea-plugin>
        <id>com.skateboard.modulegenerator</id>
        <name>组件化模板module产生器</name>
        <version>1.0</version>
        <vendor email="skateboard1991@163.com" url="http://www.yourcompany.com">YourCompany</vendor>
    
        <description><![CDATA[
          用来产生模板module
        ]]></description>
    
        <change-notes><![CDATA[
          Add change notes here.<br>
          <em>most HTML tags may be used</em>
        ]]>
        </change-notes>
    
        <!-- please see http://www.jetbrains.org/intellij/sdk/docs/basics/getting_started/build_number_ranges.html for description -->
        <idea-version since-build="173.0"/>
    
        <!-- please see http://www.jetbrains.org/intellij/sdk/docs/basics/getting_started/plugin_compatibility.html
             on how to target different products -->
        <!-- uncomment to enable plugin in all products
        <depends>com.intellij.modules.lang</depends>
        -->
    
        <extensions defaultExtensionNs="com.intellij">
            <!-- Add your extensions here -->
        </extensions>
    
        <actions>
            <!-- Add your actions here -->
            <group id="com.skateboard.modulegenerator" popup="true" text="GenerateModule">
                <action id="MultiModuleGenerator" class="com.skateboard.modulegenerator.GeneratorAction"
                        text="ModuleGenerator" description="Use to generate module">
                    <add-to-group group-id="FileMenu" anchor="first"/>
                    <keyboard-shortcut keymap="$default" first-keystroke="shift ctrl P"/>
                </action>
            </group>
        </actions>
    
    </idea-plugin>
    

    其中的<name>和<description>就是插件名称和功能描述,会在你安装插件时显示。<actions>标签定义了插件的一些动作,其中<group>定义了插件显示的菜单名称和显示样式,<add-to-group>定义了将会把GenerateModule菜单栏 添加到File菜单下。<actiton>定义了action的代码的位置。

    2.4对话框的编写

    当点击ModuleGenerator选项后,会出现一个对话框,让你输入module的名称以及包名,这个对话框其实就是用java swing编写的

    ublic class ModuleInfoDialog extends JDialog {
    
        private DialogCallback dialogCallback;
    
        private final static String OK = "OK";
    
        private final static String CANCEL = "CANCEL";
    
        private final static String TITLE = "创建新module";
    
        private final static String MODULE_NAME_HINT = "请输入模块名称:";
    
        private final static String PACKAGE_NAME_HINT = "请输入包名:";
    
        private final static String ERROR_MESSAGE = "模块名和包名不能为空";
    
        public ModuleInfoDialog(DialogCallback dialogCallback) {
            setSize(450, 300);
            setModal(true);
            setTitle(TITLE);
            prepareUI();
            this.dialogCallback = dialogCallback;
    
        }
    
        private void prepareUI() {
    
    
            GridBagLayout gridBagLayout = new GridBagLayout();
            JPanel contentPannel = new JPanel();
            contentPannel.setLayout(gridBagLayout);
    
            GridBagConstraints constraints = new GridBagConstraints();
            constraints.gridx = 0;
            constraints.gridy = 0;
            constraints.gridwidth = 1;
            constraints.weightx = 0;
    
    
            JLabel moduleHintLabel = new JLabel();
            moduleHintLabel.setText(MODULE_NAME_HINT);
            contentPannel.add(moduleHintLabel, constraints);
    
            constraints.gridx = 0;
            constraints.gridy = 1;
            constraints.weightx=0;
            JLabel packageNameHintLabel = new JLabel();
            packageNameHintLabel.setText(PACKAGE_NAME_HINT);
            contentPannel.add(packageNameHintLabel, constraints);
    
            constraints.gridx = 1;
            constraints.gridy = 0;
            constraints.weightx=1;
            constraints.fill=GridBagConstraints.HORIZONTAL;
            JTextField moduleNameImp = new JTextField();
            moduleNameImp.setForeground(Color.WHITE);
            contentPannel.add(moduleNameImp, constraints);
    
            constraints.gridx = 1;
            constraints.gridy = 1;
            constraints.weightx=1;
            constraints.fill=GridBagConstraints.HORIZONTAL;
            JTextField packageNameImp = new JTextField();
            packageNameImp.setForeground(Color.WHITE);
            contentPannel.add(packageNameImp, constraints);
    
    
            JLabel errorLabel = new JLabel();
            errorLabel.setForeground(Color.RED);
            errorLabel.setVisible(false);
    
    
            JButton okBtn = new JButton();
            okBtn.setText(OK);
            okBtn.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    if (moduleNameImp.getText().isEmpty() || packageNameImp.getText().isEmpty()) {
                        errorLabel.setVisible(true);
                        errorLabel.setText(ERROR_MESSAGE);
                        return;
                    }
                    if (dialogCallback != null) {
                        dialogCallback.onOkClicked(moduleNameImp.getText(), packageNameImp.getText());
                    }
                    dispose();
                }
            });
    
    
            JButton cancelBtn = new JButton();
            cancelBtn.setText(CANCEL);
            cancelBtn.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
    
                    if (dialogCallback != null) {
                        dialogCallback.onCancelClicked();
                    }
                    dispose();
                }
            });
    
            constraints.anchor=WEST;
            constraints.weightx=0;
            constraints.gridx = 0;
            constraints.gridy = 2;
            contentPannel.add(okBtn, constraints);
    
            constraints.fill=GridBagConstraints.NONE;
            constraints.gridy = 2;
            constraints.gridx = 1;
            contentPannel.add(cancelBtn, constraints);
    
            constraints.gridy = 3;
            constraints.gridx = 0;
            contentPannel.add(errorLabel, constraints);
    
            setContentPane(contentPannel);
        }
    
    
        interface DialogCallback {
    
            void onOkClicked(String moduleName, String packageName);
    
            void onCancelClicked();
        }
    
    
        public static void pop(DialogCallback callback) {
            ModuleInfoDialog infoDialog = new ModuleInfoDialog(callback);
            Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
            infoDialog.setLocation(screenSize.width / 2 - infoDialog.getWidth() / 2, screenSize.height / 2 - infoDialog.getHeight() / 2);
            infoDialog.setVisible(true);
        }
    
    }
    
    

    没什么特别要说的,就是构建了一个dilaog,其中的静态方法pop()用来显示这个dialog

    2.5action的编写

    当我们点击ModuleGenerator的这个选项时,会产生一个action,这里要实现对应的逻辑,就是我们创建模板文件的地方。首先创建一个类GeneratorAction并继承自AnAction,同时需要复写actionPerformed方法,看一下GeneratorAction的actionPerformed方法

     ModuleInfoDialog.pop(new ModuleInfoDialog.DialogCallback() {
                @Override
                public void onOkClicked(String moduleName, String packageName) {
                    generateModuleFiles(moduleName, packageName, e.getProject().getBasePath());
                    e.getProject().getBaseDir().refresh(true, true);
    
                }
    
                @Override
                public void onCancelClicked() {
    
                }
            });
    

    首先就是产生刚才说的用来输入module名和包名的dialog,当点击ok按钮后,就会创建项目模板文件和同步工程文件了。其中的generateModuleFils方法就是创建相应的文件夹和文件的,具体实现看代码就好了,没什么可说的。

    3.问题

    gradle文件中指定的intellij的版本号

    intellij {
        version '2018.1'
    }
    

    plugin.xml中指定的idea的build version

    <idea-version since-build="181.0"/>
    

    要和android studio的版本相对应,否则会出现错误
    plugin *** is incompatible with this installation

    4.项目地址

    github
    gradle运行runIde 这个task

    image

    关注我的公众号

    相关文章

      网友评论

        本文标题:多module开发时module模板插件开发

        本文链接:https://www.haomeiwen.com/subject/fvbucqtx.html