Android 下 Poco库的异常不能被catch

本文探讨了在Android项目中遇到的Poco库异常无法捕获的问题,通过实验发现,SDK中的第三方库异常确实可以被捕获,并提供了解决方案。文中详细记录了在使用Poco库时如何正确捕获异常,以及通过示例代码验证了异常捕获的有效性。

记一次Android项目中SDK里Poco库异常无法捕获的问题,编译Poco库,打开了异常的选项:android.mk

LOCAL_CPPFLAGS   := -frtti -fexceptions

在JNI的动态库中有异常抛出时无法正常捕获,会让程序崩溃。

  • 解决方法:在使用Poco库的异常时,需要在之前正常catch过一次才能让Poco库的异常被catch。

项目的这个问题是解决了,但并没有弄明白,看了源码也没发现问题,有知道的朋友可以在下方留言探讨下。

本想着是不是android的SDK中都无法正常捕获三方库中的异常时,写了一个demo.so,

#include "Demo.h"
int  add(int a, int b)
{
	throw -1;
	return a + b;
}

在android studio 新建一个native工程, 参考上一篇文章:android studio cmake使用三方库

在native-lib.cpp捕获:

    try{
        LOGI(" try Demo.so Add Func ...");
        int a =  add(4, 6);
        LOGI(" add result:%d", a);
    }catch (...)
    {
        LOGI("catch add ....");
    }

通过日志查看,可以被正常捕获:

通过demo.so验证了SDK中三方so的异常是可以捕获的。

看到可以捕获异常了,在继续把poco库中的异常也加入看下效果:

try {
       const std::string str = "10.135.129.41:8888";
        Poco::Net::SocketAddress sa;
        Poco::Net::StreamSocket ss;
        LOGI("try Poco socket Address...");
        ss.connect(sa, Poco::Timespan(6, 0));
        LOGI(" try Poco connect ---------");
    }
    catch (Poco::Exception &e)
    {
      std::string str = e.displayText();
      LOGI("catch Poco connect Exception .....%s.", str.c_str());
    }

运行结果比较意外,竟然可以捕获到了异常:

在得到意外结果后继续验证了是不是Poco库都需要在使用前先用标准异常,但是发现直接在cpp中使用poco的Exception后,Poco库也能正常被捕获,代码标号2处。

Demo地址:

https://github.com/caifubing/AndroidStudio_Pro.git

native-lib.cpp代码: 在只用4之前,1、2、3任何一处被执行都可以正常被捕获,否则程序会崩溃。

#include <jni.h>
#include <string>

#include <exception>
#include <stdexcept>
#include <iostream>
#include <android/log.h>
#include "Demo.h"

#include "string.h"
#include "Poco/Config.h"
#include "Poco/Foundation.h"
#include "Poco/Exception.h"
#include "Poco/Net/ServerSocket.h"
#include "Poco/Net/NetException.h"
#include "Poco/NumberFormatter.h"
#include "Poco/Timestamp.h"

using  namespace Poco;

#define TAG "jni_logger"
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO, TAG, __VA_ARGS__)

using namespace std;
extern "C" JNIEXPORT jstring JNICALL
Java_com_c_1digi_pocoexception_MainActivity_stringFromJNI(
        JNIEnv* env,
        jobject /* this */) {
    std::string hello = "Hello from C++";
////1. c++标准库异常
//    try {
//        LOGI("throw 1");
//        throw  1;
//    }catch (...)
//    {
//        LOGI("catch ... throw 1");
//    }
/*
////2. poco 网络异常
    try {
        LOGI("try NetException ...");
        throw Net::NetException();
    }catch (Poco::Exception &e )
    {
        LOGI("cathc NetException ... %s", e.displayText().c_str());
    }
    */

////3. 三方so中抛出c++标准异常
    try{
        LOGI(" try Demo.so Add Func ...");
        int a =  add(4, 6);
        LOGI(" add result:%d", a);
    }catch (...)
    {
        LOGI("catch add ....");
    }


////4. 三方so中抛出poco 网络异常
    try {
       const std::string str = "10.135.129.41:8888";
        Poco::Net::SocketAddress sa;
        Poco::Net::StreamSocket ss;
        LOGI("try Poco socket Address...");
        ss.connect(sa, Poco::Timespan(6, 0));
        LOGI(" try Poco connect ---------");
    }
    catch (Poco::Exception &e)
    {
      std::string str = e.displayText();
      LOGI("catch Poco connect Exception .....%s.", str.c_str());
    }

    return env->NewStringUTF(hello.c_str());
}

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值