Community生產力與協作github.com

boboyr/TiecodePluginSkills

結繩(Tiecode/結繩 IDE)外掛開發完整指南。涵蓋外掛 API、program.json 擴展點、.rmx 打包,以及各種功能的實作方式:程式碼補全、檔案樹、執行配置、工程模板、編譯任務、工具鏈、語言高亮、選單、設定頁等。

TiecodePluginSkills 是什麼?

這個技能提供了一份全面的結繩 IDE(QiStudio)外掛開發指南,內容基於對官方 `studio-api-1.0-preview5.jar` 的反編譯以及十多個真實外掛的源碼分析。它詳細說明了如何透過 `program.json` 中的擴展點來註冊新的工程類型、語言、工具鏈和執行配置,並深入講解了外掛入口點 (`AndroidPlugin`)、工程管理器 (`CodeProjectManager`)、語言引擎、編譯任務 (`BaseTask`)、以及運行配置 (`RunConfiguration`) 等核心 API 的使用方式。此外,指南還包含了豐富的社區實作範例,如 Go、Scala、Linux 工程外掛,以及 aar 構建、免安裝運行、libgdx 編輯器等高階用法,是開發、修改或學習結繩外掛開發的必備參考。支援的平台為結繩 IDE (QiStudio),其外掛以 `.rmx` (APK) 格式分發。

相容平台~Claude Code~Codex CLI✓Cursor
npx skills add boboyr/TiecodePluginSkills

Installed? Explore more 生產力與協作 skills: steipete/gemini, steipete/gh-issues, steipete/skill-creator · View all 6 →

在你喜歡的 AI 中提問

開啟一個已預先載入此 Agent Skill 的新對話。

說明文件

結繩外掛開發

面向「結繩 IDE / QiStudio」(宿主包名 com.tiecode.develop)的外掛開發文件。 「結繩 Studio」的官方正式名是 QiStudio(新一代開放工程平台,行動端首款實現 OSGi 標準的應用, 以「微組件 / 外掛」形式擴展工程開發環境)。 內容來源:反編譯 studio-api-1.0-preview5.jar(com.rapid.api.*)+ go / scala / kotlin / linux / aar / libgdx / 免安裝執行 等十多個真實外掛的源碼還原。


官方資料與倉庫(重要)

官方 Gitee 倉庫

倉庫說明
MobileIPE-Plugin-DevManual官方外掛開發教程(QiStudio 微組件)。含 QiStudio核心體系介紹.md、Rapid框架介紹.md、plugin/擴展點介紹.md、plugin/外掛清單配置.md、plugin/註冊你的微組件——外掛.md
TiecodeCompiler-Public結繩編譯器(跨平台版)產物發布倉庫。含 docs/(編譯器使用/語法/封裝/平台集成文件)、headers/tiec/(C API + C++ 封裝頭文件)、prebuilt/(cli + android/windows/linux/ohos/wasm 動態庫)、stdlibs/(安卓/CXX/網頁基本庫)
QiStudio-PluginSamples官方外掛示例工程集(19+ 個示例:依賴注入、編輯器動效/彩虹括號、懸浮窗日誌、Html 項目管理器、網路請求、圖標擴展、Javac9 工具鏈、語言高亮、自定義主題、Application 生命週期、項目組件、各類選單、工具頁、設置頁等)

官方 API jar 名是 qistudio-api-<版本>.jar(本 skill 裡反編譯的 studio-api-1.0-preview5.jar 是其宿主側 SDK)。 QQ 交流群:1016399857。

社區參考實現(GitHub)

本 skill 配套的真實外掛源碼集合(單倉庫多目錄,含 8 個完整可編譯外掛):

https://github.com/boboyr/tiecode-plugin

