android studio 打包.jar到unity调用

最近接入讯飞语音到unity工程里,是需要把.jar接入到unity中 遇到了一些坑 在此分享给大家 希望大家少走弯路

如果有什么问题 欢迎留言讨论qq:1902649397

网上看了很多例子 有点小细节没有注意就会导致 导出apk包不能使用

我用AndroidStudio导出jar

环境:AndroidStudio3.0 + Unity2017.2

这两个的安装就不在这里讨论了 网上的教程很多了

大概步骤分以下几步:

(1)、创建AndroidStudio工程

(2)、生成.jar

(3)、导入Unity工程(Assets/Plugins/Android/)注意一定要在Android文件夹下

(4)、导出apk包

1、创建AndroidStudio工程

设置好 名称 、 路径 、 包名

这里的 Package name 只是这个 Android Studio 工程的包名,而我们需要的并不是这个工程(默认会有一个app工程),

我们后面会在这个工程内新建一个 Android Library 类库,这个类库才是我们要导出 Jar 的对象。所以,这个 Android Studio 工程的 Application name 、Company Domain 、Package name 这三个参数可以随意填写,并不需要与正式工程相同。

选择 SDK 版本

这里的意思是选择一个可兼容的最低的 Android 系统版本。自行选择,随意。

选择 Empty Activity

直接选择空的 Activity 就可以了,因为这个是本工程的 Activity,并不是我们要导出的 Jar 的 Activity。

给此 Activity 定义参数(ActivityName 是里面最开始的一个.java)直接点Finish

因为这个是本工程的 Activity,并不是我们要导出的 Jar 的 Activity。所以随意填写,和要导出的 Jar 无关。

 建好的工程是这样的

我们需要重新 新建一个 Module

选择 Android Library

输入 Module 的参数
这里的参数就是要导出 jar 的 Android Library 类库参数。Package name 与正式工程一致。 Application/Library name 就是就填你要导出的 jar 插件的名称。Module name 自动填写就不用管了。点Finish

新建好之后是这样的

向Module中引入Unity的classes.jar

因为这里需要继承自unity中的类  在unity的安装目录下找到classes.jar

Unity\Editor\Data\PlaybackEngines\AndroidPlayer\Variations\mono\Release\Classes\classes.jar

放到这个 Module 的 libs 中  (这里要用那个版本的unity打包就放那个版本的unity中的classes.jar文件)

 

把加入的classes.jar加入依赖 到该Module  不然不能引用到

加入后是这样的

给 Module 添加 Activity Class

Name 随便输入一个 这个 Name以后要用到   可以占时跟我的一样 MyActivity   点ok

然后 写 刚才创建的类

package com.zwx.mytestjar;
import android.app.AlertDialog;
import android.content.Intent;
import com.unity3d.player.UnityPlayerActivity;
/**
 * Created by Administrator on 2018/4/13.
 */
public class MyActivity extends UnityPlayerActivity {
    public void showDialog(final String mTitle, final String mContent) {
        runOnUiThread(new Runnable() {
 
            @Override
            public void run() {
                AlertDialog.Builder mBuilder = new AlertDialog.Builder(MyActivity.this);
                mBuilder.setTitle(mTitle)
                        .setMessage(mContent)
                        .setPositiveButton("确定", null);
                mBuilder.show();
            }
        });
    }
 
    //创建一个分享
    public void shareText(String subject, String body) {
        Intent sharingIntent = new Intent(android.content.Intent.ACTION_SEND);//创建一个分享
        sharingIntent.setType("text/plain");
        sharingIntent.putExtra(android.content.Intent.EXTRA_SUBJECT, subject);//设置分享类型
        sharingIntent.putExtra(android.content.Intent.EXTRA_TEXT, body);//设置分享内容
        startActivity(Intent.createChooser(sharingIntent, "Share via"));//分享标题
    }
    
    public int GetAdd(int numA,int numB) {
        return (numA + numB);
    }
}

然后修改 build.gradle    双击 build.gradle,修改代码,注意修改的是自己新建的 Library 的build.gradle,不是整个 project 的 build.gradle

在 build.gradle 末尾添加以下代码,表示添加了一个 Task 任务(这个是修改生成.jar后 复制到一个指定路径下)

apply plugin: 'com.android.library'
 
android {
    compileSdkVersion 26
 
 
 
    defaultConfig {
        minSdkVersion 15
        targetSdkVersion 26
        versionCode 1
        versionName "1.0"
 
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
 
    }
 
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
 
}
 
