目录

  • 前言
  • 1. adb 获取当前Activity名称
  • 2. 引入Android插件库
  • 3. 插件开发
    • 3.1 获取已连接的设备
    • 3.2 执行adb Shell 命令
    • 3.3 完善UI效果

前言

在上篇文章 Android Studio 插件开发入门 中实现了在IntelliJ IDEA中点击一个菜单按钮弹出对话框。


本文在上文的基础上介绍如何编写一个IDE插件,实现获取App当前画面的Activity名称,文中有些内容是直接延用上篇文章内容,如有不明白的地方可以查看上一篇文章。

1. adb 获取当前Activity名称

ADB命令

adb shell "dumpsys window | grep mCurrentFocus"

adb 信息

 mCurrentFocus=Window{cead29 u0 com.tencent.mm/com.tencent.mm.ui.LauncherUI}

信息内容

  • 微信Package Nmae:com.tencent.mm
  • 聊天界面Activiy Name:com.tencent.mm.ui.LauncherUI

2. 引入Android插件库

首先 build.gradle文件中引入Android插件库并同步。

intellij {          plugins 'android'     }

然后在 plugin.xml 文件中添加Android插件依赖。

    <depends>com.intellij.modules.platformdepends>    //依赖Android 插件    <depends>org.jetbrains.androiddepends>

如果不在 plugin.xml 中添加上述代码,运行插件时会出现如下异常

Caused by: java.lang.ClassNotFoundException:org.jetbrains.android.sdk.AndroidSdkUtils PluginClassLoader

3. 插件开发

完成前面的工作后,只需要在 AnAction.actionPerformed 方法中执行 adb shell 命令,然后将信息在对话框中显示即可实现想要的功能。

在此先简单介绍下,需要用到的几个类。

  • com.intellij.openapi.project:表示IntelliJ项目对象
  • com.android.ddmlib.IDevice:表示Android 设备对象
  • com.android.ddmlib.AndroidDebugBridge

3.1 获取已连接的设备

class ADBAction : AnAction() {    override fun actionPerformed(e: AnActionEvent) {        val project: Project = e.project ?: error("project is error")        val device: IDevice = getConnectedDevice(project) ?: error("no connected device")        //展示已连接的设备信息        MessageDialog(device.name, device.abis.toString()).show()    }    /**     * 对象获取当前连接的设备     */    private fun getConnectedDevice(project: Project): IDevice? {        //获取所有以连接的设备        val devices: List<IDevice> =            AndroidSdkUtils.getDebugBridge(project)?.devices?.asList() ?: return null        //如果设备数量大于1 则让用户选择一个设备        if (devices.size > 1) {            val facet = AndroidUtils.getApplicationFacets(project).firstOrNull() ?: return null            //选择设备,并返回值            return DeviceSelectionUtils.chooseRunningDevice(                facet,                TargetDeviceFilter.UsbDeviceFilter(),                DeviceCount.SINGLE            )?.firstOrNull()        } else {            return devices.firstOrNull()        }    }}

运行程序,查看效果

3.2 执行adb Shell 命令

获取了连接的设备信息,在通过设备的 device.executeShellCommand() 方法执行shell命令即可。

可以看到该方法需要传入一个 IShellOutputReceiver 用于接收 shell 命令的输出日志,通过该类我们可以将输出的信息日志信息解析并展示出来。

自定义 IShellOutputReceiver 。

    class ADBMessageReceiver : MultiLineReceiver() {        //记录所有信息        private var messageLines: MutableList<String> = ArrayList()        override fun processNewLines(strings: Array<out String>) {            messageLines.addAll(strings)        }        override fun isCancelled(): Boolean = false        //输出日志接收完成后 回调此方法        override fun done() {            //拼接字符串            val message =                if (messageLines.isEmpty())                    "No message"                else                    messageLines.joinToString(separator = "")            /**             * message格式:mCurrentFocus=Window{cead29 u0 com.tencent.mm/com.tencent.mm.ui.LauncherUI}             */            val array = message.split("/")            if (array.size == 2) {                val packageName = array[0].split(" ").last()                val activityName = array[1].replace("}", "")                MessageDialog(packageName, activityName).show()            } else {                Messages.showMessageDialog(message, "adb title", Messages.getInformationIcon())            }        }    }

执行shell命令

    override fun actionPerformed(e: AnActionEvent) {        val project: Project = e.project ?: error("project is error")        val device: IDevice = getConnectedDevice(project) ?: error("no connected device")        //执行 shell 命令        val shell = "dumpsys window | grep mCurrentFocus"        device.executeShellCommand(shell,ADBMessageReceiver())    }

查看效果

3.3 完善UI效果

功能实现后,修改一下对话框的画面显示,比如 OK/Cancel 按钮,Lable的文本显示,大小等等。

修改MyMessageDialog.form

修改自定义的 MessageDialog

class MessageDialog(    private val packageName: String,    private val activityName: String) : DialogWrapper(true) {    init {        init()    }    override fun createCenterPanel(): JComponent? {        return MyMessageDialog().apply {            textPackageName.text = packageName            textActivityName.text = activityName        }.root    }    //重写创建对话框按钮的方法,只显示一个关闭按钮    override fun createActions(): Array<Action> {        val action = cancelAction.apply { putValue(DEFAULT_ACTION, true) }        return arrayOf(action)    }}

最终效果

通过上述方式,可以编写很多很多与 adb 相关的插件,例如通过adb查看app启动时间等等。

更多相关文章

  1. GitHub 标星 2.5K+!教你通过玩游戏的方式学习 VIM!
  2. 如何在后台运行Linux命令?
  3. No.11 使用firewall配置的防火墙策略的生效模式
  4. android小入门
  5. Android(安卓)Oreo 常见问题 2.0 | Android(安卓)开发者 FAQ Vol
  6. android NDK 交叉编译
  7. android busybox解决adbshell命令不全
  8. Android核心分析(18)-----Android电话系统之RIL-Java
  9. Android(安卓)-wifi 直连(wifi direct )

随机推荐

  1. 安卓开发笔记——从0到1
  2. Android(安卓)UI小贴士
  3. Android多渠道快速打包如何实现
  4. android ICS原生态Browser上增加对WML的
  5. Android中的单例模式
  6. Android应用程序提交Crash报告
  7. Android新的漏洞的应用程序中的发现!
  8. Android(安卓)NDK开发:打包so库及jar包供
  9. 最美应用-从Android研发工程师的角度之[厨
  10. Android程序开发学习笔记系列――基础篇(