学会编写Android Studio插件 别停留在用的程度了

本文为原创,授权公众号:hongyangAndroid独家代理原创发布。

转载请标明出处: 
http://blog.csdn.net/lmj623565791/article/details/51548272; 
本文出自:【张鸿洋的博客】

一、概述

相信大家在使用Android Studio的时候,或多或少的会使用一些插件,适当的配合插件可以帮助我们提升一定的开发效率,更加快乐。例如:

有句话叫做授人以鱼不如授人以渔,不能一直跟随着别人的脚步去使用插件了,有必要去学习编写插件,当自己有好的创意的时候,就可以自己实现了。So,本文的内容是:

  • 自己编写一个Android Studio插件

ok,其实编写插件并不难,官方也有详细的文档,所以你也可以选择直接阅读下文学习:

为了文章有一定的流畅性,决定以ECTranslation作为编写Android Studio插件的例子。

我为什么选这个呢?因为创意好,实用并且代码简单。

贴一个今天这个插件的最终效果图:

注:效果与ECTranslation基本一致,本文仅用作学习,不造轮子,如果需要使用,直接使用ECTranslation即可。

二、准备工作

首先需要安装IntelliJ IDEA

下载好就可以了~~

然后安装,运行,点击create New Project:

按照上图进行选择,如果没有SDK,则点击New新建一个即可。

然后点击Next,输入项目名称选择位置,就可以点击finish了。

项目的结构如下:

src目录下主要用于存放我们编写的代码。

这样准备工作就结束了~~

三、编码

(1) 关键知识

编码实际上核心的一个类叫做AnAction,可以直接选择NEW->Action,如下图:

然后填写一些相关信息:

需要填写的属性如下:

  • ActionID:代表该Action的唯一的ID,一般的格式为:pluginName.ID
  • ClassName:类名
  • Name:就是最终插件在菜单上的名称
  • Description:对这个Action的描述信息

然后往下,选择这个Action即将存在的位置:

我们选择的是EditMenu,右侧选择为first,即EditMenu下的第一个,效果如图:

再往下就是制定快捷键了~~

都填写完成就可以点击OK了。

点击ok之后,可以看到为我们生成了下类:

public class TranslateAction extends AnAction {
    @Override
    public void actionPerformed(AnActionEvent e) {
        // TODO: insert action logic here
    }
}
   
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

此外我们刚才填写的信息,也在plugin.xml中完成了注册,大家可以进去看一眼,actions的标签中,

当我们点击菜单的时候,就回触发actionPerformed()方法。

那么这么看,我们在这个方法中只要完成三件事:

  1. 获得当前选中的单词
  2. 调用相关API得到单词的意思
  3. 通过一个类似于PopupWindow来显示

当然,为了尽快的测试,你可以先在里面弹一个对话框,例如如下:

 public void actionPerformed(AnActionEvent event) {
        Messages.showMessageDialog("Hello World !", "Information", Messages.getInformationIcon());
    }
   
  • 1
  • 2
  • 3
  • 1
  • 2
  • 3

预期效果是点击Tranlate菜单,或者按快捷键会弹出一个提示对话框。

那么点击Run:

然后它会默认启动一个新的IntelliJ IDEA的界面,你可以随便新建一个项目,进入以后,你会发现Edit下多了一个Translate菜单,点击即可弹出我们设定的对话框:

ok,测试通过就放心了~

  1. 获得当前选中的单词
  2. 调用相关API得到单词的意思
  3. 通过一个类似于PopupWindow来显示

剩下的就是功能性的API了~

(2) 获得当前选中的单词

 @Override
public void actionPerformed(AnActionEvent e) {
    // TODO: insert action logic here
    final Editor mEditor = e.getData(PlatformDataKeys.EDITOR);
    if (null == mEditor) {
        return;
    }
    SelectionModel model = mEditor.getSelectionModel();
    final String selectedText = model.getSelectedText();
    if (TextUtils.isEmpty(selectedText)) {
        return;
    }
}
   
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