dependencies {
    implementation fileTree(include: ['*.jar'], dir: 'libs')
    implementation 'com.android.support:appcompat-v7:26.1.0'
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'com.android.support.test:runner:1.0.1'
    androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.1'
    implementation files('libs/classes.jar')
}
//task to delete the old jar(删除之前的.jar)
task deleteOldJar(type: Delete) {
    delete 'release/AndroidPlugin.jar'
}
 
//task to export contents as jar(拷贝到指定目录 并修改名)
task exportJar(type: Copy) {
    from('build/intermediates/bundles/release/')
    into('release/')
    include('classes.jar')
    ///Rename the jar
    rename('classes.jar', 'AndroidPlugin.jar')
}
 
exportJar.dependsOn(deleteOldJar, build)

在AndroidStudio 右侧 上边 点击Gradle 标签

刷新gradle,一般情况下修改了build.gradle后,系统上方会让你SyncNow,还可以手动刷新一下,右侧点击Gradle标签,选中自己的Library,右击选择Refresh external project

然后就可以导出 .jar文件了 找到other下的exportJar,并双击,等待完成 

或者在

 

Terminal中输入gradlew makejar

第一次运行Androidstudio可能会更新gradle,20-30分钟,更新完会自动打jar包

 

然后就可以在 release 目录下面找到生成好的 jar 包了,右击这个 jar 包选择 Show in Explorer 就可以拿到这个 jar 包了。

/***下面是把.jar导入到Unity中  并在unity中创建 AndroidManifest.xml ****/

(Assets/Plugins/Android/)注意.jar 和 AndroidManifest.xml 一定 要在Android目录下

(重要,请仔细阅读,真正理解 AndroidManifest 才是最快的方式)如果你是新工程,没有使用过其他 android 的 sdk(指的是 unity 的插件),应该是没有AndroidManifest.xml文件的,这样可以在 Asset/Plugins/Android/ 目录下新建一个 AndroidManifest.xml。

先介绍新加一个 AndroidManifest.xml

 

需要注意 的就是主 activity 的 android:name 需要为 用于导出 的  jar 的主类名

包名 package="com.zwx.mytestjar"

包名也和unity中的一致

这个包名,其实也就是 unity 工程 Player Settings 中填写的包名,因为他们需要一致

不一致都会导致报错 导致apk不能正常运行(闪退)

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.zwx.mytestjar">
  <application
    android:allowBackup="true"
    android:label="@string/app_name"
    android:supportsRtl="true">
    <!-- android:name= 后的这个名字必须与Android 中.jar写的类名一致 -->
    <activity android:name=".MyActivity"
              android:label="@string/app_name">
      <intent-filter>
        <action android:name="android.intent.action.MAIN" />


        <category android:name="android.intent.category.LAUNCHER" />
      </intent-filter>
    </activity>
  </application>

</manifest>

然后在unity中创建一个button 一个Text

再创建一个脚本  挂到Canvas上

using UnityEngine;
using UnityEngine.UI;


public class Demo : MonoBehaviour
{


    public Text getText;
    private AndroidJavaClass unity;
    private string subject = "WORD-O-MAZE";
    private string body = "PLAY THIS AWESOME. GET IT ON THE PLAYSTORE 这是要分享的内容";
    public Button[] btns;


    void Awake()
    {
        
    }


    void Start()
    {
        btns = GetComponentsInChildren<Button>();
        for (int i = 0; i < btns.Length; i++)
        {
            Button btn = btns[i];
            btn.onClick.AddListener(delegate
            {
                OnBtnClick(btn.gameObject);
            });
        } 
        if (unity == null)
        {
            unity = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
        }
    }


    void OnBtnClick(GameObject go)
    {
        switch (go.name)
        {
            case "BtnShowDialog":
                CallShowDialog();
                break;
            case "BtnShareText":
                CallShareText();
                break;
            case "BtnSetVibrator":
                CallSetVibrator();
                break;
            case "GetAddBtn":
                GetAdd();
                break;
        }
    }


    private void CallShowDialog()
    {
        AndroidJavaObject currentActivity = unity.GetStatic<AndroidJavaObject>("currentActivity");
        currentActivity.Call("showDialog", "this is my title", "this is my content");
    }


