§ PC外壳-插件开发指南
§ 介绍
Fox3.0 PC外壳是基于Electron的跨平台的外壳(widnows、linux、mac),开发语言是typescript。
§ 目录结构说明
基础插件
pc/src/main/plugins-base 基础插件目录 pc/src/main/plugins-base/registry.ts 基础插件注册表
自定义插件
pc/src/main/plugins 自定义插件目录 pc/src/main/plugins/registry.ts 自定义插件注册表
native扩展
pc/src/main/natives 自定义native扩展目录 pc/src/main/natives/registry.ts 自定义native扩展注册表
device扩展
pc/src/main/device 自定义device扩展目录
自定义插件
pc/src/main/plugins 自定义插件目录 pc/src/main/plugins/registry.ts 自定义插件注册表
§ 自定插件开发(执行插件)
下面通过splash插件说明,fox shell的插件开发过程
步骤一
在plugins目录下建立如果结构 splash/index.ts, 并创建Splash类
步骤二
继承Plugin实现execute函数,并实现插件的必要函数install
import { App, Plugin, PluginType, CallbackContext, eventProxy} from '../../assets/libs/fox-libs'
import { messageHandlerOptions } from '../../global-config'
/**
* splash plugin
*/
export default class SplashPlugin extends Plugin{
/**
* 安装插件
* @param Fox
* @param args
*/
static install(app: App, options?: object) {
app.mixin('splash', new SplashPlugin(), PluginType.EXEC)
}
/**
* 执行
* @param action
* @param args
* @param callbackContext
*/
execute(action:string, args:any[], callbackContext:CallbackContext):void{
if(action == 'close'){
eventProxy.emit(messageHandlerOptions.mainWinMessageHandler,'closeSplash')
}
callbackContext.success()
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
install为安装函数,必须在为statis,并且在该函数中调用app.mixin('splash', new SplashPlugin(), PluginType.EXEC)注册插件,PluginType有EXEC和ALL两种类型,EXEC只需要实现execute函数,而ALL需要额外实现onStart和onStop函数(APP启动与关闭时调用)
execute 为执行函数,为web提供native能力 methods
方法:Plugin.install 说明:插件安装
参数 说明 类型 app Fox APP BaseAPP options 参数 any 方法:app.mixin 说明:注册插件
参数 说明 类型 serviceName string 插件服务名 pluginType 插件类型 PluginType PluginType.EXEC 执行插件,只需要实现execute函数 PluginType.ALL 启动后执行插件,需要实现execute、onStart、onStop函数 方法:plugin.execute 说明:注册插件
参数 说明 类型 serviceName string 插件服务名 action 动作 string args 参数 any[] callbackContext 回调上下文 CallbackContext callbackContext.success(data?:any) 成功回调 callbackContext.error(data?:any) 失败回调 callbackContext.process(data?:any) 进度回调,可以回调多次 步骤三
在插件目录下的registry.ts引用插件
//---------- 插件列表 -----------------
import PreferenceProxy from './preference/index'
import VersionPlugin from './version/index'
import FilePlugin from './file/index'
import CommPlugin from './comm/index'
import SessionPlugin from './session/index'
import SplashPlugin from './splash/index'
import NavigatePlugin from './navigate/index'
import ShareBusProxy from './bus/index'
//导出列表
export default [
VersionPlugin,FilePlugin,PreferenceProxy,
CommPlugin,SessionPlugin,SplashPlugin,NavigatePlugin,
ShareBusProxy
]
2
3
4
5
6
7
8
9
10
11
12
13
14
15
§ 自定插件开发(启动插件)
下面通过version插件,来说明如果开发具备启动周期的插件
步骤一
在plugins目录下建立目录结构 version/index.ts, 并创建VersioPlugin
步骤二
实现execute、onStart和onStop函数
/**
* version插件
*/
class VersionPlugin extends Plugin {
/**
* 安装插件
* @param app
* @param options
*/
static install(app: App, options?: object) {
//参数说明: 插件名,插件实例,插件类型,插件优先级(默认不设置,缺省值为50,priority越小优先级越高)
app.mixin('versionProxy', new VersionPlugin(), PluginType.ALL, 1)
}
/**
* 启动
* @param context 进度上下文
*/
public async onStart(context: ProgressContext): Promise<void> {
context.work(0, '版本初始化')
try {
//版本更新
await this.update(context)
} catch (error) {
console.error(error.message, error)
context.work(100, '版本初始化失败')
context.done(ProgressStatus.FAIL)
}
}
/**
* 销毁状态
*/
public async onStop(): Promise<void> {
}
/**
* 执行
* @param action
* @param args
* @param callbackContext
*/
public execute(action: string, args: any[], callbackContext: CallbackContext): void {
//获取app name
let appName = callbackContext.appName
//获取app type
let appType = callbackContext.appType
if (action == 'checkVersion') {
this.checkVersion(appName, appType, callbackContext)
} else if (action == 'updateVersion') {
this.updateVersion(appName, appType, callbackContext)
} else if (action == 'getVersion') {
this.getVersion(appName, appType, callbackContext)
} else if (action == 'setVersionScale') {
this.setVersionScale(args[0] as string, callbackContext)
} else if (action == 'getVersionScale') {
this.getVersionScale(callbackContext)
} else {
let data = ResultEncoder.encode(ResultEncoder.ERROR, '', 'unknown action')
callbackContext.error(data)
}
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
export default VersionPlugin install为安装函数,必须在为statis,并且在该函数中调用app.mixin('splash', new SplashPlugin(), PluginType.EXEC)注册插件,PluginType有EXEC和ALL两种类型,EXEC只需要实现execute函数,而ALL需要额外实现onStart和onStop函数(APP启动与关闭时调用)
execute 为执行函数,为web提供native能力 methods
方法:Plugin.install 说明:插件安装
参数 说明 类型 app Fox APP BaseAPP options 参数 any 方法:app.mixin 说明:注册插件
参数 说明 类型 serviceName string 插件服务名 pluginType 插件类型 PluginType PluginType.EXEC 执行插件,只需要实现execute函数 PluginType.ALL 启动后执行插件,需要实现execute、onStart、onStop函数 方法:plugin.execute 说明:注册插件
参数 说明 类型 serviceName string 插件服务名 action 动作 string args 参数 any[] callbackContext 回调上下文 CallbackContext callbackContext.success(data?:any) 成功回调 callbackContext.error(data?:any) 失败回调 callbackContext.process(data?:any) 进度回调,可以回调多次 方法 plugin.onStart 说明:APP启动时候调用
参数 说明 类型 context ProgressContext 进度上下文 context.success() 成功回调 context.error() 失败回调 方法 plugin.onStop 说明:APP关闭时候调用
步骤三
在插件目录下的registry.ts引用插件
//---------- 插件列表 -----------------
import PreferenceProxy from './preference/index'
import VersionPlugin from './version/index'
import FilePlugin from './file/index'
import CommPlugin from './comm/index'
import SessionPlugin from './session/index'
import SplashPlugin from './splash/index'
import NavigatePlugin from './navigate/index'
import ShareBusProxy from './bus/index'
//导出列表
export default [
VersionPlugin,FilePlugin,PreferenceProxy,
CommPlugin,SessionPlugin,SplashPlugin,NavigatePlugin,
ShareBusProxy
]
2
3
4
5
6
7
8
9
10
11
12
13
14
15
§ 自定插件开发(Proxy插件)
Proxy插件是Plugin插件的简化类型,只需定义和action一致的method,就可以为web提供native能力,下面同样通过Splash插件的例子说明两者的差异吧
Plugin实现方式
/**
* splash plugin
*/
export default class SplashPlugin extends Plugin{
/**
* 安装插件
* @param Fox
* @param args
*/
static install(app: App, options?: object) {
app.mixin('splash', new SplashPlugin(), PluginType.EXEC)
}
/**
* 执行
* @param action
* @param args
* @param callbackContext
*/
execute(action:string, args:any[], callbackContext:CallbackContext):void{
if(action == 'close'){
eventProxy.emit(messageHandlerOptions.mainWinMessageHandler,'closeSplash')
}
callbackContext.success()
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
Proxy实现方式
/**
* splash plugin
*/
export default class SplashPlugin extends Proxy{
/**
* 安装插件
* @param Fox
* @param args
*/
static install(app: App, options?: object) {
app.mixin('splash', new SplashPlugin(), PluginType.EXEC)
}
/**
* 执行
* @param cite
*/
close(cite: Cite):void{ eventProxy.emit(messageHandlerOptions.mainWinMessageHandler,'closeSplash')
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
Proxy中的close方法对应着Plugin中的action,而如果该方法有参数同样对应中Plugin中的args Proxy中的action函数,总会多一个Cite参数,可以提供调用信息
declare class Cite {
/**
* app name
*/
readonly appName: string;
/**
* app type
*/
readonly appType: AppType;
/**
* http requester
*/
readonly httpRequester: HttpRequester;
/**
* 文件访问权
*/
readonly fileAccessor: FileAccessor;
/**
* 是否为异步
*/
readonly async: boolean;
/**
* 进度处理
*/
readonly process: {
(data: any): void;
};
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
§ Native扩展开发
Native扩展是Plugin的一个简化版本,以便于更加简单的提供Native能力,以开发步骤为
步骤一
在natives目录下建立目录结构 system/index.ts, 并创建VersioPlugin
步骤二
继承Native,并实现call函数,如下
class PlatformNative extends Native {
/**
* 获取native支持的action
*/
public getActionNames(): string[] {
return ['getAppVersionName', 'getAppVersionCode', 'shutdown', 'restart']
}
/**
* call
* @param action 动作
* @param params 参数
* @param cite 引用
*/
public async call(action: string, params: string, cite: Cite): Promise<NativeResult> {
if (action == 'getAppVersionName') {
let data = encodeResult(ResultCode.SUCCESS, platform.version)
return data
} else if (action == 'getAppVersionCode') {
let data = encodeResult(ResultCode.SUCCESS, platform.version)
return data
} else if (action == 'shutdown') {
eventProxy.emit(messageHandlerOptions.mainWinMessageHandler, 'exit')
let data = encodeResult(ResultCode.SUCCESS, '')
return data
} else if (action == 'restart') {
eventProxy.emit(messageHandlerOptions.mainWinMessageHandler, 'restart')
let data = encodeResult(ResultCode.SUCCESS, '')
return data
} else {
let data = encodeResult(ResultCode.ERROR, 'unknown action')
return data
}
}
}
let platformNative = new PlatformNative()
export default platformNative
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
步骤三
在natives/registry.ts中注册Native扩展
import { Native } from '../../main/assets/libs/fox-libs'
/*
* @version: 1.0
* @Author: 江成
* @Date: 2021-05-07 16:10:48
*/
//-------- 导入native对象 ------------
import platformNative from './system/index'
//---------- native列表 -----------------
//导出列表
let nativeList:Native[] = [ platformNative ]
export default nativeList
2
3
4
5
6
7
8
9
10
11
12
13
methods
方法:call 说明:插件安装
参数 说明 类型 action 动作 string params 参数 sring cite 引用 Cite Cite参数,可以提供调用信息
declare class Cite {
/**
* app name
*/
readonly appName: string;
/**
* app type
*/
readonly appType: AppType;
/**
* http requester
*/
readonly httpRequester: HttpRequester;
/**
* 文件访问权
*/
readonly fileAccessor: FileAccessor;
/**
* 是否为异步
*/
readonly async: boolean;
/**
* 进度处理
*/
readonly process: {
(data: any): void;
};
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
§ Device扩展开发
对接外设服务