是不是觉得API很陌生,恩,我也觉得很陌生,关于API这里介绍其实没什么意义,本文主要目的是让大家对自定义插件有个类helloworld的认识,至于插件里面的代码涉及到的API等到大家需要编写插件的时候,再详细学习就好了,现在就不要浪费精力记忆这些东西了。

上面的代码就是获得选中的文本,通过一个Editor,然后拿到SelectionModel,再拿到selectedText,从字面上还是蛮好理解的。

拿到选中的文本之后,应该就是去查询该单词的意思了,查询呢,ECTranslation用的是youdao的Open SDK,其实也很简单,就是拼接一个url,然后等着解析返回数据就好了。

(3)调用相关API得到单词的意思

有道API的地址:

大家如果想要做单词翻译,可以看下,非常简单。

涉及到的代码:

String baseUrl = "http://fanyi.youdao.com/openapi.do?keyfrom=Skykai521&key=977124034&type=data&doctype=json&version=1.1&q=";

HttpUtils.doGetAsyn(baseUrl + selectedText, new HttpUtils.CallBack() {
    public void onRequestComplete(String result) {
        Translation translation = gson.fromJson(result, Translation.class);
        showPopupBalloon(mEditor, translation.toString());
    }
});
   
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

HttpUtils就不贴了,就是直接开了个线程,通过HttpUrlConnection去访问网络,大家的项目中或者通过搜索引擎,代码一搜一堆。

baseUrl就是有道的url,加上我们选中的单词就是完整的url了,然后通过http访问,callback回调出返回的字符串,这里返回的是json类型的字符串。

baseUri是:

我们根据返回的json字符串生成了一个类Translation;

然后通过Gson转化为Translation对象。

ps:拿着上面的baseUrl后面跟一个任何单词,直接访问浏览器就能看到返回的json数据了,这里大家天天写接口,类似的步骤比我肯定还熟悉。

好了,有了返回的数据以后,直接通过一个类似popupWindow展现即可。

(4)通过一个类似于PopupWindow来显示

涉及到的代码:

private void showPopupBalloon(final Editor editor, final String result) {
    ApplicationManager.getApplication().invokeLater(new Runnable() {
        public void run() {
            JBPopupFactory factory = JBPopupFactory.getInstance();
            factory.createHtmlTextBalloonBuilder(result, null, new JBColor(new Color(186, 238, 186), new Color(73, 117, 73)), null)
                    .setFadeoutTime(5000)
                    .createBalloon()
                    .show(factory.guessBestPopupLocation(editor), Balloon.Position.below);
        }
    });
}
   
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

这个API,恩,我copy的源码,依然是不求记住,知道这有个类似的功能即可。

简单看一下,是通过创建一个JBPopupFactory,然后通过它创建一个HtmlTextBalloonBuilder,通过这个builder去设置各种参数,最后show。

ok,对于一个入门的例子,不要太强求对插件中这些API的掌握,还是那句话,等需要写了再去查,需要什么功能,哪怕到对应的插件中去copy源码都可以,当然也有文档:

有兴趣的可以整理各种类型的插件,比如弹出popupWindow,生成代码,生成文件类别的,然后对相关的API进行收集与整理。

这样代码写完了,先测试一下,点击RUN,然后看效果~

我们这里肯定是测试没问题的,效果图就是开始的那个gif.

如果没有问题,就可以去部署和发布我们的插件给别人去使用了。

这两部也非常简单。

四、部署插件

(1)填写插件相关信息

打开项目文件的plugin.xml,如下图:

在里面填写id,name,version等。。。记得随便填一下~

然后,点击build->prepare plugin…,如下图:

会在项目的根目录生成一个jar,如图:

这个jar就可以用于安装了。

(2)安装插件

打开Andorid Studio,选择Preferences -> Plugins -> Install plugin from disk,选择我们生成的jar即可,如图:

点击安装,然后重启即可。

好了,重启完成就可以在EDIT下看到Translate菜单了,选中单词,点击菜单或者快捷键都能实现翻译了。

如果你有兴趣,赶紧编写一个插件自己玩吧。

当然,还可以把我们的插件发布到仓库,支持在plugin中搜索安装,参考:

就是注册账号,提交jar,填写信息,等着审核就可以了。

五、总结

