1-解决首次启动释放资源文件的问题

This commit is contained in:
JackLee 2026-04-08 21:58:55 +08:00
parent a64bcda4ab
commit efff16f328
5 changed files with 182 additions and 30 deletions

View File

@ -271,21 +271,30 @@ static std::string value2String(napi_env env, napi_value value) {
napi_get_value_string_utf8(env, value, &valueString[0], stringSize + 1, &stringSize);
return valueString;
}
struct AxisEvent {
int32_t axisAction;
float displayX;
float displayY;
std::map<int32_t, double> axisValues;
int64_t actionTime { -1 };
int32_t sourceType;
int32_t axisEventType { -1 };
};
void DispatchTouchEventCB(OH_NativeXComponent* component, void* window)
{
// [StartExclude plugin_dispatch_touch_event]
OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "Callback", "DispatchTouchEventCB");
int32_t ret;
char idStr[OH_XCOMPONENT_ID_LEN_MAX + 1] = {};
uint64_t idSize = OH_XCOMPONENT_ID_LEN_MAX + 1;
ret = OH_NativeXComponent_GetXComponentId(component, idStr, &idSize);
if (ret != OH_NATIVEXCOMPONENT_RESULT_SUCCESS) {
return;
}
std::string id(idStr);
// [EndExclude plugin_dispatch_touch_event]
auto *pluginManger = NativeMgr::GetInstance();
pluginManger->DispatchTouchEvent(component, window);
}
// XComponent回调事件
NativeMgr::NativeMgr() {
xSurfaceTouchEventCallBack.OnSurfaceCreated = OnSurfaceCreatedCB;
xSurfaceTouchEventCallBack.OnSurfaceChanged = OnSurfaceChangedCB;
xSurfaceTouchEventCallBack.OnSurfaceDestroyed = OnSurfaceDestroyedCB;
xSurfaceTouchEventCallBack.DispatchTouchEvent=DispatchTouchEventCB;
xMouseEventCallBack.DispatchMouseEvent= OnMouseEventCB;
}
// 创建节点组件
@ -445,6 +454,45 @@ napi_value NativeMgr::initNativeNode(napi_env env, napi_callback_info info) {
return nullptr;
}
void NativeMgr::DispatchTouchEvent(OH_NativeXComponent* component, void* window)
{
int32_t ret = OH_NativeXComponent_GetTouchEvent(component, window, &touchEvent_);
if (ret == OH_NATIVEXCOMPONENT_RESULT_SUCCESS) {
float tiltX = 2.2;
float tiltY = 2.2;
OH_NativeXComponent_TouchPointToolType toolType =
OH_NativeXComponent_TouchPointToolType::OH_NATIVEXCOMPONENT_TOOL_TYPE_LENS;
OH_NativeXComponent_GetTouchPointToolType(component, 0, &toolType);
OH_NativeXComponent_GetTouchPointTiltX(component, 0, &tiltX);
OH_NativeXComponent_GetTouchPointTiltY(component, 0, &tiltY);
OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "XComponent_Native",
"Touch Info : x=%{public}f, y=%{public}f screenx=%{public}f, screeny=%{public}f,"
"type=%{public}d, force=%{public}f, tiltX=%{public}f, tiltY=%{public}f, toolType=%{public}d",
touchEvent_.x, touchEvent_.y, touchEvent_.screenX,
touchEvent_.screenY, touchEvent_.type, touchEvent_.force, tiltX, tiltY, toolType);
if (touchEvent_.type == OH_NativeXComponent_TouchEventType::OH_NATIVEXCOMPONENT_UP) {
}
} else {
OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "XComponent_Native", "touch fail");
}
int32_t size = 0;
OH_NativeXComponent_HistoricalPoint *points = nullptr;
if (OH_NativeXComponent_GetHistoricalPoints(component, window, &size, &points) ==
OH_NATIVEXCOMPONENT_RESULT_SUCCESS) {
OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "XComponent_Native", "HistoricalPoints size=%{public}d",
size);
for (auto i = 0; i < size; i++) {
auto point = points[i];
OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "XComponent_Native",
"HistoricalPoint %{public}d Info : id=%{public}d, x=%{public}f, y=%{public}f, "
"type=%{public}d, timeStamp=%{public}lld, sourceTool=%{public}d",
i, point.id, point.x, point.y, point.type, point.timeStamp, point.sourceTool);
}
}
}
//设置期望帧率
napi_value NativeMgr::SetFrameRate(napi_env env, napi_callback_info info) {
size_t argc = 4;

View File

@ -2,7 +2,7 @@ import { AbilityConstant, ConfigurationConstant, UIAbility, Want } from '@kit.Ab
import { hilog } from '@kit.PerformanceAnalysisKit';
import { window, display, AppStorageV2 } from '@kit.ArkUI';
import { IBestInit } from "@ibestservices/ibest-ui-v2"
import {ExtractDir,HilogSadboxFontDirFile} from "../pages/ExtractDir/ExtractDir"
import {ExtractDir,CheckExistDir,HilogSadboxFontDirFile} from "../pages/ExtractDir/ExtractDir"
import {MainWindowStageInfo,InitGlobalDisplayWindowInfo,mwInfo}from '../pages/DispWinInfo/DispWinInfo'
const DOMAIN = 0x0000;
@ -10,7 +10,29 @@ export default class EntryAbility extends UIAbility {
private mainWindow: window.Window | undefined;
onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void {
let sbFontsDir=this.context?.filesDir + '/fonts/';
let sbExampleDir=this.context?.filesDir + '/example/';
try {
if(!CheckExistDir(this.context,sbFontsDir)||!CheckExistDir(this.context,sbExampleDir)){
console.info(`first run app check dir exist`);
console.info(`extract dir file to sandbox dir`);
const fontsCopied = ExtractDir(this.context, 'fonts');
const exampleCopied = ExtractDir(this.context, 'example');
console.info(`restart app`);
if(fontsCopied&&exampleCopied){
let wantInfo: Want = {
deviceId: '',
bundleName: 'com.example.opencax',
abilityName: 'EntryAbility',
};
this.context.startAbility(wantInfo).then(() => {
this.context.terminateSelf();
})
}
}else{
HilogSadboxFontDirFile(this.context,'fonts');
HilogSadboxFontDirFile(this.context,'example');
}
this.context.getApplicationContext().setColorMode(ConfigurationConstant.ColorMode.COLOR_MODE_NOT_SET);
} catch (err) {
hilog.error(DOMAIN, 'testTag', 'Failed to set colorMode. Cause: %{public}s', JSON.stringify(err));
@ -22,12 +44,9 @@ export default class EntryAbility extends UIAbility {
hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onDestroy');
}
async onWindowStageCreate(windowStage: window.WindowStage): Promise<void> {
onWindowStageCreate(windowStage: window.WindowStage): void {
//InitFont->Copy Res/resfile/font to sandbox
if(ExtractDir(this.context,'fonts')&&ExtractDir(this.context,'example')){
HilogSadboxFontDirFile(this.context,'fonts');
HilogSadboxFontDirFile(this.context,'example');
}
InitGlobalDisplayWindowInfo(windowStage);
//Get Main Window
windowStage.getMainWindow((err, data) => {

View File

@ -1,15 +1,75 @@
import { common } from '@kit.AbilityKit';
import { picker } from '@kit.CoreFileKit';
import type { BusinessError } from '@kit.BasicServicesKit';
@Entry
@ComponentV2
export struct SWNewFile {
@Local message: string = '';
build() {
Column({ space: 5 }) {
Row(){
Text('保存目录:').width('10%')
TextInput().width('80%')
Button('选择目录').width('10%')
Button('选择目录')
.width('10%')
.backgroundColor($r('sys.color.background_secondary'))
.height(40)
.fontColor($r('sys.color.font_emphasize'))
.fontWeight(FontWeight.Medium)
.fontSize($r('sys.float.Body_L'))
.onClick(() => {
let context = getContext(this) as common.Context;
try {
const documentSelectOptions = new picker.DocumentSelectOptions();
const documentPicker = new picker.DocumentViewPicker(context);
documentPicker.select(documentSelectOptions).then((documentSelectResult: Array<string>) => {
this.message = JSON.stringify(documentSelectResult);
if (documentSelectResult.length === 0) {
return;
}
this.getUIContext().showAlertDialog(
{
title: '文件路径',
message: this.message,
autoCancel: true,
alignment: DialogAlignment.Center,
offset: { dx: 0, dy: -20 },
gridCount: 3,
width: 300,
height: 300,
cornerRadius: $r('sys.float.corner_radius_level7'),
borderWidth: 1,
borderStyle: BorderStyle.Dashed,
borderColor: Color.Blue,
backgroundColor: Color.White,
textStyle: { wordBreak: WordBreak.BREAK_ALL },
confirm: {
value: '确定',
action: () => {
console.log('Confirm button is clicked.');
},
},
onWillDismiss: (dismissDialogAction: DismissDialogAction) => {
if (dismissDialogAction.reason === DismissReason.PRESS_BACK) {
dismissDialogAction.dismiss();
}
if (dismissDialogAction.reason === DismissReason.TOUCH_OUTSIDE) {
dismissDialogAction.dismiss();
}
}
}
)
}).catch((err: BusinessError) => {
console.error(`DocumentViewPicker.select failed with err: ${err.code}, ${err.message}`);
});
} catch (error) {
const err: BusinessError = error as BusinessError;
console.error(`DocumentViewPicker failed with err: ${err.code}, ${err.message}`);
}
})
}.height('5%')
Row(){
Text('文件名:')

View File

@ -17,16 +17,18 @@ export function HilogSadboxFontDirFile(ctx: Context,dirName:string){
console.error('list file failed with error message: ' + err.message + ', error code: ' + err.code);
});
}
export function CheckExistDir(dir:string):boolean{
export function CheckExistDir(ctx: Context,dir:string):boolean{
if (!dir || typeof dir !== 'string') {
console.error('Invalid directory path provided.');
return false;
}
try {
// 使用 fs.stat 获取路径的状态信息
fs.accessSync(dir);
//路径目录不存在
if(!fs.accessSync(dir)){
return false;
}
const stat = fs.statSync(dir);
if (stat.isDirectory()) {
if (stat&&stat.isDirectory()) {
console.info(`Directory exists: ${dir}`);
return true;
} else {
@ -52,22 +54,22 @@ export function ExtractDir(ctx: Context,dirName:string):boolean{
//err->表示复制失败
try {
//初始化源Fonts目录和沙箱Fonts目录路径
let srcPath = ctx?.resourceDir+ '/'+dirName+'/';
let destPath = ctx?.filesDir + '/'+dirName+'/';
let srcDir = ctx?.resourceDir+ '/'+dirName+'/';
let destDir = ctx?.filesDir + '/'+dirName+'/';
//检测目录是否存在
let srcDirState:boolean=CheckExistDir(srcPath);
let destDirState:boolean=CheckExistDir(destPath);
let srcDirState:boolean=CheckExistDir(ctx,srcDir);
let destDirState:boolean=CheckExistDir(ctx,destDir);
//源字体目录不存在则返回.->直接无法系统
if(!srcDirState){
return false;
}
//如果沙箱目录不存在则创建目录
if(!destDirState){
fs.mkdir(destPath);
console.info('Created sandbox directory successfully:', destPath);
fs.mkdir(destDir);
console.info('Created sandbox directory successfully:', destDir);
}
fs.copyDir(srcPath, destPath);
console.info('Fonts copied to sandbox successfully.');
ExtractFile(ctx,srcDir,destDir);
console.info('Copy dir to sandbox successfully.');
return true;
} catch (err) {
let msg = 'Unknown error';
@ -76,7 +78,30 @@ export function ExtractDir(ctx: Context,dirName:string):boolean{
} else if (typeof err === 'string') {
msg = err;
}
console.error(`Copy failed: ${msg}`);
console.error(`Copy dir failed: ${msg}, error code: ${err.code}`);
return false;
}
}
export function ExtractFile(ctx: Context,srcDir:string,destDir:string){
try {
//获取srcDir目录下所有文件,并复制到destDir目录下
fs.listFile(srcDir).then((filenames: Array<string>) => {
for (let i = 0; i < filenames.length; i++) {
console.log('文件名:', filenames[i]);
let srcFile=srcDir+'/'+filenames[i];
let destFile=destDir+'/'+filenames[i];
fs.copyFileSync(srcFile, destFile);
}
}).catch((err: BusinessError) => {
console.error('copy file error message: ' + err.message + ', error code: ' + err.code);
});
}catch (err) {
let msg = 'Unknown error';
if (err instanceof Error) {
msg = err.message;
} else if (typeof err === 'string') {
msg = err;
}
console.error(`Copy file failed: ${msg}, error code: ${err.code}`);
}
}