目錄外掛演示能力
go語言工程插件/go 語言工程(控制台+SDL3)雙模板 + LSP(gopls)補全 + TextMate 高亮 + 工具鏈 + 運行配置 + 文件樹虛擬節點
結繩安卓工程aar構建插件/aar/jar 構建復用宿主编譯鏈 + NameGenerator 中文輸出
結繩免安裝運行插件/免安裝運行器復用宿主任務 + 外掛化加載未安裝 APK
libgdx遊戲編輯器插件/libgdx 可視化編輯器設計器 + 編輯器代碼區選單 + 新建場景類
scala安卓工程插件/Scala 安卓工程完整 sbt 構建鏈 + 「結繩外掛工程」模板 + 構建/調試外掛
結繩Linux工程插件/結繩 Linux-SDL3GCC 工具鏈 + SDL3 + 任務鏈
外部kotlin文件註解插件/外部 Kotlin 文件註解結繩編譯器 API:CompilerPlugin + AnnotationProcessor + Kotlin 補全
BasicLanguages-lang參考/官方基礎語言csml/json/markdown/xml/properties 語言高亮參考

0. 核心概念與整體架構

結繩 是一個模塊化 IDE 宿主,外掛以 .rmx 文件分發。一個 .rmx 本質是一個 APK:AndroidManifest.xml + classes.dex + META-INF/program.json。 宿主通過 program.json 裡的**擴展點(extension point)**聲明來發現外掛能力, 而不是靠 manifest 的 <application> 或四大組件。

0.1 三個關鍵包

包作用
com.rapid.api.*外掛 SDK(本次文件主體)。工程、語言、任務、結構、頁面、UI、網路等
com.rapid.framework.*框架層:VFS(虛擬文件系統)、Service/Data/Event Keys、program/plugin 容器
com.tiecode.compiler.*結繩編譯器(語法樹 / 符號表 / 工具鏈 completer/processor)——宿主側,外掛一般只用其 toolchain 子包

0.2 擴展點(program.json 的 extension 陣列)

META-INF/program.json 的完整結構:

{
  "id": "com.goproject.plugin",
  "name": "go語言工程插件",
  "engine": "plugin",
  "description": "...",
  "versionCode": 4,
  "versionName": "1.3",
  "minSupport": 1,
  "vendor": { "name": "boboyr", "email": "", "url": "#" },
  "extension": [
    { "point": "application", "class": "com.goproject.plugin.MyApplication" },
    { "point": "project.manager", "class": "com.goproject.plugin.project.GoProjectManager" },
    { "point": "project.language", "class": "com.goproject.plugin.lang.GoLanguageFactory",
      "scope": { "unit": "project", "identifiers": "sample.go" } },
    { "point": "domain.menu", "class": "com.goproject.plugin.Gomodmenu" }
  ]
}

minSupport 欄位說明(宿主最低支援版本)

minSupport 是整數,表示外掛要求宿主的結繩最低版本,不同版本取值不同:

結繩版本minSupport說明
結繩 4.614.6 外掛寫 "minSupport": 1
結繩 4.724.7 外掛寫 "minSupport": 2

即:給 4.6 開發外掛時 minSupport 填 1;升級到 4.7(或面向 4.7 的外掛)填 2。 取值與宿主版本號綁定的具體規則以官方為準,開發時按目標宿主版本填寫即可。

已確認的擴展點全集(point 欄位):

擴展點類要實作/繼承作用來源外掛
applicationAndroidPlugin外掛入口,onInit/activate/onUninstallgo/scala/aar/免安裝
project.managerProjectManager(常用 CodeProjectManager)註冊一種工程類型go/scala/linux
project.languageLanguageFactory註冊語言(高亮 + 關聯文件副檔名),可帶 scopego/scala
project.language.engineLanguageEngine註冊語言引擎(補全/診斷等 provider 的容器)結繩控制台外掛
project.toolchainTool 子類(如 SunJdk8Compiler)註冊編譯工具鏈JavaCompiler8
project.componentComponentIntegrator/ComponentFactory打開工程時掛組件(運行配置/首次彈窗/hook)linux/kotlin/aar/免安裝
project.file.creationOptionPSObjectCreationOption文件樹「新建文件」選單項kotlin/libgdx
project.file.openWithEditorPSObjectOpeningOption文件「打開方式」kotlin
project.event.fileUiProjectFileUiEvent文件樹 UI 事件(綁圖標等)kotlin
domain.menuBaseDomainMenuAction/選單 action頂級選單項go
domain.menu.editor.code編輯器代碼區選單libgdx
platform.settingsBuilderSettingsBuilder設置頁新增子頁scala安卓
project.file.creationOption———

