仅通过本机代码检查apk中是否存在目录(文件夹)

Checking if directory (folder) exists in apk via native code only

本文关键字:存在 文件夹 是否 本机代码 检查 apk      更新时间:2023-10-16

我需要检查apk中是否存在某个目录。

android/asset_manager.hAPI似乎不一致——当AAsset* AAssetManager_open(AAssetManager* mgr, const char* filename, int mode);无法打开文件时,它会返回NULL,但对于目录,AAssetDir* AAssetManager_openDir(AAssetManager* mgr, const char* dirName);的实现总是返回new AAssetDir(...),即使在内部无法打开/找到apk中的目录。

令人恼火的是,AAssetDir是前向声明的,它的实现隐藏在.cpp文件中,否则(也许?)可以检查内部AssetDir对象的有效性。

我现在正在探索另一种选择——调用java并做一些类似的事情:

public static boolean folderExistsInApk(final String path){
    AssetManager assetManager = activity.getAssets();
    try{
        //if .list would fail, it would throw IOException
        //which would signal that there is no such directory
        assetManager.list(path);
    }catch(Exception e){
        return false;
    }
    return true;
}

但对我来说,它似乎很"脏",而且肯定会很慢(这在我的特定代码中不是一个很大的因素,但仍然是——避免不必要的悲观情绪是一种很好的编码实践)。

我错过什么了吗?是否可以仅通过本机代码检查apk中是否存在目录?如果没有-如何最好地与jni合作?

以下代码允许检查apk捆绑包中是否存在特定文件夹:

#include <android/asset_manager.h>
bool directoryExists(jobject assetManager, const std::string& path){
    auto assetDir = AAssetManager_openDir( assetManager, path.c_str() );
    bool r = AAssetDir_getNextFileName(assetDir) != NULL;
    AAssetDir_close( assetDir );
    return r;
}

AAsetManager_openDir将始终返回一个指向初始化对象的指针,即使指定的目录不存在。换句话说,检查assetDir==NULL是否毫无意义。技巧是检查AAssetDir_getNextFileName是否会返回非空的const char *。如果是NULL——没有文件夹,否则——有一个。

重要提示:如果一个文件夹是空的,但出于某种原因,你需要知道它是否存在于apk中,由于它检查文件夹存在的方式,该代码将毫无用处。但AFAIK的空文件夹并没有复制到apk,所以这种情况是不可能的