{"id":272,"date":"2022-04-23T23:19:44","date_gmt":"2022-04-23T15:19:44","guid":{"rendered":"https:\/\/www.osvlabs.com\/blog\/?p=272"},"modified":"2022-04-28T21:58:46","modified_gmt":"2022-04-28T13:58:46","slug":"unity2020-1-android%e6%8f%92%e4%bb%b6%e5%88%b6%e4%bd%9c","status":"publish","type":"post","link":"https:\/\/blog.osvlabs.com\/?p=272","title":{"rendered":"Unity2020.1  Android\u63d2\u4ef6\u5236\u4f5c"},"content":{"rendered":"<h1>Unity2020.1  Android\u63d2\u4ef6\u5236\u4f5c<\/h1>\n<blockquote>\n<p>\u4e4b\u524d\u5199\u63d2\u4ef6\u7684\u65f6\u5019\u641c\u7d22\u4e86\u5927\u91cf\u8d44\u6599\uff0c\u6709\u4e9b\u56e0\u4e3a\u7248\u672c\u95ee\u9898\u8fc7\u65f6\uff0c\u6709\u4e9b\u6839\u672c\u5c31\u662f\u9519\u7684\uff0c\u6240\u4ee5\u8bb0\u5f55\u4e0b\u4eb2\u6d4b\u7684\u6b65\u9aa4<\/p>\n<\/blockquote>\n<ul>\n<li>\n<p><a href=\"https:\/\/www.codenong.com\/cs106683617\/\">\u4fee\u6539 unity\u8bbe\u7f6e<\/a><\/p>\n<ol>\n<li>\n<p>\u6587\u4ef6\u2192\u751f\u6210\u914d\u7f6e\u2192Android\u2192\u5bfc\u51fa\u9879\u76ee<\/p>\n<p><img src=\"https:\/\/raw.githubusercontent.com\/Attiv\/tubed\/master\/Untitled.png\" alt=\"https:\/\/raw.githubusercontent.com\/Attiv\/tubed\/master\/Untitled.png\" \/><\/p>\n<\/li>\n<li>\n<p>\u57fa\u4e8e 1 \u7684\u9875\u9762\uff0c\u70b9\u51fb\u5de6\u4e0b\u89d2\u300c\u73a9\u5bb6\u8bbe\u7f6e\u300d\u2192\u5176\u4ed6\u8bbe\u7f6e\u2192\u914d\u7f6e\u2192\u811a\u672c\u540e\u7aef\u2192IL2CPP\uff0c\u76ee\u6807\u67b6\u6784\u2192ARMv7, ARM64<\/p>\n<\/li>\n<\/ol>\n<p><img src=\"https:\/\/s2.loli.net\/2022\/04\/23\/aLSGsYy3AXTz5VB.png\" alt=\"Untitled 1.png\" \/><\/p>\n<ol start=\"3\">\n<li>\n<p>unity \u504f\u597d\u8bbe\u7f6e\u2192\u5916\u90e8\u5de5\u5177\uff0c\u786e\u4fdd\u914d\u7f6e\u597d sdk \u548c ndk<\/p>\n<p><img src=\"https:\/\/s2.loli.net\/2022\/04\/23\/1onljDqpRHUwhbz.png\" alt=\"Untitled 2.png\" \/><\/p>\n<\/li>\n<\/ol>\n<\/li>\n<li>\n<p>\u63d2\u4ef6\u5f00\u53d1(<a href=\"https:\/\/blog.csdn.net\/K20132014\/article\/details\/109159008\">\u53ef\u53c2\u8003\u90e8\u5206<\/a>)<\/p>\n<ol>\n<li>\n<p>\u65b0\u5efaAndroid studio \u9879\u76ee<\/p>\n<ol>\n<li>Empty Activity<\/li>\n<li>\u5305\u540d\u968f\u610f<\/li>\n<li>minimum SDK \u8ddf unity \u9879\u76ee\u4fdd\u6301\u4e00\u81f4<\/li>\n<\/ol>\n<\/li>\n<li>\n<p>\u62f7\u8d1d<code>unity<\/code> \u7684 <code>classes.jar (\/Applications\/Unity\/PlaybackEngines\/AndroidPlayer\/Variations\/mono\/Release\/Classes\\classes.jar)<\/code> \u5230 \u9879\u76ee <code>app\/libs<\/code> \u76ee\u5f55\u4e0b\uff0c\u53f3\u952e <code>classes.jar\u2192Add As Library<\/code><\/p>\n<\/li>\n<li>\n<p><code>MainActivity<\/code> \u5220\u9664 <code>setContentView<\/code> \u884c\u4ee3\u7801, \u5220\u9664 <code>layout<\/code> \u4e0b <code>activity_main.xml<\/code><\/p>\n<p><img src=\"https:\/\/s2.loli.net\/2022\/04\/23\/6apV9oDhOKXcH1f.png\" alt=\"Untitled 3.png\" \/><\/p>\n<\/li>\n<li>\n<p>\u4fee\u6539 <code>build.gradle<\/code> <code>apply plugin: &#039;com.android.application<\/code> \u6539\u6210 <code>apply plugin: &#039;com.android.library<\/code>, \u5220\u9664 defaultConfig \u4e0b\u7684 applicaionId \u884c<\/p>\n<p><img src=\"https:\/\/s2.loli.net\/2022\/04\/23\/BcjEdv92nPhpDe5.png\" alt=\"Untitled 4.png\" \/><\/p>\n<\/li>\n<li>\n<p>\u5728 <code>\/Applications\/Unity\/Hub\/Editor\/2020.1.13f1\/PlaybackEngines\/AndroidPlayer\/Source\/com\/unity3d\/player\/UnityPlayerActivity.java<\/code> \u627e\u5230 <code>UnityPlayerActivity.java<\/code>, \u76f4\u63a5\u62f7\u8d1dsource \u76ee\u5f55\u4e0b\u7684 com \u5305\u5230 java\u6587\u4ef6\u5939<\/p>\n<\/li>\n<li>\n<p>\u4fee\u6539 AndroidManifest.xml<\/p>\n<pre><code class=\"language-xml\"><manifest xmlns:android=\"http:\/\/schemas.android.com\/apk\/res\/android\"\n    package=\"\u968f\u4fbf\">\n\n    <application>\n      <!--\u8868\u660e\u8fd9\u4e2aActivity\u662f\u542f\u52a8Activity \u4e00\u5b9a\u8981\u5199\u5b8c\u5168\u7684\u5305\u540d \u8def\u5f84-->\n        <activity android:name=\"\u5305\u540d.MainActivity\">\n\n            <intent-filter>\n                <action android:name=\"android.intent.action.MAIN\" \/>\n                <category android:name=\"android.intent.category.LAUNCHER\" \/>\n            <\/intent-filter>\n            <meta-data android:name=\"unityplayer.UnityActivity\" android:value=\"true\" \/>\n        <\/activity>\n    <\/application>\n<\/manifest>\n<\/code><\/pre>\n<\/li>\n<li>\n<p>\u5728 build.gradle \u91cc\u52a0\u5165\u4f9d\u8d56\u5e93\uff0c\u6bd4\u5982:<\/p>\n<p><img src=\"https:\/\/s2.loli.net\/2022\/04\/23\/JwairlhHLKIOTcQ.png\" alt=\"Untitled 5.png\" \/><\/p>\n<\/li>\n<li>\n<p>\u65b0\u5efa\u4e00\u4e2a class\uff0c\u5728\u91cc\u9762\u5199\u539f\u751f\u4ee3\u7801: <\/p>\n<pre><code>package \u8def\u5f84;\npublic class MyClass {\n    private Class<?> unityPlayerClass;\n    private Field unityCurrentActivity;\n    private Method unitySendMessage;\n\n    public void init () {\n\n        \/\/Get the UnityPlayer class using Reflection\n        unityPlayerClass = Class.forName(\"com.unity3d.player.UnityPlayer\");\n        \/\/Get the currentActivity field\n        unityCurrentActivity= unityPlayerClass.getField(\"currentActivity\");\n        \/\/Get the UnitySendMessage method\n        unitySendMessage = unityPlayerClass.getMethod(\"UnitySendMessage\", new Class [] { String.class, String.class, String.class } );\n    }\n\n    \/\/Use this method to get UnityPlayer.currentActivity\n    public Activity currentActivity () {\n\n        Activity activity = (Activity) unityCurrentActivity.get(unityPlayerClass);\n        return activity;            \n    }\n\n    public void unitySendMessageInvoke (String gameObject, String methodName, String param) {\n        \/\/Invoke the UnitySendMessage Method\n        unitySendMessage.invoke(null, new Object[] { gameObject, methodName, param} );\n    }\n\n    public void makeToast (final String toastText, final int duration) {\n        currentActivity().runOnUiThread(new Runnable() {\n            @Override\n            public void run() {\n                Toast.makeText(getActivity(), toastText, duration).show();\n            }\n        });\n    }\n        \/\/ \u522b\u5fd8\u4e86\u8c03\u7528\n        private void listenSDKData() {\n            currentActivity().runOnUiThread(new Runnable() {\n                @Override\n                public void run() {\n                    MotrixiSDK.INSTANCE.setOnLogListener(new OnLogListener() {\n                        @Override\n                        public void onLogListener(String s) {\n                            unitySendMessageInvoke(\"UnityAndroidConnect\", \"AndroidCallUnityMsg\", s);\n                        }\n                    });\n                }\n            });\n        }\n}<\/code><\/pre>\n<\/li>\n<li>\n<p>Build-&gt;Make Project\uff0c\u4e00\u822c\u53ea\u8981 <code>build\/intermediates\/arr_main_jar\/debug\/classes.jar<\/code> \u5c31\u884c<br \/>\n<img src=\"https:\/\/s2.loli.net\/2022\/04\/23\/B2uwN5bFnyjDQ4e.png\" alt=\"Untitled 6.png\" \/><\/p>\n<\/li>\n<\/ol>\n<p>\u7528\u538b\u7f29\u5305\u6253\u5f00jar \u5305\uff0c\u5220\u9664 com \u76ee\u5f55\u4e0b\u7684 unity3D\u548c \u9879\u76ee\u540d\u6700\u5e95\u5c42\u6587\u4ef6\u5939\u91cc\u7684 BuildConfig.class<\/p>\n<p><img src=\"https:\/\/s2.loli.net\/2022\/04\/23\/6WzRrMYF287NXH5.png\" alt=\"Untitled 7.png\" \/><\/p>\n<ol start=\"10\">\n<li>\n<p>\u628a\u4e0a\u8ff0\u9879\u76ee\u7684 AndroidManifest.xml \u548c \u5bfc\u51fa\u7684 classes.jar(\u53ef\u4ee5\u6539\u540d)\u653e\u5230unity \u4e2d\uff0c\u8def\u5f84\u5982\u4e0b<\/p>\n<p>jar \u653e\u5230 <code>Assets\/Plugins\/Android\/libs<\/code> \u4e0b<\/p>\n<\/li>\n<li>\n<p>\u5728<code>\/Applications\/Unity\/Hub\/Editor\/2020.1.13f1\/PlaybackEngines\/AndroidPlayer\/Tools\/GradleTemplates<\/code> \u8def\u5f84\u4e0b\u6709 gradle \u6a21\u677f\uff0c\u628a\u9700\u8981\u7528\u5230\u7684\u653e\u5230 unity \u9879\u76ee Assets\/Plugins\/Android \u4e0b:<\/p>\n<ul>\n<li>BaseProjectTemplate.gradle: project \u8def\u5f84\u4e0b\u7684gradle<\/li>\n<li>gradleTemplate: gradle \u914d\u7f6e<\/li>\n<li>mainTemplate: module \u4e0b\u7684 gradle<\/li>\n<\/ul>\n<\/li>\n<li>\n<p>Unity \u521b\u5efa\u4e00\u4e2aGameObject\uff0c\u547d\u540d\u4e0e\u81ea\u5b9a\u4e49java class \u6587\u4ef6\u4e2d\u7684 gameObject \u540d\u5b57\u4e00\u81f4, Assets \u4e0b\u521b\u5efa\u4e00\u4e2acs\u6587\u4ef6\uff0c\u5173\u8054\u5230GameObject.<\/p>\n<p>cs \u6587\u4ef6\u5982\u4e0b\uff1a<\/p>\n<pre><code class=\"language-csharp\">using System;\nusing System.Collections;\nusing System.Collections.Generic;\nusing UnityEngine;\nusing UnityEngine.UI;\n\npublic class UnityAndroidConnect : MonoBehaviour\n{\n\n    private string appKey = \"\";\n        \/\/ \u4e24\u4e2a\u6309\u94ae\n    private GameObject resetButton;\n    private GameObject uploadButton;\n        \/\/ \u6587\u672c\u6846\n    private GameObject informationLabel;\n        \/\/ \u6587\u672c\u6846\u7684\u6587\u5b57\n    public Text informtaionText;\n\n    \/\/ AndroidJavaClass jc;\n    AndroidJavaObject androidInstance; \n\n    \/\/ Start is called before the first frame update\n    void Start()\n    {\n        try\n        {\n                        \/\/\u53c2\u6570\u5c31\u662fjar \u5305\u7684\u9879\u76eepackage name\n            androidInstance = new AndroidJavaObject(\"com.motrixi.unity.plugin.Motrixi\");\n            if (null != androidInstance) \n            {\n                                \/\/ \u53c2\u6570\u4e3a\u81ea\u5b9a\u4e49 java \u6587\u4ef6\u91cc\u7684\u65b9\u6cd5\n                androidInstance.Call(\"initPlugin\");\n                                androidInstance.Call(\"init\", appKey)\n            }\n        }\n        catch (Exception e)\n        {\n            Debug.Log( \"init error:\" + e.ToString());\n        }\n                \/\/ \u83b7\u53d6 resetButton\n        resetButton = GameObject.Find(\"ResetButton\");\n        resetButton.GetComponent<Button>().onClick.AddListener(Reset);\n\n        uploadButton = GameObject.Find(\"UploadButton\");\n        uploadButton.GetComponent<Button>().onClick.AddListener(DebugUpload);\n\n        informationLabel = GameObject.Find(\"SdkInformationArea\");\n\n        informtaionText = GameObject.Find(\"SdkInformationArea\").GetComponent<Text>();\n    }\n\n     public void Reset()\n     {\n        try\n            {\n                Debug.Log(\"Reset Clicked. ClickHandler.\");\n                androidInstance.Call(\"resetConsentForm\");\n            }\n        catch (Exception e)\n            {\n                Debug.Log( \"reset button error:\" + e.ToString());\n            }\n     }\n\n     public void DebugUpload()\n     {\n            try\n            {\n                Debug.Log(\"DebugUpload Clicked. ClickHandler.\");\n                androidInstance.Call(\"upload\");\n            }\n        catch (Exception e)\n            {\n                Debug.Log( \"DebugUpload button error:\" + e.ToString());\n            }\n     }\n\n        \/\/ java \u4f20\u7ed9 unity \u7684\u65b9\u6cd5\n     public void AndroidCallUnityMsg(string recvMsg)\n     {\n        Debug.Log(\"recvMsg:\" + recvMsg);\n        informtaionText.text = recvMsg;\n     }\n\n    \/\/ Update is called once per frame\n    void Update()\n    {\n\n    }\n}<\/code><\/pre>\n<\/li>\n<li>\n<p>\u5bfc\u51faAndroid\u9879\u76ee\u5c31\u53ef\u4ee5\u4e86<\/p>\n<\/li>\n<\/ol>\n<\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>Unity2020.1 Android\u63d2\u4ef6\u5236\u4f5c \u4e4b\u524d\u5199\u63d2\u4ef6\u7684\u65f6\u5019\u641c\u7d22\u4e86\u5927\u91cf\u8d44\u6599\uff0c\u6709\u4e9b\u56e0\u4e3a\u7248\u672c\u95ee\u9898\u8fc7\u65f6\uff0c\u6709\u4e9b\u6839\u672c\u5c31\u662f\u9519\u7684\uff0c\u6240\u4ee5\u8bb0\u5f55\u4e0b\u4eb2\u6d4b\u7684\u6b65\u9aa4 \u4fee\u6539 unity\u8bbe\u7f6e \u6587\u4ef6\u2192\u751f\u6210\u914d\u7f6e\u2192Android\u2192\u5bfc\u51fa\u2026<\/p>\n","protected":false},"author":4,"featured_media":274,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[2],"tags":[],"blocksy_meta":{"styles_descriptor":{"styles":{"desktop":"","tablet":"","mobile":""},"google_fonts":[],"version":5}},"_links":{"self":[{"href":"https:\/\/blog.osvlabs.com\/index.php?rest_route=\/wp\/v2\/posts\/272"}],"collection":[{"href":"https:\/\/blog.osvlabs.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.osvlabs.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.osvlabs.com\/index.php?rest_route=\/wp\/v2\/users\/4"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.osvlabs.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=272"}],"version-history":[{"count":1,"href":"https:\/\/blog.osvlabs.com\/index.php?rest_route=\/wp\/v2\/posts\/272\/revisions"}],"predecessor-version":[{"id":273,"href":"https:\/\/blog.osvlabs.com\/index.php?rest_route=\/wp\/v2\/posts\/272\/revisions\/273"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/blog.osvlabs.com\/index.php?rest_route=\/wp\/v2\/media\/274"}],"wp:attachment":[{"href":"https:\/\/blog.osvlabs.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=272"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.osvlabs.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=272"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.osvlabs.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=272"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}