注意:scope.identifiers 用來把語言/組件限定到某個工程 typeId(如 sample.go)。 某些擴展點 class 可以是 None(佔位)。


1. 外掛入口:application 擴展點

import com.rapid.framework.program.android.app.AndroidPlugin;
import com.rapid.framework.program.android.DvmPluginDescriptor;
import com.rapid.api.Platform;
import com.rapid.api.framework.project.toolchain.ToolchainService;
import com.rapid.api.framework.project.ProjectServiceKeys;

public class MyApplication extends AndroidPlugin {
    @Override
    public void onInit(DvmPluginDescriptor descriptor) {
        // 註冊自定義編譯工具鏈(示例:go 編譯器)
        ToolchainService service = Platform.getService(ProjectServiceKeys.TOOLCHAIN);
        service.setTool(GoCompileApiKeys.Gocompile, new BaseGoCompiler());
    }
    @Override
    public void activate() {
        // 外掛被激活時執行一次(常放 hook、監聽、裝配編譯外掛)
    }
    @Override
    public void onUninstall() {
        // 卸載清理:結束自己拉起的子進程(如 gopls)、斷開 LSP
    }
}

關鍵 API(com.rapid.api.Platform):

  • Platform.getService(Key<T>) —— 取宿主服務(如 ProjectServiceKeys.TOOLCHAIN)
  • Platform.getProject() —— 當前打開的工程對象
  • Platform.getApplicationContext() —— 宿主 Context

2. 工程類型:project.manager 擴展點

一個外掛通過 ProjectManager 註冊一種「工程類型」(如 go語言工程、結繩安卓工程)。

2.1 管理器骨架

public class GoProjectManager extends CodeProjectManager<GoProject> {
    public final static String TYPE = "go語言工程";       // 顯示名
    public final static String IDENTIFIER = "sample.go"; // typeId,project.json 裡存這個

    public GoProjectManager() {
        super();
        this.fileManager = new GoFileManager();   // 可選:自定義文件管理器(綁圖標等)

        // ① 文件打開方式(按副檔名)
        fileManager.addPSObjectOpeningOption(DefaultOpeningOption.INSTANCE, ".go", ".mod");
        // ② 文件樹節點展開方式(虛擬「外部庫」節點)
        fileManager.addPSObjectExpansionCase(new ExternalLibrariesExpansionCase(), MARKER);
        // ③ 新建文件選單項
        fileManager.addPSObjectCreationOption(new GoFileCreationOption());
        // ④ 語言引擎與語言工廠
        languageManager.registerEngine("go", GoLanguageEngine.getInstance());
        languageManager.registerLanguageFactory(new GoLanguageFactory());
        languageManager.registerOperatorProvider(GoLanguage.ID, new GoOperatorProvider());
        // ⑤ 工程創建模板
        addTemplate(new GoConsoleTemplate());
        addTemplate(new GoSdl3Template());
    }

    @Override public String getIdentifier() { return IDENTIFIER; }

    @Override public TypeDescription getTypeDescription() {
        Drawable d = ContextUtils.getDrawable(AndroidPlugins.getContext(this), R.drawable.golang);
        return new TypeDescription(TYPE, TypeDescription.APPLICATION, d);
    }

    @Override public GoProject newProject() { return new GoProject(); }

    @Override public boolean isProjectDir(File file) { return false; }
}