终于到了总结的环节,这么长的文章其实编写插件总结起来就几句话。

  1. 下载Intellij IDEA,新建一个Intellij IDEA plugin的项目
  2. 然后在里面new Action以及编写API
  3. 点击prepare plugin生成jar,这个jar就可以用来安装了。

恩,就是这么简单,实践起来会比较麻烦一点,等成功以后,回过头来总结,发现步骤其实就那么几个步骤~~对于实际的Action相关的API,等你在编写相关插件的时候,参考别的类似插件,查看官方文档都可以。

### 在 Android Studio 中集成 Kimi Code API 的完整指南 Kimi Code 是月之暗面公司推出的智能编程助手,通过其开放的 API 接口,开发者可以将其集成到 Android Studio 中,获得智能代码补全、错误检测和编程建议等功能。下面详细介绍接入方法和实现步骤。 #### 一、前期准备工作 在开始集成前,需要完成以下准备工作: | 准备事项 | 具体说明 | |---------|----------| | 获取 API Key | 访问月之暗面开发者平台注册账号并创建应用,获取专属 API Key [ref_1] | | 确认 API 端点 | 当前 Kimi Code 的服务端点为 `https://api.moonshot.cn/v1/chat/completions` [ref_1] | | 网络权限配置 | 在 AndroidManifest.xml 中添加 `<uses-permission android:name="android.permission.INTERNET"/>` | | 依赖库引入 | 在 build.gradle 中添加 Retrofit 和 Gson 依赖 | **build.gradle 依赖配置示例:** ```kotlin dependencies { implementation 'com.squareup.retrofit2:retrofit:2.9.0' implementation 'com.squareup.retrofit2:converter-gson:2.9.0' implementation 'com.squareup.okhttp3:logging-interceptor:4.11.0' } ``` #### 二、核心实现步骤 ##### 1. 定义 API 请求数据模型 根据 Kimi Code API 文档,需要构建符合要求的请求体和响应体数据结构 [ref_1]。 **请求数据模型:** ```kotlin data class KimiRequest( val model: String = "kimi-code", // 指定使用 kimi-code 模型 val messages: List<Message>, val temperature: Double = 0.3, // 控制生成随机性 val stream: Boolean = false // 是否使用流式响应 ) data class Message( val role: String, // "user" 或 "assistant" val content: String // 消息内容 ) data class KimiResponse( val choices: List<Choice> ) data class Choice( val message: Message ) ``` ##### 2. 创建 Retrofit 服务接口 使用 Retrofit 创建网络请求接口,这是与 Kimi Code API 通信的核心组件。 ```kotlin interface KimiCodeService { @POST("chat/completions") suspend fun getCodeCompletion( @Header("Authorization") authorization: String, @Body request: KimiRequest ): KimiResponse @Streaming @POST("chat/completions") suspend fun getStreamingCompletion( @Header("Authorization") authorization: String, @Body request: KimiRequest ): Response<ResponseBody> } ``` ##### 3. 配置 Retrofit 实例和 OkHttpClient 设置网络客户端,包括认证头信息和超时配置。 ```kotlin class KimiCodeClient { companion object { private const val BASE_URL = "https://api.moonshot.cn/v1/" private const val API_KEY = "your_api_key_here" // 替换为实际 API Key fun create(): KimiCodeService { val client = OkHttpClient.Builder() .addInterceptor { chain -> val request = chain.request().newBuilder() .addHeader("Authorization", "Bearer $API_KEY") .addHeader("Content-Type", "application/json") .build() chain.proceed(request) } .connectTimeout(30, TimeUnit.SECONDS) // 设置连接超时 .readTimeout(60, TimeUnit.SECONDS) // 设置读取超时 .build() return Retrofit.Builder() .baseUrl(BASE_URL) .client(client) .addConverterFactory(GsonConverterFactory.create()) .build() .create(KimiCodeService::class.java) } } } ``` ##### 4. 实现 Android Studio 插件集成 为了在 Android Studio 中直接使用 Kimi Code,可以创建一个简单的插件来处理代码补全请求。 **插件入口类:** ```kotlin class KimiCodePlugin : ApplicationComponent { private val kimiService = KimiCodeClient.create() override fun initComponent() { // 注册编辑器动作 val actionManager = ActionManager.getInstance() actionManager.registerAction("KimiCodeCompletion", KimiCodeCompletionAction()) } class KimiCodeCompletionAction : AnAction("Get Kimi Code Suggestion") { override fun actionPerformed(e: AnActionEvent) { val editor = e.getData(CommonDataKeys.EDITOR) ?: return val project = e.project ?: return // 获取当前选中的代码或光标位置的代码段 val selectedText = editor.selectionModel.selectedText ?: getCurrentLineText(editor) // 在后台线程中调用 Kimi Code API CoroutineScope(Dispatchers.IO).launch { try { val suggestion = getCodeSuggestion(selectedText) // 在主线程中更新 UI withContext(Dispatchers.Main) { insertSuggestion(editor, suggestion) } } catch (e: Exception) { println("Kimi Code API 调用失败: ${e.message}") } } } private suspend fun getCodeSuggestion(codeContext: String): String { val request = KimiRequest( messages = listOf( Message(role = "user", content = "请为以下代码提供补全建议: $codeContext") ) ) val response = kimiService.getCodeCompletion("Bearer ${KimiCodeClient.API_KEY}", request) return response.choices.firstOrNull()?.message?.content ?: "暂无建议" } private fun insertSuggestion(editor: Editor, suggestion: String) { val document = editor.document val caretModel = editor.caretModel document.insertString(caretModel.offset, "\n// Kimi Code 建议:\n$suggestion") } } } ``` #### 三、实际应用场景示例 ##### 场景 1:代码补全 当开发者在编写 RecyclerView 适配器时,选中部分代码后触发 Kimi Code 补全: ```kotlin // 用户选中代码: class MyAdapter(private val dataList: List<String>) : RecyclerView.Adapter<MyAdapter.ViewHolder>() { override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder { // 光标停留在此处,触发 Kimi Code 建议 } } // Kimi Code 返回的补全建议: val view = LayoutInflater.from(parent.context) .inflate(R.layout.item_layout, parent, false) return ViewHolder(view) ``` ##### 场景 2:错误检测和修复 当代码中存在潜在问题时,Kimi Code 可以提供修复建议: ```kotlin // 原始代码(存在内存泄漏风险): class MainActivity : AppCompatActivity() { private val handler = Handler() override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) handler.postDelayed({ // 执行某些操作 }, 5000) } } // Kimi Code 建议: // 建议使用 ViewModel 和 Lifecycle 来管理异步任务,避免内存泄漏 // 或者确保在 onDestroy 中移除所有 callback ``` #### 四、高级功能和优化建议 1. **流式响应处理**:对于较长的代码生成任务,可以使用流式 API 实现实时显示: ```kotlin @Streaming @POST("chat/completions") suspend fun getStreamingCompletion( @Header("Authorization") authorization: String, @Body request: KimiRequest ): Response<ResponseBody> // 处理流式响应 response.body()?.source()?.use { source -> while (!source.exhausted()) { val line = source.readUtf8Line() ?: break if (line.startsWith("data: ")) { val json = line.substring(6) if (json != "[DONE]") { // 解析并显示部分结果 } } } } ``` 2. **上下文感知**:通过分析当前文件的导入语句、类结构和项目配置,提供更精准的代码建议。 3. **缓存机制**:对频繁请求的代码模式实现本地缓存,减少 API 调用次数。 #### 五、注意事项和最佳实践 - **API 调用频率**:注意遵守 Kimi Code API 的调用频率限制,合理安排请求间隔 - **错误处理**:实现完善的网络异常处理和重试机制 - **用户体验**:在等待 API 响应时显示加载状态,避免界面卡顿 - **代码质量**:对 Kimi Code 返回的建议进行必要的代码审查,确保符合项目规范 通过以上完整的集成方案,开发者可以在 Android Studio 中充分利用 Kimi Code 的智能编程能力,显著提升开发效率和质量。这种集成不仅提供了基础的代码补全功能,还能根据具体开发场景提供针对性的优化建议。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值