天天看点

解决 react-native报错java.lang.OutOfMemoryError: Could not allocate JNI Env

问题复现:

打包生成用rn写的apk安装在手机上之后,首次进入APP之后没问题,再次进入就闪退,接着就再也进不去了,这个问题困扰了我三四天了吧,我的这个描述能看懂吗?我是个智障吗?

报错代码:

查找了相关命令之后用adb logcat AndroidRuntime:E *:S来打印出错误,发现是内存泄露的问题。

PS G:\RN1workspace\TigerGameApp> adb logcat AndroidRuntime:E *:S
--------- beginning of system
--------- beginning of main
--------- beginning of crash
08-16 19:27:42.223 23377 29132 E AndroidRuntime: FATAL EXCEPTION: OkHttp Dispatcher
08-16 19:27:42.223 23377 29132 E AndroidRuntime: Process: com.tigergameapp, PID: 23377
08-16 19:27:42.223 23377 29132 E AndroidRuntime: java.lang.OutOfMemoryError: Could not allocate JNI Env
08-16 19:27:42.223 23377 29132 E AndroidRuntime:        at java.lang.Thread.nativeCreate(Native Method)
08-16 19:27:42.223 23377 29132 E AndroidRuntime:        at java.lang.Thread.start(Thread.java:1063)
08-16 19:27:42.223 23377 29132 E AndroidRuntime:        at java.util.concurrent.ThreadPoolExecutor.addWorker(ThreadPoolExecutor.java:921)
08-16 19:27:42.223 23377 29132 E AndroidRuntime:        at java.util.concurrent.ThreadPoolExecutor.execute(ThreadPoolExecutor.java:1339)
08-16 19:27:42.223 23377 29132 E AndroidRuntime:        at okhttp3.ConnectionPool.put(ConnectionPool.java:135)
08-16 19:27:42.223 23377 29132 E AndroidRuntime:        at okhttp3.OkHttpClient$1.put(OkHttpClient.java:149)
08-16 19:27:42.223 23377 29132 E AndroidRuntime:        at okhttp3.internal.connection.StreamAllocation.findConnection(StreamAllocation.java:188)
08-16 19:27:42.223 23377 29132 E AndroidRuntime:        at okhttp3.internal.connection.StreamAllocation.findHealthyConnection(StreamAllocation.java:129)
08-16 19:27:42.223 23377 29132 E AndroidRuntime:        at okhttp3.internal.connection.StreamAllocation.newStream(StreamAllocation.java:98)
08-16 19:27:42.223 23377 29132 E AndroidRuntime:        at okhttp3.internal.connection.ConnectInterceptor.intercept(ConnectInterceptor.java:42)
08-16 19:27:42.223 23377 29132 E AndroidRuntime:        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:92)
08-16 19:27:42.223 23377 29132 E AndroidRuntime:        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:67)
08-16 19:27:42.223 23377 29132 E AndroidRuntime:        at okhttp3.internal.cache.CacheInterceptor.intercept(CacheInterceptor.java:109)
08-16 19:27:42.223 23377 29132 E AndroidRuntime:        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:92)
08-16 19:27:42.223 23377 29132 E AndroidRuntime:        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:67)
08-16 19:27:42.223 23377 29132 E AndroidRuntime:        at okhttp3.internal.http.BridgeInterceptor.intercept(BridgeInterceptor.java:93)
08-16 19:27:42.223 23377 29132 E AndroidRuntime:        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:92)
08-16 19:27:42.223 23377 29132 E AndroidRuntime:        at okhttp3.internal.http.RetryAndFollowUpInterceptor.intercept(RetryAndFollowUpInterceptor.java:124)
08-16 19:27:42.223 23377 29132 E AndroidRuntime:        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:92)
           

解决过程:

向朋友(前端大佬)请教了之后,他定位到是定时器函数出了问题,于是我就自吸想想到底是哪块的问题,返回代码继查看,发现在设置了定时器之后并没有清除定时器,不知道啥情况,把清除定时器的代码给注释了。于是解开注释重新打包安装,发现是可以的,随之问题也就解决了。

RN中文网的解释:

我们发现很多 React Native 应用发生致命错误(闪退)是与计时器有关。具体来说,是在某个组件被卸载(unmount)之后,计时器却仍然在运行。要解决这个问题,只需铭记

在unmount组件时清除(clearTimeout/clearInterval)所有用到的定时器

即可:

import React, { Component } from "react";

export default class Hello extends Component {
  componentDidMount() {
    this.timer = setTimeout(() => {
      console.log("把一个定时器的引用挂在this上");
    }, 500);
  }
  componentWillUnmount() {
    // 请注意Un"m"ount的m是小写

    // 如果存在this.timer,则使用clearTimeout清空。
    // 如果你使用多个timer,那么用多个变量,或者用个数组来保存引用,然后逐个clear
    this.timer && clearTimeout(this.timer);
  }
}
           

继续阅读