如何理解AndroidJavaProxy?

先上一个官网的实例, 直接在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表现为一个接口





转自茶向:http://blog.csdn.net/sgnyyy/article/details/53048552

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值