RN捕获异常
来源:互联网 发布:xp映射网络驱动器 编辑:程序博客网 时间:2024/04/19 18:00
目的
思路
alert 是否统一在rn中写,还是在原生中写?
拼接字符串 (系统+版本号+项目+info)
在信分期的项目中用现金贷的接口
android
init//getName()show()exit()//当UncaughtException发生时会转入该函数来处理uncaughtException()//自定义错误处理,收集错误信息 发送错误报告等操作均在此完成.handleException()//收集设备参数信息collectDeviceInfo()//保存错误信息到文件中getCatchString()//testtestException()
CrashHandler.javapackage com.xfq.app;import com.facebook.react.bridge.NativeModule;import com.facebook.react.bridge.ReactApplicationContext;import com.facebook.react.bridge.ReactContext;import com.facebook.react.bridge.ReactContextBaseJavaModule;import com.facebook.react.bridge.ReactMethod;import com.facebook.react.bridge.Promise;import com.facebook.react.bridge.LifecycleEventListener;import android.Manifest;import android.content.Context;import android.content.pm.PackageInfo;import android.content.pm.PackageManager;import android.os.Build;import android.os.Environment;import android.os.Handler;import android.os.Looper;import android.widget.Toast;import java.io.BufferedReader;import java.io.File;import java.io.FileInputStream;import java.io.FileOutputStream;import java.io.IOException;import java.io.InputStreamReader;import java.io.PrintWriter;import java.io.StringWriter;import java.io.Writer;import java.lang.Thread.UncaughtExceptionHandler;import java.lang.reflect.Field;import java.text.DateFormat;import java.text.SimpleDateFormat;import java.util.Date;import java.util.HashMap;import java.util.Map;public class CrashHandler extends ReactContextBaseJavaModule implements UncaughtExceptionHandler { private Promise jsPromise; // 系统默认的UncaughtException处理类 private UncaughtExceptionHandler mDefaultHandler = null; // 程序的Context对象 private Context mContext = null; // 用来存储设备信息和异常信息 private Map<String, String> infos = new HashMap<String, String>(); /** * 初始化 */ public CrashHandler(ReactApplicationContext reactContext) { super(reactContext); mContext = reactContext; // 获取系统默认的UncaughtException处理器 mDefaultHandler = Thread.getDefaultUncaughtExceptionHandler(); // // 设置该CrashHandler为程序的默认处理器 Thread.setDefaultUncaughtExceptionHandler(this); } @Override public String getName() { return "UncaughtExceptionHandler"; } @ReactMethod public void show(Promise promise) { this.jsPromise = promise; testException(); } @ReactMethod public void exit() { System.exit(0); // ActivityManager.AppExit(mContext); } /** * 当UncaughtException发生时会转入该函数来处理 */ @Override public void uncaughtException(Thread thread, Throwable ex) { if (!handleException(ex) && mDefaultHandler != null) { // 如果用户没有处理则让系统默认的异常处理器来处理 mDefaultHandler.uncaughtException(thread, ex); } } /** * 自定义错误处理,收集错误信息 发送错误报告等操作均在此完成. * * @param ex * @return true:如果处理了该异常信息;否则返回false. */ private boolean handleException(final Throwable ex) { if (ex == null) { return false; } // 收集设备参数信息// collectDeviceInfo(mContext); this.jsPromise.resolve(getCatchString(ex)); return true; } /** * 收集设备参数信息 * * @param ctx */ public void collectDeviceInfo(Context ctx) { try { PackageManager pm = ctx.getPackageManager(); PackageInfo pi = pm.getPackageInfo(ctx.getPackageName(), PackageManager.GET_ACTIVITIES); if (pi != null) { String versionName = pi.versionName == null ? "null" : pi.versionName; String versionCode = pi.versionCode + ""; infos.put("versionName", versionName); infos.put("versionCode", versionCode); infos.put("Build.VERSION.SDK_INT",Build.VERSION.SDK_INT+""); } } catch (Exception e) { } Field[] fields = Build.class.getDeclaredFields(); for (Field field : fields) { try { field.setAccessible(true); infos.put(field.getName(), field.get(null).toString());// LogUtil.d(TAG, field.getName() + " : " + field.get(null)); } catch (Exception e) { } } } /** * 保存错误信息到文件中 * * @param ex * @return 返回文件名称,便于将文件传送到服务器 */ private String getCatchString(Throwable ex) { StringBuffer sb = new StringBuffer(); for (Map.Entry<String, String> entry : infos.entrySet()) { String key = entry.getKey(); String value = entry.getValue(); sb.append(key + "=" + value + "\n"); } Writer writer = new StringWriter(); PrintWriter printWriter = new PrintWriter(writer); ex.printStackTrace(printWriter); Throwable cause = ex.getCause(); while (cause != null) { cause.printStackTrace(printWriter); cause = cause.getCause(); } printWriter.close(); String result = writer.toString(); sb.append(result); return sb.toString(); } public void testException() { new Thread(new Runnable() { public void run() { try { Thread.currentThread().sleep(3000);//阻断3秒 } catch (InterruptedException e) { e.printStackTrace(); } String msg = ""; System.out.println(msg.charAt(1)); } }).start(); }}
CrashHandlerPackage.javapackage com.xfq.app;import com.facebook.react.ReactPackage;import com.facebook.react.bridge.JavaScriptModule;import com.facebook.react.bridge.NativeModule;import com.facebook.react.bridge.ReactApplicationContext;import com.facebook.react.uimanager.ViewManager;import java.util.Map;import java.util.Arrays;import java.util.List;import java.util.Collections;import java.util.ArrayList;public class CrashHandlerPackage implements ReactPackage { @Override public List<Class<? extends JavaScriptModule>> createJSModules() { return Collections.emptyList(); } @Override public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) { return Collections.emptyList(); } @Override public List<NativeModule> createNativeModules(ReactApplicationContext reactContext) { List<NativeModule> modules = new ArrayList<>(); modules.add(new CrashHandler(reactContext)); return modules; }}
ios
.h//// UncaughtExceptionHandler.h// XinfenqiApp//// Created by yyt on 2016/10/8.// Copyright © 2016年 Facebook. All rights reserved.//#import <Foundation/Foundation.h>#import <UIKit/UIKit.h>#import "RCTBridgeModule.h"@interface UncaughtExceptionHandler : NSObject <RCTBridgeModule>{ BOOL dismissed;}@property RCTPromiseResolveBlock resolve;@property RCTPromiseRejectBlock reject;@endvoid HandleException(NSException *exception);void SignalHandler(int signal);void InstallUncaughtExceptionHandler(void);
//// UncaughtExceptionHandler.m// XinfenqiApp//// Created by yyt on 2016/10/8.// Copyright © 2016年 Facebook. All rights reserved.//#import "UncaughtExceptionHandler.h"#include <libkern/OSAtomic.h>#include <execinfo.h>NSString * const UncaughtExceptionHandlerSignalExceptionName = @"UncaughtExceptionHandlerSignalExceptionName";NSString * const UncaughtExceptionHandlerSignalKey = @"UncaughtExceptionHandlerSignalKey";NSString * const UncaughtExceptionHandlerAddressesKey = @"UncaughtExceptionHandlerAddressesKey";volatile int32_t UncaughtExceptionCount = 0;const int32_t UncaughtExceptionMaximum = 10;const NSInteger UncaughtExceptionHandlerSkipAddressCount = 4;const NSInteger UncaughtExceptionHandlerReportAddressCount = 5;static UncaughtExceptionHandler *defaultHandler = nil;@implementation UncaughtExceptionHandlerRCT_EXPORT_MODULE();RCT_EXPORT_METHOD(show:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject){ defaultHandler = self; dispatch_sync(dispatch_get_main_queue(), ^(){ // AppDelegate *delegate = (AppDelegate *)[[UIApplication sharedApplication] delegate]; // self.resolve = resolve;// self.reject = reject; InstallUncaughtExceptionHandler();// [self performSelector:@selector(ssss) withObject:nil afterDelay:5.0]; });}RCT_EXPORT_METHOD(exit){ exit(0);}+ (NSArray *)backtrace{ void* callstack[128]; int frames = backtrace(callstack, 128); char **strs = backtrace_symbols(callstack, frames); int i; NSMutableArray *backtrace = [NSMutableArray arrayWithCapacity:frames]; for ( i = UncaughtExceptionHandlerSkipAddressCount; i < UncaughtExceptionHandlerSkipAddressCount + UncaughtExceptionHandlerReportAddressCount; i++) { [backtrace addObject:[NSString stringWithUTF8String:strs[i]]]; } free(strs); return backtrace;}- (void)alertView:(UIAlertView *)anAlertView clickedButtonAtIndex:(NSInteger)anIndex{ if (anIndex == 0) { dismissed = YES; }else if (anIndex==1) { NSLog(@"ssssssss"); }}- (void)validateAndSaveCriticalApplicationData{}- (void)handleException:(NSException *)exception{ [self validateAndSaveCriticalApplicationData]; self.resolve([exception reason]); /* UIAlertView *alert = [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"抱歉,程序出现了异常", nil) message:[NSString stringWithFormat:NSLocalizedString( @"如果点击继续,程序有可能会出现其他的问题,建议您还是点击退出按钮并重新打开\n\n" @"异常原因如下:\n%@\n%@", nil), [exception reason], [[exception userInfo] objectForKey:UncaughtExceptionHandlerAddressesKey]] delegate:self cancelButtonTitle:NSLocalizedString(@"退出", nil) otherButtonTitles:NSLocalizedString(@"继续", nil), nil]; [alert show]; */ CFRunLoopRef runLoop = CFRunLoopGetCurrent(); CFArrayRef allModes = CFRunLoopCopyAllModes(runLoop); while (!dismissed) { for (NSString *mode in (__bridge NSArray *)allModes) { CFRunLoopRunInMode((CFStringRef)mode, 0.001, false); } } CFRelease(allModes); NSSetUncaughtExceptionHandler(NULL); signal(SIGABRT, SIG_DFL); signal(SIGILL, SIG_DFL); signal(SIGSEGV, SIG_DFL); signal(SIGFPE, SIG_DFL); signal(SIGBUS, SIG_DFL); signal(SIGPIPE, SIG_DFL); if ([[exception name] isEqual:UncaughtExceptionHandlerSignalExceptionName]) { kill(getpid(), [[[exception userInfo] objectForKey:UncaughtExceptionHandlerSignalKey] intValue]); } else { [exception raise]; }}@endvoid HandleException(NSException *exception){ int32_t exceptionCount = OSAtomicIncrement32(&UncaughtExceptionCount); if (exceptionCount > UncaughtExceptionMaximum) { return; } NSArray *callStack = [UncaughtExceptionHandler backtrace]; NSMutableDictionary *userInfo = [NSMutableDictionary dictionaryWithDictionary:[exception userInfo]]; [userInfo setObject:callStack forKey:UncaughtExceptionHandlerAddressesKey]; [defaultHandler performSelectorOnMainThread:@selector(handleException:) withObject: [NSException exceptionWithName:[exception name] reason:[exception reason] userInfo:userInfo] waitUntilDone:YES];}void SignalHandler(int signal){ int32_t exceptionCount = OSAtomicIncrement32(&UncaughtExceptionCount); if (exceptionCount > UncaughtExceptionMaximum) { return; } NSMutableDictionary *userInfo = [NSMutableDictionary dictionaryWithObject:[NSNumber numberWithInt:signal] forKey:UncaughtExceptionHandlerSignalKey]; NSArray *callStack = [UncaughtExceptionHandler backtrace]; [userInfo setObject:callStack forKey:UncaughtExceptionHandlerAddressesKey]; [defaultHandler performSelectorOnMainThread:@selector(handleException:) withObject: [NSException exceptionWithName:UncaughtExceptionHandlerSignalExceptionName reason: [NSString stringWithFormat: NSLocalizedString(@"Signal %d was raised.", nil), signal] userInfo: [NSDictionary dictionaryWithObject:[NSNumber numberWithInt:signal] forKey:UncaughtExceptionHandlerSignalKey]] waitUntilDone:YES];}void InstallUncaughtExceptionHandler(void){ NSSetUncaughtExceptionHandler(&HandleException); signal(SIGABRT, SignalHandler); signal(SIGILL, SignalHandler); signal(SIGSEGV, SignalHandler); signal(SIGFPE, SignalHandler); signal(SIGBUS, SignalHandler); signal(SIGPIPE, SignalHandler);}
RN
如果是RN的代码错误,在alert之前,程序以及崩溃,alert无法调用显示。
异常之后,就再也调用不了原生模块了
const ErrorUtils = require('ErrorUtils');getCrash(){ var str = moment().format("YYYY-MM-DD HH:mm")+'|' + DeviceInfo.getBrand()+ DeviceInfo.getModel()+'|' + DeviceInfo.getSystemVersion()+'|' + DeviceInfo.getBundleId()+'|' + DeviceInfo.getVersion()+'|' if (!__DEV__) { ErrorUtils.setGlobalHandler(error => { console.log("很抱歉error---",str + error); this.showAlert() }) } NativeModules.UncaughtExceptionHandler.show() .then(data => { console.log('获取异常info',str + data) this.showAlert() })}
0 0
- RN捕获异常
- 异常捕获
- 捕获异常
- 异常捕获
- 捕获异常
- 异常捕获
- 异常捕获
- 捕获异常
- 捕获异常
- 异常捕获
- 捕获异常
- 异常捕获
- 捕获异常
- 捕获异常
- 捕获异常
- 捕获异常
- 捕获异常
- 异常捕获
- 并发与并行的区别
- 内存管理:01存储器层次结构
- 文章标题
- nRF2401A无线传输模块介绍
- (模板题)UVALive 7362 Farey(欧拉函数)
- RN捕获异常
- [已解决]error: possibly undefined macro: AC_PROG_LIBTOOL
- Leetcode 27 Remove Element
- Ubuntu 16.04 一系列软件安装命令,包括QQ、搜狗、Chrome、vlc、网易云音乐安装方法
- 自定义搜索框
- 第五周 求两整数正差值
- 知识竞赛时,倒计时字体的大小和位置如何调整?
- Jenkins+maven+svn+tomcat操作手册(一)
- 2016中国互联网发展趋势报告(111页PPT可下载)