    private void CallShareText()
    {
        AndroidJavaObject currentActivity = unity.GetStatic<AndroidJavaObject>("currentActivity");
        currentActivity.Call("shareText", subject, body);
    }
    private void CallSetVibrator()
    {
        AndroidJavaObject currentActivity = unity.GetStatic<AndroidJavaObject>("currentActivity");
        currentActivity.Call("setVibrator");
    }
    private void GetAdd()
    {
        AndroidJavaObject currentActivity = unity.GetStatic<AndroidJavaObject>("currentActivity");
        int a = currentActivity.Call<int>("GetAdd",2,5);
        getText.text = a.ToString();
    }

// Update is called once per frame
    void Update()
    {


        if (Input.GetKeyDown(KeyCode.Escape) || Input.GetKeyDown(KeyCode.Home))
        {
            Application.Quit();
        }


}


}

然后就可以用unity导出apk了

注意unity中的包名要跟这个.jar的一致 

com.zwx.mytestjar

然后把apk安装到手机上运行

点击button前后  由于参数传的 是2 , 5  所以返回 7 是正确的

/********下面介绍一下AndroidManifest.xml  主要参考来自    我会把我的unity工程上传上去便于大家参考*****/

http://gad.qq.com/article/detail/29260

https://www.2cto.com/kf/201608/542437.html

 

资源地址:

https://download.csdn.net/download/unity_http/10347228

修改 AndroidManifest.xml

如果你之前的工程有使用过其他的 Android 的 SDK(指的是 unity 的插件),那么在 Asset/Plugins/Android/ 目录下应该已经有一个 AndroidManifest.xml,那么你就需要将这次导出的 jar 的 activity 添加到这个 AndroidManifest.xml 中进行注册。

一个 AndroidManifest.xml 只有一个主 activity (直接的观察就是这个 activity 标签中包含了下面这段标签)。

<intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
      </intent-filter>

 

(这里需要强调一下,本文是基于 unity 的 Android 平台的)
而 unity 工程,需要将继承了 UnityPlayerActivity 或者 UnityNativePlayerActivity 的 Activity (见上面第9步)为启动 Activity ,才可以在 Android 平台(说白了就是手机等等)启动你的 unity 工程。而这个 “设置为启动 Activity ” 的步骤,就是在 AndroidManifest.xml 中完成的,也就是在 AndroidManifest.xml 中将这个 Activity 注册为主 Activity 。

还有,你在 unity 中做的所有东西,发布到 Android 上,就只有一个 Activity,你如果在 unity 中唤起了其他的 Activity,就会像手机后台切应用一样的切换到你唤起的这个 Activity。所以,进行 unity 的 android 插件开发,只有一个入口,也就是继承 UnityPlayerActivity 或者 UnityNativePlayerActivity (UnityNativePlayerActivity 其实就是继承UnityPlayerActivity 的一个类,并没有进行任何操作)。

理解了这些之后,就能理解为什么一般的 unity 插件,并不会将自己的 Activity 注册成主 Activity,所以你只需要将他们的 Activity 标签复制粘贴到你的 AndroidManifest.xml(Asset/Plugins/Android/ 目录下,一个工程只需要一个 AndroidManifest.xml(多个的用法本文不涉及,你只需要知道,Asset/Plugins/Android/ 目录下仅有一个 AndroidManifest.xml 文件))中就可以了(如果他们的 Activity 标签有上面提到的 “intent-filter” 标签 也就是被标记成主 Activity,你就要考虑,他们的功能是需要在 unity 的这个主 Activity 启动就响应的,还是切换另外一个 Activity 才进行操作的)。

所以,综上,如果是你自行开发的多个 unity Android 插件(jar),就需要尽量先在 Android 层合并成一个 jar 插件包,以保证只有一个入口,一个主 Activity 。不光是自行开发的,使用其他 sdk 的时候,也要想,如果可以直接在 Android 层进行合并操作(统一一个 Activity 入口,然后所有调用其他 sdk 功能的接口全部放在这个 Activity 中)的,就尽量在 Android 层进行。

多个 unity Android 插件(jar)合并的时候,难的部分其实也不难,就是理解他们的功能,然后合并 AndroidManifest.xml 的操作。

如果你需要唤起其他的 Activity,就在上方第二行,将 "currentActivity" 改成你在 AndroidManifest.xml 中注册的 Activity 名字,然后就可以通过 AndroidJavaObject.Call 的方式调用那个 Activity 类里的接口。如果这个接口在这个 Activity 类里被标记成了 static,还可以通过AndroidJavaObject.CallStatic 的方式调用。

第一行的 "com.unity3d.player.UnityPlayer" 是需要调用的接口所在的 Activity 所在的包名,如果是 unity 主 Activity ,就可以直接使用 "com.unity3d.player.UnityPlayer",如果是其他插件包,就使用那个包的包名。

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值