Unity接入多个SDK的通用接口开发与资源管理(二)

本文详细介绍如何在Unity中封装Android SDK接口,包括利用_mActivity.Call调用原生方法及bugly异常上报等操作,并实现了单例管理器SDKManager。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

接着上篇,本篇对SDK接口进行封装。在开始之前,需要先了解下面知识。
(1)unity与android之间的交互
unity通过下面方式调用android中的函数:
方法一:

AndroidJavaClass jc = new AndroidJavaClass ("com.unity3d.player.UnityPlayer");
AndroidJavaObject  _mActivity = jc.GetStatic<AndroidJavaObject>("currentActivity");
_mActivity.Call("函数名");

方法二:

AndroidJavaClass jc = new AndroidJavaClass ("com.unity3d.player.UnityPlayer");//括号里可以是任意jar包的包名+类名
jc.CallStatic("函数名");

上面代码第一种先获得UnityPlayer类,UnityPlayer类是unity导出Android工程后生成的unity-classes.jar里的类。然后再获取静态变量_mActivity,_mActivity 是Activity类型,由此获得了Android当前的Activity,然后再调用此Activity中的方法。我们可以看一下unity自动生成的classes.jar中的源码:
这里写图片描述
第二种是通过包名+类名获取该类,直接调用类中的静态方法来实现的。可以是任意自定义的包名和类名。但这种就与Android的生命周期无关了。
我们可以这么理解Android应用中一个界面是一个Activity,两个界面的跳转就是两个Activity之间的跳转(类似的iOS是UIController之间的跳转)。其实我们unity游戏在Android上也是一个Android应用,所以它也是运行在一个Activity上的,这个Activity叫UnityPlayerActivity,它继承自Activity,看源码如下,每个Activity初始化的时候会首先执行onCreate()方法,所以通常把SDK的初始化函数也放在这个函数中。它就会随着Android的生命周期进行初始化,这是第一种做法,也是最常用的SDK初始化方法。还有一种SDK初始化的方法,就是自己新建一个jar包,在jar包中新建类,在类中写一些SDK初始化的静态方法,然后通过方法二在unity中调用这些方法进行初始化。我们这里采用大多数人使用的方法一,即在onCreate()中初始化。
这里写图片描述
有了上面的了解,我们开始进行unity的通用接口的开发。我们需要一个SDKManager类来管理所有调用SDK接口的方法,代码如下,把脚本挂在一个空物体上。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;

public class SDKManager : MonoBehaviour {

    private static SDKManager _instance = null;
    public static SDKManager Instance
    {
        get
        {
            return _instance;
        }
    }

    private void Awake()
    {
        if (_instance != null)
        {
            GameObject.Destroy(this.gameObject);
        }
        _instance = this;

        InitSDKManager();

        DontDestroyOnLoad(this);
    }

    private void OnDestroy()
    {
        if (_instance == this) {
            _instance = null;
        }
    }

#if UNITY_ANDROID && !UNITY_EDITOR
    private static string UNITY_CLASS = "com.unity3d.player.UnityPlayer";
    private AndroidJavaObject _mActivity;
#endif
    public void InitSDKManager()
    {
#if UNITY_ANDROID && !UNITY_EDITOR
        AndroidJavaClass jc = new AndroidJavaClass (UNITY_CLASS);
        _mActivity = jc.GetStatic<AndroidJavaObject>("currentActivity");
#endif
    }

    //信鸽SDK接口
    public void GetPushToken()
    {
#if UNITY_ANDROID && !UNITY_EDITOR
        _pushToken = _mActivity.Call<string>("GetXGPushTokenNew");
#endif
    }

    public void SetXGPushTag(string tag)
    {
#if UNITY_ANDROID && !UNITY_EDITOR
        _mActivity.Call("SetXGPushTag",tag);
#endif
    }

    public void AddLocalPushNotificationAndroid(string content, DateTime date, bool isRepeatEveryday = false)
    {
#if UNITY_ANDROID && !UNITY_EDITOR
        int isRepeat = 0;
        if (isRepeatEveryday == true)
        {
            isRepeat = 1;
        }

        _mActivity.Call("AddLocalNotification","SDK集合",content, date.ToString("yyyyMMdd"), date.ToString("HH"), date.ToString("mm"),isRepeat);
#endif
    }

    public void ClearAllLocalNotificationAndroid()
    {
#if UNITY_ANDROID && !UNITY_EDITOR
        _mActivity.Call("ClearAllLocalNotification");
#endif
    }

    //buglySDK接口
    //启动c#异常捕获上报功能
    public void buglyCatch()
    {
        Debug.Log("start Bugly report");
        BuglyAgent.EnableExceptionHandler();

    }

}

然后新建一个Test脚本挂在摄像机上,调用这些接口:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;

public class Test : MonoBehaviour
{

    void OnGUI()
    {
        if (GUILayout.Button("信鸽推送", GUILayout.Width(100.0f), GUILayout.Height(50.0f)))
        {
            DateTime noticeTime = new DateTime(2017, 11, 24, 21, 30, 30);
            SDKManager.Instance.AddLocalPushNotificationAndroid("信鸽给你的推送", noticeTime);
        }
        if (GUILayout.Button("清除本地推送", GUILayout.Width(100.0f), GUILayout.Height(50.0f)))
        {

            SDKManager.Instance.ClearAllLocalNotificationAndroid();
        }
        if (GUILayout.Button("开启Bugly异常上报", GUILayout.Width(100.0f), GUILayout.Height(50.0f)))
        {
            SDKManager.Instance.buglyCatch();
        }
    }
}

