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

时间:2022-05-04 03:58:44

I need to check wether a certain directory exists in apk.

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

The android/asset_manager.h api seems to be inconsistent - it returns NULL when AAsset* AAssetManager_open(AAssetManager* mgr, const char* filename, int mode); fails to open a file, but for directories AAssetDir* AAssetManager_openDir(AAssetManager* mgr, const char* dirName);'s implementation always returns a new AAssetDir(...), even if internally it failed to open/find the directory in apk.

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

It is quite irritating that AAssetDir is forward-declared and it's implementation is hidden away in the .cpp file, otherwise it would've been (maybe?)possible to check the internal AssetDir object for validity.

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

There is another option I am exploring right now - to call java and do something like:

我现在正在探索另一个选项 - 调用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;
}

But it seems "dirty" to me, and it would definitely be pretty slow (which isn't a big factor in my specific code, but still - avoiding unnecessary pessimisation is good coding practice).

但它对我来说似乎“肮脏”,它肯定会很慢(这不是我特定代码中的一个重要因素,但仍然 - 避免不必要的悲观化是良好的编码实践)。

Have I missed something? Is it possible to check if directory exists in apk via native code only? If not - how to best do it with jni?

我错过了什么吗?是否可以通过本机代码检查apk中是否存在目录?如果不是 - 如何最好地使用jni?

1 个解决方案

#1


5  

Following code allows to check if certain folder exists in apk bundle:

以下代码允许检查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 will always return a pointer to initialized object, even if the specified directory doesn't exist. In other words, checking if assetDir==NULL is pointless. Trick is to check if AAssetDir_getNextFileName will return a non-null const char *. If it's NULL - there is no folder, else - there is one.

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

Important notice: if a folder is empty, but for some reason you need to know if it exists in apk, that code would be useless due to the way it checks folder existance. But AFAIK empty folders aren't copied to apk, so such situation is improbable.

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

#1


5  

Following code allows to check if certain folder exists in apk bundle:

以下代码允许检查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 will always return a pointer to initialized object, even if the specified directory doesn't exist. In other words, checking if assetDir==NULL is pointless. Trick is to check if AAssetDir_getNextFileName will return a non-null const char *. If it's NULL - there is no folder, else - there is one.

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

Important notice: if a folder is empty, but for some reason you need to know if it exists in apk, that code would be useless due to the way it checks folder existance. But AFAIK empty folders aren't copied to apk, so such situation is improbable.

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