ProjectManager 接口方法(來自 javap):

String getIdentifier();
TypeDescription getTypeDescription();      // 名稱 + 類型 + 圖標
List<Template<T>> getTemplates();
void addTemplate(Template<T>);
ProjectFileManager<T> getFileManager();
T newProject();
void load(T, LoadingPresentation);
boolean isProjectDir(File);                // 判斷某目錄是否該類型工程
String backup(T); void delete(T);

TypeDescription 的類型常量:APPLICATION / CONSOLE / LIBRARY。


3. 工程對象與流水線裝配:CodeProject.prepare()

工程類型對應一個 Project 子類。prepare() 在打開工程時被宿主調用,此時模板文件已寫出,可據目錄內容裝配任務鏈、運行配置、組件。

public class GoProject extends CodeProject {
    @Override
    public void prepare() {
        if (GoProjectKind.isSdl3(getProjectDir())) {
            Task buildLibmain = new BuildLibmainTask();
            Task publishLib = new PublishLibTask();
            addTask(buildLibmain);
            addTask(publishLib);
            publishLib.dependsOn(buildLibmain);      // 任務依賴
            addRunConfiguration(new GoSdl3RunConfiguration());
        } else {
            addTask(new CompilerGoTask());
            addTask(new RunGoTask());
            addRunConfiguration(new GoStartRunConfig());
            addRunConfiguration(new ElfRunConfig());
        }
    }
    @Override public ProjectVariant getVariant() { return ProjectVariant.DEBUG; }
}

CodeProject(extends BaseProject)關鍵方法:

void prepare();
TaskContainer getTasks();  TaskExecutor getTaskExecutor();
void addTask(Task);  void setTasks(Iterable<Task>);
void addRunConfiguration(RunConfiguration);   // CodeProject 獨有
ProjectVariant getVariant();  void setVariant(ProjectVariant);
Logger getLogger();  void setLogger(Logger);
String getName();
File getProjectDir();  File getChildFile(String);   // 工程相對路徑解析成 File
void recycle();

ProjectVariant 取值:DEBUG / RELEASE / UNDEFINED。

技巧(來自 go 外掛):在 prepare() 裡給工程補寫標記文件(如 External Libraries), 能給已存在的舊工程一次性補上能力,不必重建工程。


4. 工程模板:BaseTemplate

模板決定「新建工程」對話框裡有哪些可選項、創建時寫出哪些文件。

public class GoConsoleTemplate extends BaseTemplate<GoProject> {
    @Override public String getName() { return "控制台工程"; }
    @Override public Drawable getPicture() { return null; }        // 模板預覽圖,可 null
    @Override public String getDefaultProjectName() { return "我的go控制台工程"; }
    @Override public Form getForm() { return new Form(); }         // 可加輸入項

    @Override public void create(GoProject project, Form form,
                                 Project.OnProjectCreateListener listener) {
        try {
            File file = project.getChildFile("src/main.go");
            String html = AssetUtils.readAsset(AndroidPlugins.getContext(this), "sample/main.go");
            html = html.replace("${project_name}", project.getName());
            FileUtils.writeFile(html, file);                        // 寫到工程目錄
            FileUtils.writeFile("module main\ngo 1.26.0", project.getChildFile("src/go.mod"));
            listener.onSuccess();                                    // 成功回調
        } catch (IOException e) {
            listener.onFail("寫出默認文件失敗");                      // 失敗回調
        }
    }
}

Template<T> 接口方法:

String getName();
Drawable getPicture();
String getDefaultProjectName();
Form getForm();          // com.rapid.framework.data.form.Form,可 addInput(new FormInput(...))
void create(T, Form, OnProjectCreateListener);   // OnProjectCreateListener.onSuccess()/onFail(msg)

模板攜帶資源:把模板文件打進 app/src/main/assets/<name>,用 AssetUtils.readAsset / AssetUtils.unZipAssetsFolder(context, zipName, destDir) 讀取和解壓。 (SDL3 工程模板就是用 asset 裡的 gosdl3_template.zip 整個解壓到工程目錄。)


