先上一个官网的实例, 直接在Unity中既可以运行
https://blog.csdn.net/yanchezuo/article/details/52261944
1. 官网例子说明:
using UnityEngine;
using System;
class ExampleClass : MonoBehaviour
{
private static DateTime selectedDate = DateTime.Now;
class DateCallback : AndroidJavaProxy
{
public DateCallback() : base("android.app.DatePickerDialog$OnDateSetListener") { }
void onDateSet(AndroidJavaObject view, int year, int monthOfYear, int dayOfMonth)
{
selectedDate = new DateTime(year, monthOfYear+1, dayOfMonth);
}
}
void OnGUI ()
{
if (GUI.Button(new Rect (15, 15, 450, 75), string.Format("{0:yyyy-MM-dd}", selectedDate)))
{
AndroidJavaObject activity = new AndroidJavaClass("com.unity3d.player.UnityPlayer").GetStatic<AndroidJavaObject>("currentActivity");
activity.Call("runOnUiThread", new AndroidJavaRunnable(() =>
{
new AndroidJavaObject("android.app.DatePickerDialog", activity, new DateCallback(), selectedDate.Year, selectedDate.Month-1, selectedDate.Day).Call("show");
}));
}
}
}
此例子就是显示一个时间选择器,当在手机上操作选择时间之后,onDateSet就会被当成DatePickerDialog的当成一个监听器的回调函数被调用,从而的OnGUI得日期被改变。
核心:在此的核心是只要继承了android的某一个接口Interface,android里面定义接口,在Unity中实现这个接口,并继承于AndroidJavaProxy。 然后在android中就可以以多态的形式被调用,调用之后,就会调用到C# 的代码,然后就可以实现我们想要的与Unity与Android的回调。
上面的例子的Android实现, 在此在C#中实现的类就是继承于OnDateSetListener, 而对应的如果要写Android代码,是这么写,也就相当于我们在C#中实现了OnDateSetListener
new DatePickerDialog(MainActivity.this,
// 绑定监听器
new DatePickerDialog.OnDateSetListener() {
@Override
public void onDateSet(DatePicker view, int year,
int monthOfYear, int dayOfMonth) {
TextView show = (TextView) findViewById(R.id.txt1);
show.setText("您选择了:" + year + "年" + monthOfYear
+ "月" + dayOfMonth + "日");
}
}
// 设置初始日期
, c.get(Calendar.YEAR), c.get(Calendar.MONTH), c
.get(Calendar.DAY_OF_MONTH)).show();
翻阅Android的源码,可以看到OnDateSetListener就是一个android的接口,而对于AndroidJavaProxy,就是要在Unity实现这个接口,再传入Android就可以实现回调
public static abstract interface OnDateSetListener
{
public abstract void onDateSet(DatePicker paramDatePicker, int paramInt1, int paramInt2, int paramInt3);
}
2. 实例展示
下面我们完全自己从Android并实现一个在Android中调用Unity的回调方法
先看Android部分,至少我们要先定义一个接口
public interface ExActivityListener
{
public void onRestart();
public void onStart();
public void onResume();
public void onPause();
public void onStop();
public void onActivityResult(int requestCode, int resultCode, Intent data);
}
然后在UnityActivity中添加一个方法,这个方法用于接收Unity关于上面接口的实现, 核心函数就是setListener和传递的参数,多态形式,这个会在Unity端传入
public class MainActivity extends UnityPlayerActivity {
private ExActivityListener listener;
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
}
public void setListener(ExActivityListener listener)
{
Log.v("Unity", "setListener(1)!------------");
this.listener = listener;
}
@Override
public void onRestart()
{
Log.v("Unity", "onRestart!------------");
super.onRestart();
if(listener != null) listener.onRestart();
}
@Override
public void onStart()
{
super.onStart();
if(listener != null) listener.onStart();
}
@Override
public void onResume()
{
super.onResume();
if(listener != null) listener.onResume();
}
@Override
public void onPause()
{
super.onPause();
if(listener != null) listener.onPause();
}
@Override
public void onStop()
{
if(listener != null) listener.onStop();
super.onStop();
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data)
{
if(listener != null) listener.onActivityResult(requestCode, resultCode, data);
}
剩下就是看Unity端,需要先实现这个接口,这样才可能产生回调
using UnityEngine;
using System.Collections;
public class Hoge : MonoBehaviour
{
public class ActivityListener : AndroidJavaProxy
{
public ActivityListener() : base("com.baofeng.test.ExActivityListener")
{
}
public void onRestart()
{
UnityEngine.Debug.LogError("Back to Unity onRestart");
}
public void onStart()
{
UnityEngine.Debug.LogError("Back to Unity onStart");
}
public void onResume()
{
UnityEngine.Debug.LogError("Back to Unity onResume");
}
public void onPause()
{
UnityEngine.Debug.LogError("Back to Unity onPause");
}
public void onStop()
{
UnityEngine.Debug.LogError("Back to Unity onStop");
}
public void onActivityResult(int requestCode, int resultCode, AndroidJavaObject data)
{
UnityEngine.Debug.LogError("onActivityResult");
}
}
void Awake()
{
AndroidJavaObject activity = new AndroidJavaClass("com.unity3d.player.UnityPlayer").GetStatic<AndroidJavaObject>("currentActivity");
activity.Call("setListener", new ActivityListener());
UnityEngine.Debug.LogError("Awake");
}
}
然后一定要注意的是AndroidManifest也要放入到Unity工程,否则可能会报找不到类的错误
总结: 就是Android定义一个接口,在Unity中实现,再次传入到Android中,在Android中就可以调用这个Unity中的类,在Android表现为一个接口