AI prompts
base on 腾讯(Tencent)Shadow的二次封装项目,开袋即食版。 # BlackShadow
接入shadow需要大量的二次开发工作,其实一般小型项目其实并不想关心太多的逻辑和管理,只想开袋即食,奈何Shadow也并没有提供这方面的能力,所有开发者接入都需要二次开发才可以使用,所以花了点时间在Shadow的基础上包装了一层,几乎不需要任何二次开发,即可通过几个简单的接口使用与管理Shadow,屏蔽了Shadow所有的技术细节。
## 相关
博客文章:
[腾讯Shadow浅析及应用及BlackShadow](https://blog.niunaijun.top/index.php/archives/blackshadow.html)
Tencent Shadow:
https://github.com/Tencent/Shadow
## 基于Shadow的技术方案
BlackShadow使用的是非动态方案
- 支持同时最多10个插件运行,分别都是各自单独的进程。
- install与launch都有boolean返回值,可反馈出插件是否安装/启动成功。
- 支持插件内打开/查询/卸载/安装,其他插件。
## 未实现
- Activity栈的管理,目前统一打开standard Activity
- 多个插件共用一个进程
## 如何使用?
建议直接clone本项目查看项目结构。
### 1. clone Shadow
nnjun仓库与Tencent仓库没有技术性差异。
```
git clone https://github.com/Tencent/Shadow.git
或者
git clone https://github.com/nnjun/Shadow.git (建议使用这个)
```
### 2. 编译本地仓库
拉下仓库后,进入Shadow目录,将Shadow发布到本地maven仓库
```
./gradlew publish
```
### 3. 修改项目Shadow版本
修改Shadow版本为本地的版本,如果是拉取nnjun仓库则不需要改
https://github.com/CodingGay/BlackShadow/blob/main/build.gradle#L3
## BlackShadow使用方法
在Application#attachBaseContext中初始化
```java
@Override
protected void attachBaseContext(Context base) {
super.attachBaseContext(base);
BlackShadow.get().init(this);
}
```
安装与启动
```java
InstallResult installResult = BlackShadow.get().installPlugin("plugin-key", new File(pluginAPk));
if (installResult.isSuccess()) {
Intent intent = new Intent();
intent.xxxxxxxxxxxxx
BlackShadow.get().launchPlugin("plugin-key", intent);
}
```
其余接口
```java
// 仅启动application
public boolean callApplication(String pluginKey)
// 获取所有已安装的plugin
public List<InstalledPlugin> getInstalledPlugins()
// 获取某个已安装的plugin
public InstalledPlugin getInstalledPlugin(String pluginKey);
// 卸载某个plugin
public void uninstallPlugin(String pluginKey)
// 停止某个plugin
public void stopPlugin(String pluginKey)
// 停止所有plugin
public void stopAllPlugin()
// 获取正在运行的plugin
public List<RunningPlugin> getRunningPlugins()
```
## 插件包名与宿主包名不相同的需求
由于Shadow内核要求,plugin与宿主的包名必须一致,否则会出现问题,然而我方产品可能会存在不同的渠道包不同的包名,但是插件没有必要分开很多份,所以BlackShadow是支持插件与宿主不同的包名,处理的方法是在install时如果不一样,BlackShaodw会自动将插件的包名改成与宿主相同,不需要额外开发,直接进行install即可,BlackShadow会自动处理该问题。
假如你也有这个需求,则需要自行修改Shaodw内核,或者直接使用nnjun仓库
https://github.com/nnjun/Shadow/commit/32636d2759bae1d1f241c8f43ffb769ff2ce5ef5
### 不是修改了包名了吗?为什么还需要修改内核?
因为Shadow的包名基准是由Shadow编译时生成的com.tencent.shadow.core.manifest_parser.PluginManifest文件来确定,BlackShadow只会修改Manifest中的包名,并不会修改PluginManifest.class内的硬编码包名,所以需要修改编译插件,否则无法运行。
如果你没有以上的场景,那么请无视上面这一段内容,直接使用即可。
", Assign "at most 3 tags" to the expected json: {"id":"8678","tags":[]} "only from the tags list I provide: [{"id":77,"name":"3d"},{"id":89,"name":"agent"},{"id":17,"name":"ai"},{"id":54,"name":"algorithm"},{"id":24,"name":"api"},{"id":44,"name":"authentication"},{"id":3,"name":"aws"},{"id":27,"name":"backend"},{"id":60,"name":"benchmark"},{"id":72,"name":"best-practices"},{"id":39,"name":"bitcoin"},{"id":37,"name":"blockchain"},{"id":1,"name":"blog"},{"id":45,"name":"bundler"},{"id":58,"name":"cache"},{"id":21,"name":"chat"},{"id":49,"name":"cicd"},{"id":4,"name":"cli"},{"id":64,"name":"cloud-native"},{"id":48,"name":"cms"},{"id":61,"name":"compiler"},{"id":68,"name":"containerization"},{"id":92,"name":"crm"},{"id":34,"name":"data"},{"id":47,"name":"database"},{"id":8,"name":"declarative-gui "},{"id":9,"name":"deploy-tool"},{"id":53,"name":"desktop-app"},{"id":6,"name":"dev-exp-lib"},{"id":59,"name":"dev-tool"},{"id":13,"name":"ecommerce"},{"id":26,"name":"editor"},{"id":66,"name":"emulator"},{"id":62,"name":"filesystem"},{"id":80,"name":"finance"},{"id":15,"name":"firmware"},{"id":73,"name":"for-fun"},{"id":2,"name":"framework"},{"id":11,"name":"frontend"},{"id":22,"name":"game"},{"id":81,"name":"game-engine "},{"id":23,"name":"graphql"},{"id":84,"name":"gui"},{"id":91,"name":"http"},{"id":5,"name":"http-client"},{"id":51,"name":"iac"},{"id":30,"name":"ide"},{"id":78,"name":"iot"},{"id":40,"name":"json"},{"id":83,"name":"julian"},{"id":38,"name":"k8s"},{"id":31,"name":"language"},{"id":10,"name":"learning-resource"},{"id":33,"name":"lib"},{"id":41,"name":"linter"},{"id":28,"name":"lms"},{"id":16,"name":"logging"},{"id":76,"name":"low-code"},{"id":90,"name":"message-queue"},{"id":42,"name":"mobile-app"},{"id":18,"name":"monitoring"},{"id":36,"name":"networking"},{"id":7,"name":"node-version"},{"id":55,"name":"nosql"},{"id":57,"name":"observability"},{"id":46,"name":"orm"},{"id":52,"name":"os"},{"id":14,"name":"parser"},{"id":74,"name":"react"},{"id":82,"name":"real-time"},{"id":56,"name":"robot"},{"id":65,"name":"runtime"},{"id":32,"name":"sdk"},{"id":71,"name":"search"},{"id":63,"name":"secrets"},{"id":25,"name":"security"},{"id":85,"name":"server"},{"id":86,"name":"serverless"},{"id":70,"name":"storage"},{"id":75,"name":"system-design"},{"id":79,"name":"terminal"},{"id":29,"name":"testing"},{"id":12,"name":"ui"},{"id":50,"name":"ux"},{"id":88,"name":"video"},{"id":20,"name":"web-app"},{"id":35,"name":"web-server"},{"id":43,"name":"webassembly"},{"id":69,"name":"workflow"},{"id":87,"name":"yaml"}]" returns me the "expected json"