5. 編譯任務與工具鏈:BaseTask + ToolchainService

5.1 任務 BaseTask

public class CompilerGoTask extends BaseTask {
    @Override public void execute() throws TaskInterruptError {
        File output = new File(Platform.getProject().getProjectDir() + "/output");
        if (!output.exists()) output.mkdirs();
        GoCompile a = Platform.getService(ProjectServiceKeys.TOOLCHAIN)
                             .getTool(GoCompileApiKeys.Gocompile);
        if (!a.isInstalled(ctx)) { logger.info("安裝工具鏈..."); a.install(ctx); }
        GoCompileParams p = new GoCompileParams();
        p.inputFiles = FileUtils.getGofile(srcDir);
        p.outputPath = output.getPath();
        p.options = new String[]{"build", "-o"};
        a.compile(p, new CompileOnExecutionCallback());
    }

    // 必須覆寫:默認 BaseTask.prepare 拋 UnsupportedOperationException;
    // 且 logger/variant 字段要在這裡賦值,否則 execute() 裡 logger.info 會 NPE。
    @Override public void prepare(Project project, ProjectVariant variant, Logger logger) {
        this.logger = logger;
        this.variant = variant;
        Os.setenv("GOROOT", goRoot, false);   // 設置環境變量(android.system.Os)
    }

    @Override public String getId() { return "compileWithGo"; }   // 供運行配置 getTaskId() 引用
    @Override public String getName() { return "編譯到目標平台"; }
}

Task 接口(來自 javap):

String getId();  String getName();
void prepare(Project, ProjectVariant, Logger);      // 注意默認拋異常,務必覆寫
void execute() throws TaskInterruptError;
TaskState getState();
void interrupt();
void dependsOn(Task...);  void dependsOn(List<Task>);
Task getDependencyTask(String);  Task getDependencyTaskByName(String);
String getIntermediatePath();  String getIntermediatePath(String);
String getOutputPath();  String getOutputPath(String);
File getGeneratedDir();

踩坑(go 外掛註釋原話):任務裡 logger 不賦值,execute() 裡用 logger.info 會 NPE 直接失敗,工具鏈安裝永不執行。

5.2 工具鏈 Tool + Installable

public interface Tool { /* 內置了 ANDROID_SDK/AAPT/AAPT2/D8/R8/DX/PROGUARD/
                         MANIFEST_MERGER/APK_SIGNER/JAVA_SDK/JAVA_COMPILER 等 Key */ }
public interface Installable {
    boolean isInstalled(Context);
    void install(Context) throws IOException;
}
  • 自定義工具鏈在 application.onInit() 裡用 ToolchainService.setTool(customKey, impl) 註冊。
  • 內置 Android 工具鏈 Key 都在 Tool 接口裡(可直接 Platform.getService(TOOLCHAIN).getTool(Tool.AAPT2))。
  • 復用宿主编譯鏈(aar 外掛 / 免安裝外掛做法):不自己打包編譯器,而是 getDependencyTaskByName("compileWithTiecodec") 之類拿到宿主任務掛依賴,或直接復用 getTaskId()。

6. 運行配置:RunConfiguration / TaskRunConfiguration

給工程的「運行」選單添加可執行項。最常用 TaskRunConfiguration:指定一個任務 id, 任務執行成功後回調 onResult。

public class GoStartRunConfig extends TaskRunConfiguration {
    public Project getProject() { return Platform.getProject(); }
    public String getTaskId() { return "RunWithGo"; }          // 關聯的任務 id
    public ProjectVariant getVariant() { return ProjectVariant.DEBUG; }

    @Override public void onTaskSuccess(TaskResult result) {
        // 任務成功後:執行 APK / ELF...
    }
}

RunConfiguration 接口:

