仅通过本机代码检查APK中是否存在目录(文件夹) [英] Checking if directory (folder) exists in apk via native code only

查看:168
本文介绍了仅通过本机代码检查APK中是否存在目录(文件夹)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要检查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);的实现总是返回new AAssetDir(...),即使内部无法打开/在APK中找到目录.

AAssetDir是前向声明的,并且它的实现被隐藏在.cpp文件中,这非常令人恼火,否则可能(也许?)检查内部AssetDir对象的有效性./p>

我现在正在探索另一种选择-调用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,因此这种情况是不可能的.

I need to check wether a certain directory exists in 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.

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.

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

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?

解决方案

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

#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.

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中是否存在目录(文件夹)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