HarmonyOS鸿蒙Next开发工坊是如何实现插件化的?
HarmonyOS鸿蒙Next开发工坊是如何实现插件化的? 开发样例里中的程序,可以下载后直接运行。是怎么实现的?

更多关于HarmonyOS鸿蒙Next开发工坊是如何实现插件化的?的实战教程也可以访问 https://www.itying.com/category-93-b0.html
厉害了,源码都找到了👍,
按需分发:一个应用程序被打包成多个安装包,安装包包含了所有的应用程序代码和静态资源。用户从应用市场下载的应用只包含基本功能的安装包,当用户需要使用增强功能时,相应安装包将会从服务器下载到设备上。

- 用户下载A应用的基础包。
- 用户使用增强功能。
- 应用通过API下载动态安装包。
- 动态安装包下载完成。
- 通过on接口告知用户下载结果。
Demo实现:
import type { common, StartOptions } from '@kit.AbilityKit';
import { display } from '@kit.ArkUI';
import { BusinessError, emitter } from '@kit.BasicServicesKit';
import { moduleInstallManager } from '@kit.StoreKit';
import Logger from './Logger';
const DOWNLOAD_TIMEOUT_LIMIT: number = 1800;
const TAG: string = '[DynamicInstallManager]';
export class DynamicInstallManager {
private static aVAbilityList: string[] = [
'KnocksharesampleAbility',
'VideocastsampleAbility',
'AudiointeractionsampleAbility',
];
public static getModuleStatus(moduleName: string): moduleInstallManager.InstallStatus {
try {
const result: moduleInstallManager.InstalledModule = moduleInstallManager.getInstalledModule(moduleName);
Logger.info(TAG, `getModuleStatus moduleName: ${result.moduleName}, installStatus: ${result.installStatus}`);
return result.installStatus;
} catch {
Logger.error(TAG, `GetModuleStatus getInstalledModule failed.`);
return moduleInstallManager.InstallStatus.NOT_INSTALLED;
}
}
public static fetchModule(context: common.UIAbilityContext,
moduleName: string): Promise<moduleInstallManager.ModuleInstallSessionState> {
return new Promise((resolve: (value: moduleInstallManager.ModuleInstallSessionState) => void,
reject: (reason?: object) => void) => {
try {
Logger.info(TAG, `fetchModule moduleName: ${moduleName}`);
const myModuleInstallProvider: moduleInstallManager.ModuleInstallProvider =
new moduleInstallManager.ModuleInstallProvider();
const moduleInstallRequest: moduleInstallManager.ModuleInstallRequest =
myModuleInstallProvider.createModuleInstallRequest(context);
moduleInstallRequest.addModule(moduleName);
moduleInstallManager.fetchModules(moduleInstallRequest)
.then((data: moduleInstallManager.ModuleInstallSessionState) => {
Logger.debug(TAG, `fetchModule success, result: ${JSON.stringify(data)}`);
resolve(data);
});
} catch (error) {
const err: BusinessError = error as BusinessError;
Logger.error(TAG, `request installing module failed, error: ${err.code} ${err.message}`);
reject(error);
}
});
}
public static cancelDownloadTask(taskId?: string): void {
try {
const rtnCode: moduleInstallManager.ReturnCode = moduleInstallManager.cancelTask(taskId);
Logger.info(TAG, `Succeeded in getting result: ${rtnCode}`);
} catch (error) {
Logger.error(TAG, `cancelTask error code is ${error.code}, message is ${error.message}`);
}
}
public static subscribeDownloadProgress(): void {
try {
moduleInstallManager.on('moduleInstallStatus', (downloadData: moduleInstallManager.ModuleInstallSessionState) => {
Logger.info(TAG,
`subscribeDownloadProgress downloadsize: ${downloadData.downloadedSize}, totalsize: ${downloadData.totalSize}`);
const eventData: emitter.EventData = {
data: {
'taskStatus': downloadData.taskStatus,
'downloadedSize': downloadData.downloadedSize,
'totalSize': downloadData.totalSize
}
};
emitter.emit(CommonConstants.DYNAMIC_INSTALL_EVENT, eventData);
}, DOWNLOAD_TIMEOUT_LIMIT);
Logger.info(TAG, 'subscribe download progress success');
} catch (error) {
Logger.error(TAG, `subscribeDownloadProgress failed, error: ${error.code}, ${error.message}`);
}
}
public static unsubscribeDownloadProgress(): void {
try {
moduleInstallManager.off('moduleInstallStatus');
Logger.info(TAG, 'unsubscribe download progress success');
} catch (error) {
Logger.error(TAG, `onListening error code is ${error.code}, message is ${error.message}`);
}
}
public static loadModule(context: common.UIAbilityContext, moduleAbility: string): Promise<void> {
return new Promise((resolve: (value: void) => void, reject: (reason?: BusinessError) => void) => {
try {
const isAVAbility: boolean = DynamicInstallManager.aVAbilityList.includes(moduleAbility);
const isSameAbility: boolean = (moduleAbility === AppStorage.get('AVAbilityModule'));
const aVAbilityContext: common.UIAbilityContext =
AppStorage.get<common.UIAbilityContext>('AVAbilityContext') as common.UIAbilityContext;
if (isAVAbility && !isSameAbility && aVAbilityContext) {
aVAbilityContext.terminateSelf();
AppStorage.delete('AVAbilityContext');
}
const option: StartOptions = DynamicInstallManager.setStartAbilityProperty();
context.startAbility({ bundleName: context.abilityInfo.bundleName, abilityName: moduleAbility }, option)
.then(() => {
if (isAVAbility) {
AppStorage.setOrCreate('AVAbilityModule', moduleAbility);
}
Logger.info(TAG, `start ${moduleAbility} success}`);
resolve();
})
.catch((error: BusinessError) => {
Logger.error(TAG,
`start ${moduleAbility} failed, error code is ${error.code}, message is ${error.message}`);
reject(error);
});
} catch (error) {
const err: BusinessError = error as BusinessError;
Logger.error(TAG, `startAbility failed, error code is ${err.code}, message is ${err.message}`);
}
});
}
public static setStartAbilityProperty(): StartOptions {
try {
const uiContext: UIContext = AppStorage.get<UIContext>(StorageKey.UI_CONTEXT) as UIContext;
const displayData = display.getDefaultDisplaySync();
const windowWidth = displayData.availableWidth * CommonConstants.WINDOW_RATIO;
const windowHeight = displayData.availableHeight * CommonConstants.WINDOW_RATIO;
const windowLeft = (displayData.availableWidth - windowWidth) / 2.0;
const windowTop = (displayData.availableHeight - windowHeight) / 2.0;
const option: StartOptions = {
minWindowWidth: Math.min(uiContext.px2vp(windowWidth), CommonConstants.MIN_WINDOW_WIDTH),
minWindowHeight: Math.min(uiContext.px2vp(windowHeight), CommonConstants.MIN_WINDOW_HEIGHT),
windowLeft: windowLeft,
windowTop: windowTop,
windowWidth: windowWidth,
windowHeight: windowHeight,
};
return option;
} catch {
Logger.error(TAG, `SetStartAbilityProperty getDefaultDisplaySync failed.`);
return {};
}
}
}
666
HarmonyOS Next的插件化机制基于ArkTS语言和Stage模型实现。系统通过动态加载HAP(Harmony Ability Package)文件实现插件功能,支持按需加载和独立更新。每个插件作为独立模块运行在沙箱环境中,通过ExtensionAbility机制与主应用通信。系统管理插件的生命周期和资源隔离,确保安全性和稳定性。
HarmonyOS Next的插件化能力主要通过ArkTS的静态共享包(Static Shared Package) 和动态共享包(Dynamic Shared Package) 实现,支持代码和资源的灵活分发与按需加载。
在开发工坊样例中,您下载后能直接运行,是因为样例通常以HAP(Harmony Ability Package) 形式提供,它包含了运行所需的代码、资源和配置文件。具体实现方式如下:
-
静态共享包(Static Shared Package):包含ArkTS代码、C++库和资源文件,在应用构建时直接集成到HAP中。您下载的样例已内置所需依赖,因此无需额外配置即可运行。
-
动态共享包(Dynamic Shared Package):支持在运行时按需加载,包含代码和资源,适用于功能模块的延迟加载或独立更新。
-
工程结构:样例工程通常采用标准的HarmonyOS应用结构,包含
entry(主模块)和可选的feature或library模块。构建后生成HAP,可直接在真机或模拟器上安装运行。 -
工具链支持:DevEco Studio提供完整的开发、编译和调试工具链,确保样例工程能一键编译并打包为可部署的HAP。
因此,您下载的样例本质是一个已配置完备的HarmonyOS应用包(HAP),所有插件化依赖已在构建时处理完毕,实现了开箱即用的体验。


