native 源码修改、优化

本贴最后更新于 1944 天前,其中的信息可能已经水流花落

iOS

1. 本地图片资源加载闪退问题

环境:react-native 0.55.4
友盟上报错误如下:

7 libsystem_malloc.dylib 0x00000001824e0384 + 0
8 CoreFoundation 0x0000000182924ec8 + 44
9 libicucore.A.dylib 0x0000000182667ee8 utext_close + 68
10 libicucore.A.dylib 0x000000018271b3fc _ZN3icu12RegexMatcherD2Ev + 132
11 libicucore.A.dylib 0x000000018271b43c _ZN3icu12RegexMatcherD0Ev + 12
12 libicucore.A.dylib 0x00000001827690ac uplrules_select + 216
13 libicucore.A.dylib 0x0000000182769554 uregex_close + 36
14 Foundation 0x0000000183259540 + 64
15 Hebao!-[RCTImageLoader canHandleRequest:] [RCTImageLoader.m : 794]
16 Hebao!-[RCTNetworking handlerForRequest:] [RCTNetworking.mm : 209]
17 Hebao!-[RCTNetworking networkTaskWithRequest:completionBlock:] [RCTNetworking.mm : 0]
18 Hebao!-[RCTImageLoader _loadURLRequest:progressBlock:completionBlock:] [RCTImageLoader.m : 0]
19 Hebao!__118-[RCTImageLoader _loadImageOrDataWithURLRequest:size:scale:resizeMode:progressBlock:partialLoadBlock:completionBlock:]_block_invoke.181 [RCTImageLoader.m : 404]

根据报错内容和符号解析定位到代码位置
/workspace/Libraries/Image/RCTImageLoader line 802

NSString *query = requestURL.query;
if (query != nil && [videoRegex firstMatchInString:query
options:0
range:NSMakeRange(0, query.length)]) {
return NO;
}


此处可能出现多线程问题,修改如下
>```
 static dispatch_once_t onceToken;
 dispatch_once(&onceToken, ^{
 NSError *error = nil;
 videoRegex = [NSRegularExpression  regularExpressionWithPattern:@"(?:&|^)ext=MOV(?:&|$)"
 options:NSRegularExpressionCaseInsensitive
 error:&error];
 if (error) {
 RCTLogError(@"%@", error);
 }
 });

2. Reload 方法桥接

虽然 react-native 提供 Live Reload, 修改代码会实时打包部署,从而页面也会随着一起更新,但是这项功能开启会导致一定的卡顿,特别如果你是用 WebStorm 开发项目。
目前摇一摇是唯一手动触发更新的操作,但是很明显效率不高,摇起来很费劲,其实我们完全可以将 reload 方法桥接出来提供给 js 这边调用,你可以在任何地方调用此方法更新代码。

新建一个 DevHelper
RNBridge.h

#import <Foundation/Foundation.h>
#import <React/RCTBridgeModule.h>
#import <React/RCTEventEmitter.h>
@interface DevHelper : RCTEventEmitter
@end


`DevHelper.m`
>```
#import "DevHelper.h"
@implementation  DevHelper
RCT_EXPORT_MODULE();
- (dispatch_queue_t)methodQueue{    
  return dispatch_get_main_queue();
}
RCT_EXPORT_METHOD(debugReload){    
  [(RCTRootView *)[UIApplication sharedApplication].keyWindow.rootViewController.view bridge] reload];
}

JS 端调用 NativeModules.DevHelper.debugReload()

Android

1. compile react-native from source

环境:react-native 0.55.4
fresco 1.3.0 在 png 进行 resize 时有性能问题,经 google 后,发现需要改动 fresco 源码,因此将 react-native 改为 arr 包进行引入
文件位置:
node_modules/react-native/android/com/facebook/react/react-native/0.55.4/react-native-0.55.4-sources.jar!/com/facebook/react/modules/fresco/FrescoModule.java
找到以下代码修改为:

public static ImagePipelineConfig.Builder getDefaultConfigBuilder(ReactContext context) {
HashSet requestListeners = new HashSet<>();
requestListeners.add(new SystraceRequestListener());
OkHttpClient client = OkHttpClientProvider.createClient();
// make sure to forward cookies for any requests via the okHttpClient
// so that image requests to endpoints that use cookies still work
CookieJarContainer container = (CookieJarContainer) client.cookieJar();
ForwardingCookieHandler handler = new ForwardingCookieHandler(context);
container.setCookieJar(new JavaNetCookieJar(handler));
return OkHttpImagePipelineConfigFactory
.newBuilder(context.getApplicationContext(), client)
.setNetworkFetcher(new ReactOkHttpNetworkFetcher(client))
.setDownsampleEnabled(true)
.setRequestListeners(requestListeners);
}


#### 2. Reload 方法桥接
新建一个`DevHelper`
>```
public class DevModules extends ReactContextBaseJavaModule {
    private static final String MODULES_NAME_Dev = "DevHelper" ;
    public DevModules(ReactApplicationContext reactContext) {
        super(reactContext);
    }
    @Override
    public String getName() {
        return MODULES_NAME_Dev;
    }
    @ReactMethod
    public void reload() {
        UIManagerModule uiManager = getReactApplicationContext().getNativeModule(UIManagerModule.class);
        uiManager.addUIBlock(new UIBlock() {
            @Override
            public void execute(NativeViewHierarchyManager nativeViewHierarchyManager) {
                getReactNativeHost().getReactInstanceManager()
                        .getDevSupportManager().handleReloadJS();
            }
        });
    }
    protected ReactNativeHost getReactNativeHost() {
        return  MainApplication.getMyApplication().getReactNativeHost();
    }
}

将其加到 AppReactPackage

public class AppReactPackage implements ReactPackage {
@Override
public List createNativeModules(ReactApplicationContext reactContext) {
List modules = new ArrayList<>() ;
modules.add(new DevModules(reactContext)) ;
return modules ;
}
@Override
public List createViewManagers(ReactApplicationContext reactContext) {
return Collections.emptyList();
}
}


修改`MainApplication`
>```
public class MainApplication extends Application implements ReactApplication {
  private static MainApplication instance;
  public static MainApplication getMyApplication() {
    return instance;
  }
  private final ReactNativeHost mReactNativeHost = new ReactNativeHost(this) {
    @Override
    public boolean getUseDeveloperSupport() {
      return BuildConfig.DEBUG;
    }
    @Override
    protected List getPackages() {
      return Arrays.asList(
          new MainReactPackage(), new LottiePackage(), new AppReactPackage()
      );
    }
    @Override
    protected String getJSMainModuleName() {
      return "index";
    }
  };
  @Override
  public ReactNativeHost getReactNativeHost() {
    return mReactNativeHost;
  }
  @Override
  public void onCreate() {
    super.onCreate();
    instance = this;
    SoLoader.init(this, /* native exopackage */ false);
  }
}
  • React

    React 是 Facebook 开源的一个用于构建 UI 的 JavaScript 库。

    192 引用 • 291 回帖 • 441 关注
  • iOS

    iOS 是由苹果公司开发的移动操作系统,最早于 2007 年 1 月 9 日的 Macworld 大会上公布这个系统,最初是设计给 iPhone 使用的,后来陆续套用到 iPod touch、iPad 以及 Apple TV 等产品上。iOS 与苹果的 Mac OS X 操作系统一样,属于类 Unix 的商业操作系统。

    84 引用 • 139 回帖
  • Crash
    2 引用

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...