場景描述開發過程中可能需要在native側實現資源訪問,應用經常會遇到如下的業務訴求: 場景一:c++訪問公共目錄的文件圖片等資源(圖庫和文管) 場景二:c++訪問沙箱文件/圖片等資源 場景三:c++訪問應用包里的文件/圖片資源 rawfile和resource 場景一:c++訪問公共目錄的文件圖片等資源(圖庫和文管)一、獲取擁有讀/寫權限的文件URI,當前需要在arkts側獲取并通過NAPI的方式將uri傳遞給C++側,如通過picker獲取對應uri,再將uri傳遞到c++側。 二、使用FileManagement\_ErrCode OH\_FileUri\_GetPathFromUri根據uri獲取對應的文件路徑。 //將傳入的uri轉換成路徑path。 FileManagement_ErrCode OH_FileUri_GetPathFromUri (const char * uri, unsigned int length, char ** result ) 三、使用C++標準的文件接口打開文件。 fp = fopen(path, "r"); 場景二:c++訪問沙箱文件/圖片等資源一、獲取沙箱路徑 方式一:通過arkts側傳遞 在應用arkts側,提供了ApplicationContext對象,可獲取沙箱路徑: 應用arkts側 在ApplicationContext對象中獲取應用沙箱路徑,傳遞應用沙箱路徑到Native C++側。 let applicationContext = getContext().getApplicationContext(); // 獲取應用上下文對象 let filesDir = applicationContext.filesDir; // 應用通用文件路徑 let cacheDir = applicationContext.cacheDir; // 應用緩存文件路徑 let tempDir = applicationContext.tempDir; // 應用臨時文件路徑 備注:目前NDK并沒有提供獲取ApplicationContext的接口,無法直接獲取應用沙箱路徑。 方式二:拼接 根據應用沙箱目錄的[規范](https:///openharmony/docs/blob/master/zh-cn/applicat...),在Native C++側定義完整的沙箱路徑。如:/data/app/el2/100/base/{包名}/haps/entry/files/test.txt 二、根據沙箱路徑打開文件/圖片等資源 參考場景一的使用C++標準的文件接口打開文件,path傳入對應文件所在的沙箱路徑。 fp = fopen(path, "r"); 場景三:c++訪問應用包里的文件/圖片資源(rawfile和resource)一、js側傳入對應的資源管理對象resourceManager 獲取本應用包資源resourceManager對象的示例如下: private resmgr = getContext().resourceManager; // 獲取本應用包的資源對象 二、獲取文件/資源路徑一般是由開發者自行規劃的,可由開發者自行拼接。在傳遞ResourceManger的同時傳遞了對應的文件夾名稱。 let rawfilelist = testNapi.getFileList(this.resmgr, "rawdir"); //傳入資源對象,以及訪問的rawfile文件夾名稱 三、C++側訪問rawfile和resource下的資源文件 通過arkts傳入的resourceManager訪問資源文件,整個過程按照以下步驟進行: 1、初始化resourceManager2、打開rawfile文件初始化: NativeResourceManager *manager = OH_ResourceManager_InitNativeResourceManager(env, args[0]); 為使用OH\_ResourceManager\_OpenRawFile打開rawfile文件(mNativeResMgr為js傳入的resourceManager): RawFile *rawFile = OH_ResourceManager_OpenRawFile(mNativeResMgr, filename.c_str()); if (rawFile != nullptr) { OH_LOG_Print(LOG_APP, LOG_ERROR, GLOBAL_RESMGR, tag, "OH_ResourceManager_OpenRawFile success"); } 使用OH\\_ResourceManager\\_GetRawFileSize獲取rawfile大小并申請內存: long len = OH_ResourceManager_GetRawFileSize(rawFile); std::unique_ptr<uint8_t[]> data= std::make_unique<char[]>(len); 讀取rawfile:方式一:使用OH\_ResourceManager\_ReadRawFile一次性讀取rawfile全部內容: int res = OH_ResourceManager_ReadRawFile(rawFile, data.get(), len); 方式二:使用OH\\_ResourceManager\\_ReadRawFile多次部分讀取rawfile, 每次讀取100 Byte。獲取全部內容: long offset = 0; while (OH_ResourceManager_GetRawFileRemainingLength(rawFile) > 0) { OH_ResourceManager_ReadRawFile(rawFile, data.get() + offset, 100); offset += 100; } 使用OH\_ResourceManager\_CloseRawFile關閉打開的指針對象: OH_ResourceManager_CloseRawFile(rawFile); OH_ResourceManager_ReleaseNativeResourceManager(mNativeResMgr); 轉為arkts對象(可以根據這個arkts對象在arkts側調用): return CreateJsArrayValue(env, data, len); |
|