2

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

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

前向声明并且它的实现隐藏在 .cpp 文件中是非常令人恼火AAssetDir的,否则(可能?)可能检查内部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?

4

1 回答 1

9

以下代码允许检查 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会返回非 null const char *。如果是NULL- 没有文件夹,否则 - 有一个。

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

于 2014-09-30T15:04:15.517 回答