捕获运行在 Android 上的本机代码引发的异常 [英] Catching exceptions thrown from native code running on Android

查看:48
本文介绍了捕获运行在 Android 上的本机代码引发的异常的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我目前正在进行的项目需要我编写跨平台程序实现的 android 部分.

The project I'm currently working on requires me to code up the android portion of a cross platform program implementation.

通过 android-ndk 构建了一组核心功能并将其包含在我的应用程序中.我发现本机代码中发生的任何异常/崩溃充其量只会不时报告.发生错误时,我会出现以下行为之一:

A core set of functionality is built and included in my app through android-ndk. I've found that any exception/crash which happens in the native code is only reported now and again at best. When an error occurs I get one of the following behaviours:

  • 发生堆栈跟踪/内存转储并写入日志文件.程序消失(设备上没有给出关于为什么应用程序突然不再存在的指示).
  • 没有任何堆栈跟踪/转储或其他迹象表明本机代码已崩溃.程序消失.
  • java 代码因 NullPointerException 崩溃(通常每个本地代码异常都在同一个地方,这是一个巨大的痛苦).通常会导致我花很长时间尝试调试 Java 代码抛出错误的原因,结果却发现 Java 代码很好.本机代码错误已被完全屏蔽.
  • A stacktrace / memory dump occurs and is written to the log file. The program disappears (no indication is given on the device as to why suddenly the app is no longer there).
  • No stacktrace / dump or other indication is given that the native code has crashed. The program disappears.
  • The java code crashes with a NullPointerException (usually in the same place per native code exception which is a massive pain). Usually causing me to spend quite a while trying to debug why the Java code has thrown an error only to discover the Java code is fine & the native code error has been entirely masked.

我似乎找不到任何方法来隔离"我的代码,使其免受本机代码中出现的错误的影响.Try/catch 语句被彻底忽略.除了当我的代码被指责为罪魁祸首之外,我什至没有机会警告用户发生错误.

I can't seem to find any way to "insulate" my code against errors which occur in native code. Try/catch statements are resoundingly ignored. Apart from when my code is fingered as the culprit I don't even get a chance to warn the user than an error has occurred.

有人能帮我解决一下原生代码崩溃的情况吗?

Can someone please help me out as to how to respond to the situation of crashing native code?

推荐答案

我曾经遇到过同样的问题,确实在android中(在执行na​​tive代码时通常在任何VM内部)如果你抛出C++异常并且这个一个没有被抓住,VM就死了(如果我理解正确,我认为这是你的问题).我采用的解决方案是在 C++ 中捕获任何异常并抛出 java 异常,而不是使用 JNI.下一个代码是我的解决方案的简化示例.首先,您有一个捕获 C++ 异常的 JNI 方法,然后在 try 子句中注释 Java 异常.

I used to have the same problem, it is true that in android (inside any VM in general when executing native code) if you throw a C++ exception and this one is not caught, the VM dies (If I understood correctly, I think it is your problem). The solution I adopted was to catch any exception in C++ and throw a java exception instead of using JNI. The next code it is a simplified example of my solution. First of all you have a JNI method that catches a C++ exception and then in the try clause the Java exception is annotated.

JNIEXPORT void JNICALL Java_com_MyClass_foo (JNIEnv *env, jobject o,jstring param)
{
    try
    {
        // Your Stuff
        ...
    }
    // You can catch std::exception for more generic error handling
    catch (MyCxxException e)
    {
        throwJavaException (env, e.what());
    }
}


void throwJavaException(JNIEnv *env, const char *msg)
{
    // You can put your own exception here
    jclass c = env->FindClass("company/com/YourException");

    if (NULL == c)
    {
        //B plan: null pointer ...
        c = env->FindClass("java/lang/NullPointerException");
    }

    env->ThrowNew(c, msg);
}

请注意,在 ThrowNew 之后,本机方法不会突然自动终止.也就是说,控制流返回到您的本机方法,此时新的异常处于未决状态.在您的 JNI 方法完成后将引发异常.

Note that after a ThrowNew, the native method does not abruptly terminate automatically. That is, control flow returns to your native method, and the new exception is pending at this point. The exception will be thrown after your JNI method is finished.

我希望这是您正在寻找的解决方案.

I hope it was the solution you are looking for.

这篇关于捕获运行在 Android 上的本机代码引发的异常的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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