上面代码,我们新建一个SDKManaget单例类,把每个SDK的接口封装成一个函数。像信鸽这种原生的jar包中的方法,我们就用_mActivity.Call()去调用,像bugly这种提供了接口的,我们直接调用提供的接口。通用接口类就介绍到这里,下面我们来实现_mActivity.Call()中调用的Android工程里的方法。使用Android Studio(2.3.3)新建一个工程。我们的目的是做一个jar包,这个jar包作用有两点:(1)用来对接unity调用jar包里的方法。(2)对接unity导出的Android工程的生命周期。这是我们为什么选择上面第一种接入方法的原因。上面说过unity运行的Activity是UnityPlayerActivity,我们新建一个类MainActivity,继承com.unity3d.player.UnityPlayerNativeActivity,而UnityPlayerNativeActivity继承UnityPlayerActivity。然后在AndroidManifest.xml里设置MainActivity为启动的Activity,所以MainActivity就是当前unity运行的Activity。我们通过_mActivity = jc.GetStatic(“currentActivity”)获取到的就是MainActivity,然后我们在MainActivity中实现被unity调用的函数。代码:

public class MainActivity extends com.unity3d.player.UnityPlayerNativeActivity {

    private static boolean _isXGRegisterSuccess = false;
    private static String _pushToken = "";

    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        if (savedInstanceState == null)
        {
            savedInstanceState = new Bundle();
        }
        super.onCreate(savedInstanceState);
        Log.d("myGame", "MainActivity onCreate Called");

        InitBugly();
        InitXG();
    }

void InitBugly()
{
    CrashReport.initCrashReport(getApplicationContext(),"aaaaaaaa",false);
}

void InitXG(){
    XGPushConfig.enableDebug(this,false);
    MsgReceiver testReceiver = new MsgReceiver();
    IntentFilter intentFilter = new IntentFilter();
    intentFilter.addAction("com.abc.def.receiveintent");
    registerReceiver(testReceiver,intentFilter);
    XGPushManager.registerPush(this, new XGIOperateCallback() {
        @Override
        public void onSuccess(Object o, int i) {
            Log.w("XGPush","XGsuccess:"+o);
            _isXGRegisterSuccess = true;
            _pushToken = o.toString();
        }

        @Override
        public void onFail(Object o, int i, String s) {
            _isXGRegisterSuccess = false;
            Log.w("XGPush","failed:"+i+", msg:"+s);
        }
    });
}

public void AddLocalNotification(String title, String content, String date, String hour, String min, int isRepeatEveryday)
{
    if (_isXGRegisterSuccess)
    {
        XGLocalMessage msg = new XGLocalMessage();
        msg.setTitle(title);
        msg.setContent(content);
        msg.setDate(date);
        msg.setHour(hour);
        msg.setMin(min);

        int notifyIconId = getResources().getIdentifier("notify_icon", "drawable", getPackageName());
        Log.e("notify icon id",notifyIconId+"");
        msg.setSmall_icon(Integer.toString(notifyIconId));

        int _hour = Integer.parseInt(hour);
        int _min = Integer.parseInt(min);
        msg.setRing(1);

        XGPushManager.addLocalNotification(MainActivity.this,msg);
    }
}
public void ClearAllLocalNotification()
{
    Log.w("ClearAllLocalNotice","success");
    if (_isXGRegisterSuccess)
    {
        XGPushManager.clearLocalNotifications(MainActivity.this);
    }
}
}

如果需要在启动unity的Activity(即MainActivity)前做一些处理,你可以新建一个类SplashActivity继承Activity,设置SplashActivity为启动Activity,然后跳转到MainActivity。就可以在SplashActivity中做一些启动游戏前的处理。我们把上述工作做完后,就可以将这些类打包成一个jar包(AS如何打jar包,再说),导入unity导出的Android工程中就可以了。到这里通用接口的开发就完了。还剩下一项工作就是我们之前从unity中提取出来的SDK资源,我们需要添加到Android工程中,下面就介绍如何进行资源管理,把资源添加到unity导出的Android工程中。


AS打jar包,在build.gradle最后加这些代码:

task makeJar(type: Jar, dependsOn:['build']){
    archiveName = 'QuicksdkDemo.jar'     //包名
    from('build/intermediates/classes/debug/')
    destinationDir = file('build/libs')     //导出路径
    exclude('com/taiyouxi/a3k/BuildConfig.class')     //不打进包的文件
    exclude('com/taiyouxi/a3k/BuildConfig\$*.class')     //不打进包的文件
    exclude('**/R.class')     //不打进包的文件
    exclude('**/R\$*.class')     //不打进包的文件
    include('com/taiyouxi/a3k/*.class')     //需要打进包的文件
    include('com/quicksdk/unity/*.class')     //需要打进包的文件
    include('com/weibo/*.class')     //需要打进包的文件
    include('com/wxapi/*.class')     //需要打进包的文件
}
makeJar.dependsOn(build)

然后打开Terminal窗口,输入gradlew makeJar然后回车:

gradlew makeJar

打出的包在build>libs文件夹下如图:
这里写图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值