String getName();  Drawable getIcon();
String getDescription();
ProjectVariant getVariant();
boolean canRun();
void run();
boolean canStop();  void stop();

常見場景:

  • TaskRunConfiguration:直接關聯一個任務,任務執行後自動回調 onTaskSuccess。
  • 自定義 RunConfiguration:實現 run() 中自己調用 Platform.getProject().getTaskExecutor().execute(taskChain)。

7. 文件樹高級擴展

7.1 虛擬文件節點:ExpansionCase / PSObjectExpansionCase

文件樹的「外部庫」節點:

public class ExternalLibrariesExpansionCase extends PSObjectExpansionCase {
    @Override
    public List<PSObject> getChildren(PSObject parent, ExpansionCaseExpander expander) {
        List<PSObject> nodes = new ArrayList<>();
        // 遍歷 GOROOT/src 裡 go 目錄...
        nodes.add(goPsObj);
        return nodes;
    }
    @Override public boolean hideArrow() { return false; }
    @Override public String getText() { return "外部庫"; }
    @Override public Drawable getIcon() { return icon; }
}

7.2 新建文件嚮導:PSObjectCreationOption

public class GoFileCreationOption implements PSObjectCreationOption {
    @Override public String getText() { return "Go 文件"; }
    @Override public Drawable getIcon() { return icon; }
    @Override public String getExtensionName() { return ".go"; }

    @Override
    public void onClick(PSObjectCreationDialog dialog, PSObject parent,
                        Runnable onRefresh) {
        // 顯示對話框或直接創建
    }
}

7.3 文件打開方式:PSObjectOpeningOption

public class GoModOpeningOption implements PSObjectOpeningOption {
    @Override public String getText() { return "以 go.mod 編輯器打開"; }
    @Override public void onClick(PSObject object, Project project) {
        // 打開自定義 UI
    }
}

8. 語言支持:高亮 + 補全 + 引擎

8.1 語言工廠 LanguageFactory

public class GoLanguageFactory implements LanguageFactory {
    @Override public Language create() { return GoLanguage.INSTANCE; }
}

8.2 語言對象 Language

public class GoLanguage extends Language {
    public final static String ID = "go";
    public final static GoLanguage INSTANCE = new GoLanguage();

    @Override public String getId() { return ID; }
    @Override public List<String> getFileExtensions() {
        return Arrays.asList(".go", ".mod");
    }
    @Override public TextMateProvider getTextMateProvider() {
        return new GoTmbundleProvider();   // TextMate 高亮
    }
    @Override public OperatorProvider getOperatorProvider() { return operatorProvider; }
    @Override public LanguageConfiguration getLanguageConfiguration() { return null; }
}

8.3 語言引擎 LanguageEngine(代碼補全 / 診斷)

public class GoLanguageEngine extends LanguageEngine {
    // 生命週期:start (onProjectOpened) -> suspend -> (activates when file opened)
    // -> complete/diagnose -> stop (user closes project)

    @Override public void start(Project project, Language language) {
        // 啟動 gopls 進程
    }
    @Override public Completion getCompletion(Document document, int offset) {
        // 請求 gopls 補全
    }
    @Override public List<Diagnostic> getDiagnostics(Document document) {
        // 診斷
    }
    @Override public void stop() {
        // 殺死 gopls 進程
    }
}

LanguageEngine 完整接口(javap):

void start(Project, Language);
void suspend();
Completion getCompletion(Document, int, CompletionConfiguration);
List<Diagnostic> getDiagnostics(Document);
List<NavItem> getNavigationItems(Document);
HoverResult getHoverHelp(Document, int);
List<UsageResult> getUsageResult(Document, int);
void stop();

TextMate 高亮:外掛把 .tmBundle 或 .tmLanguage 文件放在 assets/tmbundles/<語言名>/ 下, TextMateProvider 讀取並返回。


9. 編譯器 API:CompilerPlugin + AnnotationProcessor

