【Unity调用原生安卓】3.总结篇 总结一般用法

目录

基础

关注原生安卓主要信息

基础语法

类和对象

返回值类型

获取字段

调用方法

仿照安卓方法

问题总结:【.】vs【$】

用法总结


基础

转自MemoryC

a. AndroidJavaClass对应着Android里面的Java类,而AndroidJavaObject对应着Android里面实例化的对象。

b. 一定要切记C#里的String和Java的String不是一码事,所以调用Android方法时如果需要传字符串为参数时,不能直接给个字符串,应该给个Java里的String,例如 new AndroidJavaObject("java.lang.String","你想传的字符串");

c. 由于AndroidJavaClass对应的是类,所以一般用之来调用对应的类的静态变量(GetStatic<Type>)或者静态方法(CallStatic<Type>("functionName",param1,param2,....));其中的Type为返回类型,注意是Java的返回类型不是C#的,一般整型和布尔型是通用的,其他的如果不清除可以统一写返回类型为AndroidJavaObject,当然没有返回类型的不需要写Type。

d. AndroidJavaObject对应的是实例对象,所以用new方法给其初始化时要注意说明其是哪个类的实例对象。再比如刚才那个例子: AndroidJavaObject javaString=new AndroidJavaObject("java.lang.String","字符串的值");

关注原生安卓主要信息

如果直接调用安卓的一些方法,最起码要要了解原生安卓怎么写的,仿照在Unity内实现

关注原生安卓主要信息:

1.原生安卓方法怎么写

2.静态、非静态

3.参数类型

4.返回值类型

基础语法

类和对象

1.AndroidJavaClass

 new AndroidJavaClass("全类名")  

---new一个Android原生类

例如:AndroidJavaClass JavaLog = new AndroidJavaClass("android.util.Log");

2. AndroidJavaObject

 new AndroidJavaObject("全类名",args1,args2,...) 

---new一个Android原生对象,后面是参数,参数类型一定要参照原生安卓

例如:new AndroidJavaObject("java.lang.String", msg);

返回值类型

调用方法和获取字段,都要注意返回值是什么类型

int,string可以直接接收,其他类用AndroidJavaObject接收

JavaLog.CallStatic<int>("i", tag, msg);

secure.CallStatic<string>("getString", contentResolver, "android_id");

返回数组例子

            AndroidJavaObject packageInfos = PackageManager.Call<AndroidJavaObject>("getInstalledPackages", 0);
            AndroidJavaObject[] packages = packageInfos.Call<AndroidJavaObject[]>("toArray");

获取字段

1.获取非静态字段

例如:string packageName = applicationInfo.Get<string>("packageName");

2.获取静态字段

例如:AndroidJavaObject activity = jo.GetStatic<AndroidJavaObject>("currentActivity")

调用方法

1.调用非静态方法

jo.Call("方法名")

jo.Call("方法名",args1,args2,...) 

例如:UnityActivity.Call("runOnUiThread", r);

2.调用静态方法

例如JavaLog.CallStatic<int>("i", tag, msg);

仿照安卓方法

以判断指定服务是否运行为例,主要用到安卓方法

        ActivityManager activityManager = (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE);
        List<ActivityManager.RunningServiceInfo> serviceList = activityManager.getRunningServices(100);

  /*安卓方法
         	public static boolean isServiceRunning(Context mContext, String className) {
		boolean isRunning = false;
		ActivityManager activityManager = (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE);
		List<ActivityManager.RunningServiceInfo> serviceList = activityManager.getRunningServices(100);
		if (!(serviceList.size() > 0)) {
			return false;
		}
		for (int i = 0; i < serviceList.size(); i++) {
			String name = serviceList.get(i).service.getClassName();
			if (name.equals(className) == true) {
				isRunning = true;
				break;
			}
		}
		return isRunning;
	    }*/
        /// <summary>
        /// 判断指定服务是否运行  测试ok
        /// </summary>
        /// <returns></returns>
        public static bool IsServiceRunning(string serviceName)
        {
            AndroidJavaClass Context = new AndroidJavaClass("android.content.Context");
            AndroidJavaObject systemServices = UnityAppContext.Call<AndroidJavaObject>("getSystemService", Context.GetStatic<AndroidJavaObject>("ACTIVITY_SERVICE"));
            AndroidJavaObject runningServiceInfos = systemServices.Call<AndroidJavaObject>("getRunningServices", 100);
            AndroidJavaObject[] runningServices = runningServiceInfos.Call<AndroidJavaObject[]>("toArray");
            //AndroidLog("Running service Length:" + runningServices.Length);
            for (int i = 0; i < runningServices.Length; i++)
            {
                AndroidJavaObject sName = runningServices[i].Get<AndroidJavaObject>("service").Call<AndroidJavaObject>("getClassName");

                AndroidLog(sName.ToCString());
                if (sName.ToCString() == serviceName)
                {
                    return true;
                }
            }
            return false;
        }

问题总结:【.】vs【$】

android.os.Build.VERSION将意味着要到一个叫VERSIONBuild包中的类,

android.os.Build$VERSION将意味着进入一个内部类Versionos

android.os.Build$VERSION本身是一个内部类,因此必须追加$让JRE使用点标志来确定包与内在的阶级。

参考 http://cn.voidcc.com/question/p-nulzoglo-uz.html

用法总结

总结其中的功能是:
Unity提供的主要几个接口分别为:
AndroidJavaClass 类
AndroidJavaObject 对象
AndroidJavaRunnable Unity对java.lang.Runnable object的实现
AndroidJavaProxy 接口,用于实现任何java接口;通过invoke调用接口中的方法
AndroidJavaException 继承于Exception的android异常类

有这几个东西,就可以调用实现Android中的任何方法,创建任何类,实现任何功能了。可以丢弃UnityPlayer.UnitySendMessage(GameObject, functionName,params);方法向Unity端发送message了。


需要注意的几个东西:
1.Android的命名规则,函数名都是首字母小写的;onClick(),不是OnClick()方法
2.对于interface,返回的interface只是实现了interface方法的Class, 所以,用AndroidJavaObject接收返回的interface实例
3.在Unity中,所有调用Android UI相关的东西,都要通过activity.runOnUiThead,在UI线程中调用
4.Unity中,实现Android接口,继承AndroidJavaProxy方法,构造方法要实现继承的java接口;其中,java中的接口,直接在继承的类中写(因为AndroidJavaProxy用Invoke的方式调用方法,类似于反射,只需要知道方法名和参数就可以了,并不需要知道这个方法是不是override的)
5.如果调用的方法在logcat中报错,可以查看报错内容,其中需要调用的名称或者接口方法,需要的返回类型都会在错误中:
找不到CycClickListner.onClick(AndroidJavaObject,Int32)方法,其中标明了需要的方法是onClick,方法需要的参数类型分别为AndroidJavaObjec和Int32


非本作者同意,请勿转载

我也是刚学习,不足之处请指出

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Jack Yan

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值