§ 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()
    }

}
1
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
]
1
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)
        }
    }
}
1
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
]
1
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()
    }
}
1
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')
    }
}
1
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;
    };
}
1
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
1
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
1
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;
    };
}
1
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扩展开发

对接外设服务

最后更新于: 4/18/2022, 5:22:49 PM