外部 Kotlin 文件註解外掛 演示了此 API: 宿主編譯過程中調用外掛的 CompilerPlugin 處理語法樹節點(AST)。

@CompilerPlugin(id = "kotlin.annotation")
public class KotlinAnnotationPlugin extends CompilerPlugin {
    @Override
    public void process(@NotNull KtFile ktFile, @NotNull CompilerPluginContext context) {
        // 遍歷 AST 節點...
        // context.reportError(KtDiagnostic(...));
    }
}

表現:

  • 外掛 jar 的 META-INF/services/com.tiecode.compiler.CompilerPlugin 裡註冊類名。
  • 宿主在編譯工程時自動加載並調用 process()。
  • 可報告診斷、修改 AST(實驗性)。

10. 選單與工具索引

10.1 頂級選單 domain.menu

public class Gomodmenu extends BaseDomainMenuAction {
    @Override public String getText() { return "Go 模塊"; }
    @Override public void onClick() {
        // 顯示對話框或執行操作
    }
}

10.2 編輯器代碼區選單 domain.menu.editor.code

// 在 libgdx 外掛裡:
// 選單項目目前支持 editor.code,文檔略

10.3 腳本索引 IndexActivity + ScriptIndexProvider

public class MyIndexProvider extends ScriptIndexProvider {
    // 工具頁面(索引)入口
}

11. 設置頁:platform.settingsBuilder 擴展點

public class ScalaSettingsBuilder implements SettingsBuilder {
    @Override public void addFunction(Context context, SettingsFunction function) {
        function.addSetting(new SettingItem("sbt 路徑", "key_sbt_path", ""));
    }
}

12. .rmx 打包與發布

.rmx = 普通 APK,但宿主只識別符合以下條件的 APK:

  1. AndroidManifest.xml 存在(可空)
  2. META-INF/program.json 存在且格式正確
  3. 有 classes.dex

打包方式(以 Android Studio / Gradle 為例):

  • 用 com.android.application 插件構建 APK。
  • program.json 放 src/main/assets/META-INF/ 或手動複製到 APK 的 META-INF/。
  • 安裝:宿主(QiStudio)的「外掛管理」頁面選擇 .rmx 文件安裝。

常見問題(FAQ)

Q: 執行配置點擊無反應?

A: 確認 TaskRunConfiguration.getTaskId() 與 BaseTask.getId() 匹配,且任務已在 prepare() 中添加。

Q: 外掛安裝後未生效?

A: 檢查宿主版本是否與 minSupport 匹配;檢查 program.json 的 extension 陣列中類名是否完整(含包名)。

Q: TextMate 高亮不工作?

A: 確認 .tmLanguage 文件格式為 Plist XML;確認 TextMateProvider 返回正確的 Grammar。

Q: 任務裡 logger 報 NPE?

A: 見 5.1 節,務必在 prepare() 中賦值 this.logger = logger。


附錄:相關 API 速查

Platform 靜態方法

方法返回說明
getService(Key)T獲取宿主服務
getProject()Project當前工程(可能 null)
getApplicationContext()Context宿主 Context
getLogger()Logger宿主 Logger
getPlatformVersion()int宿主版本號

ProjectServiceKeys

常量服務類型說明
TOOLCHAINToolchainService工具鏈管理
LANGUAGE_MANAGERLanguageManager語言管理
PROJECT_MANAGERProjectManagerService工程管理器
FILE_MANAGERProjectFileManager文件管理器

Tool 內置 Key 一覽

Key對應工具
Tool.ANDROID_SDKAndroid SDK 路徑
Tool.AAPT2aapt2
Tool.D8D8 dexer
Tool.JAVA_COMPILERjavac
Tool.APK_SIGNERapksigner

全部 Key 見 com.rapid.api.framework.project.toolchain.Tool 接口常量。


本文件基於 com.rapid.api.* 的反編譯結果 + 真實外掛源碼整理,如有疏漏歡迎 PR。

相關技能