您的位置:首页 > 移动开发 > Android开发

如何理解AndroidJavaProxy?

2016-11-06 00:52 295 查看
先上一个官网的实例, 直接在Unity中既可以运行

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表现为一个接口

转自茶向:http://blog.csdn.net/sgnyyy/article/details/53048552
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: