You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React Native集成Android原生组件构建失败:空对象引用错误求助

React Native集成Android原生组件空指针问题修复方案

我是React Native新手,按官方文档集成Android原生组件后,应用无法构建,报错:Attempt to invoke interface method 'int java.util.List.size()' on a null object reference。原项目未修改时可在Pixel 4a正常运行,排查多日无果,以下是代码及修复建议。


核心错误原因

报错源于某个List对象为null时被调用了size()方法,结合代码排查,主要问题出在MyPackage的createNativeModules方法返回null,此外还有多处潜在空指针风险。


修复步骤

1. 修复MyPackage的createNativeModules方法

React Native要求该方法必须返回List对象(即使是空列表),返回null会触发框架调用size()时的空指针:

package com.testapp;

import androidx.annotation.NonNull;

import com.facebook.react.ReactPackage;
import com.facebook.react.bridge.NativeModule;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.uimanager.ViewManager;

import java.util.ArrayList;
import java.util.List;

public class MyPackage implements ReactPackage {

    @NonNull
    @Override
    public List<NativeModule> createNativeModules(@NonNull ReactApplicationContext reactApplicationContext) {
        // 返回空列表而非null
        return new ArrayList<>();
    }

    @Override
    public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) {
        List<ViewManager> VM = new ArrayList<>();
        VM.add(new MyViewManager(reactContext));
        return VM;
    }
}

2. 给MyViewManager的receiveCommand添加参数非空判断

JS传递的args可能为null,直接调用args.getInt(0)会触发空指针:

@Override
public void receiveCommand(
        @NonNull FrameLayout root,
        String commandId,
        @Nullable ReadableArray args
) {
    super.receiveCommand(root, commandId, args);
    // 添加args非空判断
    if (args == null || args.size() == 0) {
        return;
    }
    int reactNativeViewId = args.getInt(0);
    int commandIdInt = Integer.parseInt(commandId);

    switch (commandIdInt) {
        case COMMAND_CREATE:
            createFragment(root, reactNativeViewId);
            break;
        default: {}
    }
}

3. 初始化propWidth和propHeight的默认值

未设置style时,这两个变量默认值为0,可能导致布局异常:

public class MyViewManager extends ViewGroupManager<FrameLayout> {
    public static final String REACT_CLASS = "MyViewManager";
    public final int COMMAND_CREATE = 1;
    // 初始化默认宽高,避免measure时用0
    private int propWidth = 200;
    private int propHeight = 200;

    // 其他代码不变...
}

4. 在createFragment中添加非空判断

parentView和activity可能为null,需提前判断避免崩溃:

public void createFragment(FrameLayout root, int reactNativeViewId) {
    ViewGroup parentView = (ViewGroup) root.findViewById(reactNativeViewId);
    // 检查parentView是否存在
    if (parentView == null) {
        return;
    }
    setupLayout(parentView);

    FragmentActivity activity = (FragmentActivity) reactContext.getCurrentActivity();
    // 检查activity是否有效
    if (activity == null) {
        return;
    }
    final MyFragment myFragment = new MyFragment();
    activity.getSupportFragmentManager()
            .beginTransaction()
            .replace(reactNativeViewId, myFragment, String.valueOf(reactNativeViewId))
            .commit();
}

5. 优化setupLayout的回调逻辑

原代码中Choreographer的回调会无限执行,导致性能问题,改为只执行一次:

public void setupLayout(View view) {
    Choreographer.FrameCallback callback = new Choreographer.FrameCallback() {
        @Override
        public void doFrame(long frameTimeNanos) {
            manuallyLayoutChildren(view);
            view.getViewTreeObserver().dispatchOnGlobalLayout();
            // 执行后移除回调
            Choreographer.getInstance().removeFrameCallback(this);
        }
    };
    Choreographer.getInstance().postFrameCallback(callback);
}

内容的提问来源于stack exchange,提问作者Shrini

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.10 07:34:55