TEL:400-8793-956
当前位置:开发工具

Android如何捕获本地信号异常,如何在Activey中调用将通过c底部的反射结束的方法,然后重新打开Android应用程序?

提问者:网民 近期获赞:43 浏览人数:124 发布时间:2020-12-09 10:15:09

 问:在Android系统上运行时,有四个主要异常会导致应用程序崩溃并退出。

 
答:runtimeException。
ANR。
JNI类和我们自己编写的C代码生成的信号异常。
由第三方so数据包引起的本机信号异常。
因为我们公司的应用程序绝对不需要崩溃退出,所以我着手处理这四种异常,第一种非常容易处理(通过继承Uncaught Exception Handler;通过侦听ANR广播系统;或者通过将C编写为模仿Java中的try-cache函数来捕获信号异常并进行处理),第四个比较困难。
捕获本机异常需要两个步骤
 
在C的底部捕获本机信号
After receiving the native signal, the signal processing function in C layer calls the method in Java through reflection.
在C的底部捕获本机信号也非常简单。它可以通过信号进行注册。接收到本机信号后,它将直接进入信号处理功能。
最麻烦的是第二步,如何反思。
当前的问题
当前的问题是如何在接收到本地信号后如何通过反射在C语言的信号处理功能中调用Java中的方法。
通过通用C层中的反射来调用Java层的方法没问题,但是当前的问题是在信号处理函数中无法调用它,或者它没有任何作用,因为当捕获信号时,原始进程将很快关闭。
到目前为止,我尝试过的方法是
 
在信号处理功能中,调用原始活动的方法不容易使用。
在信号处理功能中,调用另一个进程的活动(在清单文件中配置该进程)的方法不容易使用。
在信号处理功能中,将引发并且不能引发异常。
在信号处理函数中,可以引发异常(提前取消默认的关闭操作),但不会被Java层中的异常捕获类捕获(但不能在信号处理函数中引发)捕获并处理)。
部分C代码
 
void debug(const char *format, ... ) {
    va_list argptr;
    va_start(argptr, format);
    __android_log_vprint(ANDROID_LOG_ERROR, "NATIVE_LIB", format, argptr);
    va_end(argptr);
}
 
static JNIEnv *env;
static jobject obj;
static jclass clazz;
static jmethodID methodID;
 
//------------------------------------- C abnormal signal acquisition, complex acquisition--------------------------------------------------------------------------------------------------
 
const int handledSignals[] = {
    SIGSEGV, //Signal 11 Invalid Memory Reference
    SIGABRT, //Signal 6 Termination Signal from Abrt Function
    SIGFPE, //Signal 8 Floating Point Anomalies
    SIGILL, //Signal 4 Illegal Directive
    SIGBUS, //Signal 7 Bus Error
    SIGALRM//Signal 14 Signal from Alarm
};
 
//const int handledSignalsNum = sizeof(handledSignals) / sizeof(handledSignals[0]);
Enum {handled Signals Num = sizeof (handled Signals) / sizeof (handled Signals [0])}; // Instead of the above, this is used to avoid errors in Variable modified XXXXXX at file scope.
struct sigaction old_handlers[handledSignalsNum];
 
// When a Native crash occurs and the previous signal anomalies occur, my_sigaction is called to complete the signal processing.
void my_sigaction(int signal, siginfo_t *info, void *reserved) {
    // Here catch the native crash
    Debug.
 
////    const char*const message = coffeecatch_get_message();
//// debug ("** FATAL ERROR:% s n", message captured globally";
 
        (* env) - > CallVoid Method (env, obj, methodID, (* env) - > New String UTF (env, "Hello World");
}
 
int loadSigaction() {
    struct sigaction handler;
    memset(&handler, 0, sizeof(sigaction));
    handler.sa_sigaction = my_sigaction;
    // After signal processing, reset to the default processing mode.
            // SA_RESTART: Re-initiate syscall interrupted by the signal.
            // SA_NOCLDSTOP: Causes the parent process not to receive SIGCHLD signals when its child process pauses or continues.
            // SA_NOCLDWAIT: Makes the parent process not receive SIGCHLD signal when its child process exits, and then the child process will not become a zombie process if it exits.
            // SA_NODEFER: Invalidates the shielding of the signal, i.e. the signal can still be sent during the execution of the signal processing function.
            // SA_RESETHAND: After signal processing, reset to the default processing mode.
            // SA_SIGINFO: Use sa_sigaction members instead of sa_handler as signal processing functions.
    handler.sa_flags = SA_RESETHAND;
 
    Int i; // for loop I needs to be defined outside otherwise error will be reported
    for (i = 0;i < handledSignalsNum; ++i) {
 
//        if(i == 0){
The /// sigaction function is used to change the behavior of a process when it receives a specific signal. If the second and third parameters are set to NULL, the function can be used to check the validity of the signal.
// sigaction (handled signals [i], // representing signal coding) can be any specific and effective signal except SIGKILL and SIGSTOP. Defining their own processing functions for these two signals will lead to signal installation errors.
/& handler, // A pointer to an instance of the structured sigaction that specifies the processing of a particular signal, and if set to null, the process performs the default processing.
// SA_RESTART; // is similar to the parameter act, except that the original processing of the corresponding signal can also be set to NULL.
//        } else {
The /// sigaction function is used to change the behavior of a process when it receives a specific signal. If the second and third parameters are set to NULL, the function can be used to check the validity of the signal.
        Sigaction (handled signals [i], // representing signal coding) can be any specific and effective signal except SIGKILL and SIGSTOP. Defining their own processing functions for these two signals will lead to signal installation errors.
                Handler, // A pointer to an instance of the structured sigaction that specifies the processing of a particular signal, and if set to null, the process performs the default processing.
                Old_handlers [i]; // is similar to the parameter act, except that the original signal processing can also be set to NULL.
//        }
    }
 
    return 1;
}
 
 
// Simple handling of simple capture
void handler(int sig){
    Debug ("processing");
}
 
jstring Java_com_wtest_wlib_android_catchs_CatchNativeCrash_loadCatch(
            JNIEnv* zenv,   
            jobject thiz)    
{
    env = zenv;
    obj = thiz;
    Load Sigaction (); // Load Capture of JNI Abnormal Signals
 
// signal (SIGALRM, handler); // Another simple capture method
 
    clazz = (*env)->FindClass(env, "com/wtest/wlib/android/catchs/CatchNativeCrash");
 
    methodID = (*env)->GetMethodID(env, clazz, "show", "(Ljava/lang/String;)V");
 
    (* env) - > CallVoid Method (env, obj, methodID, (* env) - > New String UTF (env, "Hello World");
 
    Char * CSTR = Register Native Signal Capture ok; //jni almost uses this way to define C language strings
    Jstring jstr = (* env) - > New String UTF (env, cstr); // Common Writing
    return jstr;
}
上一篇: 返回列表
下一篇: Github上git commit提交注释的规范