Unity调用Android示例

2020-09-10  本文已影响0人  yiangdea

Android, java to class接口示例

包名和类名可以随意起,unity端只要知道其名称即可,但请不要轻易更改(反射要写死在代码里)

主接口

package com.yicheng.serviceandroid;

public class UnityToAndroid {
  private static final UnityToAndroid ourInstance = new UnityToAndroid();
  public static UnityToAndroid getInstance() {
        return ourInstance;
   }
  private UnityToAndroid() {
  }
  
  private LoginCallback loginCall;
  public void LoginUser(String userName, String passWord, LoginCallback handler) {
        loginCall = handler;
        // 在需要给unity回调的时候,调用loginCall的方法,比如:
        // loginCall.statusCallback(msg.what, message);
  }
  
 // 特殊参数Context传递
  public int initWithProjectType(int projectType, long uid, Context context, String logPath) {
        
        return 0;
    }
}

interface定义

package com.yicheng.serviceandroid;

public interface LoginCallback {
    public void statusCallback(int res, String message);
    public void loginInfoCallback(String credit, String passport, String yyid);
}

Android JNI接口示例

CPP文件

#include <jni.h>
#include <string>
#include <android/log.h>
#include <android/native_window_jni.h>
#include <EGL/egl.h>
#include <GLES2/gl2.h>
#include <string.h>
#include<stdio.h>
#include<pthread.h>

#define LOGD(...) __android_log_print(ANDROID_LOG_WARN,"yuvLibNative",__VA_ARGS__)

struct VideoFrameData
{
    uint64_t uid;
    bool yuv;
    int width;
    int height;
    int yStride;
    int uvStride;
    int uvWidth;
    int uvHeight;

    char* yBuffer;
    char* uBuffer;
    char* vBuffer;

    int rotation;
};

typedef void (*FrameBack)(VideoFrameData data);


FrameBack frameBack = 0;

JavaVM *local_jvm = NULL;
jobject local_object = NULL;

jmethodID notifyVideo;

// java调用
extern "C"
JNIEXPORT void JNICALL
Java_com_nextedu_serviceandroid_UnityToAndroid_updateFrame(JNIEnv *env,
        jobject thiz,jbyteArray byteArray, jint nWidth, jint nHeight, jlong nFlag, jint dataType) {
     if (local_jvm == NULL){
        env->GetJavaVM(&local_jvm); //保存到全局变量JVM中
        local_object = env->NewGlobalRef(thiz); /* 创建对象的本地变量 */
     }
    // 视频,nFlag为0的时候代表本地视频,不然为uid
    jbyte *byte = env->GetByteArrayElements(byteArray, 0);
    int len_arr = env->GetArrayLength(byteArray);
    int width = (int)nWidth;
    int height = (int)nHeight;
    if ( frameBack != 0 ){
        VideoFrameData data;
        data.yBuffer = (char *)byte;
        data.uBuffer = (char *)(byte + width * height);
        data.vBuffer = (char *)(byte + width * height + width * height / 4);

        data.rotation = 0;
        data.uid = (uint64_t)nFlag;
        // datatype  其中0代表I420声网返回的数据格式 。 1代表NV21yy返回的数据格式
        if (dataType == 0) {
            data.yuv = true;
        } else {
            data.yuv = false;
        }
        data.width = width;
        data.height = height;
        data.uvWidth = width/2;
        data.uvHeight = height/2;
        data.yStride = width;
        data.uvStride = width/2;
        //LOGD("updateFrameuid: %llu ", data.uid);
        //LOGD("updateFramewidth: %d ", data.width);
        //LOGD("updateFrameheight: %d ", data.height);
        frameBack(data);
    }
    env->ReleaseByteArrayElements(byteArray,byte,0);
}
// C# 调用
extern "C"  {

        void LibOnCaptureVideoFrame(FrameBack cb){
            frameBack = cb;
        }

        void NotifyVideoFrameDraw(long remoteUid, long renderTimeMs){
            JNIEnv *env;
            jclass clz;
            jmethodID mid;
            if(local_jvm->AttachCurrentThread(&env, NULL) != JNI_OK)
            {
                LOGD("%s: AttachCurrentThread() failed", __FUNCTION__);
                return;
            }
            clz = env->GetObjectClass(local_object);
            if(clz == NULL)
            {
                LOGD("FindClass() Error...");
                return;
            }
            mid = env->GetMethodID(clz, "notifyVideoFrameDraw", "(JJ)V");
            if (mid == NULL)
            {
                LOGD("GetMethodID() Error...");
                return;
            }
            env->CallVoidMethod(local_object, mid , remoteUid, renderTimeMs);
        }
}

C#示例

/// <summary>
    /// 视频帧数据
    /// </summary>
    /// <param name="MediaFrameBack"></param>
    [DllImport("libnative")]
    public static extern void LibOnCaptureVideoFrame(MediaFrameBack onVidoeFrameData);

    /// <summary>
    /// 渲染后,调用sdk返回结果
    /// </summary>
    /// <param name="remoteUid"></param>
    /// <param name="renderTimeMs"></param>
    [DllImport("libnative")]
    public static extern void NotifyVideoFrameDraw(long remoteUid, long renderTimeMs);

调用流程:

java -> jni -> C#

上一篇 下一篇

猜你喜欢

热点阅读