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

如何实现Android不同包类数据传输,Unity插件传值到主包并解决广播空指针

错误根因

你不能通过new BroadcastSender()的方式创建Activity实例,安卓的Activity是系统管理的组件,手动new出来的实例没有绑定系统上下文Context,调用需要Context的sendBroadcast方法时就会触发空指针异常。你最初用Intent.ACTION_SEND的方案也不对,这个Action是用来调用系统分享功能的,不适合同应用内跨模块传值。


修复方案(广播实现)

步骤1:修改MyPlugin类,移除手动创建Activity的逻辑,改为持有外部传入的Context

不需要单独的BroadcastSender类,直接在MyPlugin里处理广播发送逻辑即可:

package com.example.unity;

import android.content.Context;
import android.content.Intent;
import android.util.Log;

public class MyPlugin {
    private static final MyPlugin ourInstance = new MyPlugin();
    private static final String LOGTAG = "AltGras";
    private Context hostContext;
    public float surfaceArea ;

    public static MyPlugin getInstance() { return ourInstance; }

    private MyPlugin() {
        Log.i(LOGTAG, "Created MyPlugin");
    }

    // 新增初始化方法,传入宿主上下文
    public void init(Context context) {
        // 用Application级Context避免内存泄漏
        this.hostContext = context.getApplicationContext();
    }

    public void printText(float num)
    {
        surfaceArea = num;
        Log.d(LOGTAG, "printText: Text from Unity: "+num);
        // 直接发送自定义广播
        Intent intent = new Intent();
        intent.setAction("com.alternativegrass.alternativegrassapp.CUSTOM_SENDDATA_INTENT");
        intent.putExtra("com.alternativegrass.alternativegrassapp.EXTRA_SURFACEAREA", num);
        hostContext.sendBroadcast(intent);
    }
}

步骤2:在主包初始化MyPlugin

首先确保app模块的build.gradle中已经添加了对unityLibrary模块的依赖,之后在启动Unity的主Activity的onCreate方法中初始化MyPlugin:

// com.company.package1包下的主Activity
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    // ...其他初始化逻辑
    MyPlugin.getInstance().init(this);
}

步骤3:在主包需要接收数据的类中注册广播接收器

比如要接收值的Activity中注册接收器:

private BroadcastReceiver dataReceiver = new BroadcastReceiver() {
    @Override
    public void onReceive(Context context, Intent intent) {
        float surfaceArea = intent.getFloatExtra("com.alternativegrass.alternativegrassapp.EXTRA_SURFACEAREA", 0f);
        // 此处处理拿到的float值即可
        Log.d("ReceiveUnityData", "拿到的值为:" + surfaceArea);
    }
};

@Override
protected void onStart() {
    super.onStart();
    // 注册接收器,监听自定义广播Action
    IntentFilter filter = new IntentFilter("com.alternativegrass.alternativegrassapp.CUSTOM_SENDDATA_INTENT");
    registerReceiver(dataReceiver, filter);
}

@Override
protected void onStop() {
    super.onStop();
    // 页面销毁时注销接收器,避免内存泄漏
    unregisterReceiver(dataReceiver);
}

可选更高效方案:接口回调

同应用内跨模块传值更推荐用接口回调,没有广播的通信开销,逻辑更直接:

  1. 在unityLibrary模块中定义回调接口:
package com.example.unity;

public interface UnityDataCallback {
    void onReceiveSurfaceArea(float value);
}
  1. MyPlugin中添加回调设置方法:
private UnityDataCallback callback;
public void setDataCallback(UnityDataCallback callback) {
    this.callback = callback;
}

// printText方法修改为
public void printText(float num) {
    surfaceArea = num;
    if (callback != null) {
        callback.onReceiveSurfaceArea(num);
    }
}
  1. 主包需要接收值的类直接实现接口设置即可:
MyPlugin.getInstance().setDataCallback(value -> {
    // 直接处理拿到的float值
});

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.12 03:30:03