In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-02-23 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Servers >
Share
Shulou(Shulou.com)05/31 Report--
This article will explain in detail about the principle of Unity compilation Android parsing and apk packaging analysis is how, the content of the article is of high quality, so the editor to share to you to do a reference, I hope you have a certain understanding of the relevant knowledge after reading this article.
Recently, because we want to call the relevant interface of Android's Activity in the script component of Scene, we need to understand the actual correspondence between Scene and Activity, and study some of the principles of Unity calling Android.
This paper mainly discusses the relationship between Scene and Activity, and what is the difference between Unity packaging apk and Android studio packaging apk? After finding this difference, how can it be used?
The following tools are needed:
Android decompilation tool-- apktool
Decompilation function of Android studio
First, what will be the program entry to compile Unity's Scene into apk,apk?
Create a new Unity project, create a Scene, and compile the Unity project into apk.
Decompile the compiled apk with apktool: apktool d unityTest.apk
The resulting AndroidManifest file is as follows:
As you can see from the AndroidManifest file, the system still has a master Activity, named com.unity3d.player.UnityPlayerActivity.
The implication is that compiling a Unity project that contains only Scene, packaged into Android apk, will take com.unity3d.player.UnityPlayerActivity as the main program entry, so the question is, how does Scene load and display to this UnityPlayerActivity?
2. How does UnityPlayerActivity load Scene in Unity?
2.1 UnityPlayerActivity
This starts with the UnityPlayerActivity source code. To use UnityPlayerActivity in the Android project, you need to rely on Unity's Android plug-in classes.jar (located in the Unity installation directory and can be found with everything software), and decompile it to get part of the UnityPlayerActivity source code:
Public class UnityPlayerActivity extends Activity {protected UnityPlayer mUnityPlayer; protected void onCreate (Bundle var1) {this.requestWindowFeature (1); super.onCreate (var1); this.getWindow () .setFormat (2); this.mUnityPlayer = new UnityPlayer (this); this.setContentView (this.mUnityPlayer); this.mUnityPlayer.requestFocus ();}}
Although confusing, it may seem laborious, but you can see from the code this.setContentView (this.mUnityPlayer) that the final interface display depends on an instance of UnityPlayer.
In addition, because Google has also done a set of Unity VR SDK, the corresponding class of UnityPlayerActivity is GoogleUnityActivity, which is also analyzed below.
2.2 re-analysis from GoogleUnityActivity.java
GoogleUnityActivity is a class used to implement UnityActivity in VR SDK introduced by google. Query its source code through google to find:
1. The actual layout file activity_main.xml of GoogleUnityActivity.java
There is no specific content in the layout file, only a FrameLayout layout.
two。 Focus on the onCreate function of GoogleUnityActivity:
Public class GoogleUnityActivity extends Activity implements ActivityCompat.OnRequestPermissionsResultCallback {protected void onCreate (Bundle savedInstanceState) {requestWindowFeature (Window.FEATURE_NO_TITLE); super.onCreate (savedInstanceState); setContentView (R.layout.activity_main); setContentView (R.id.activity_main.xml) mUnityPlayer = new UnityPlayer (this) If (mUnityPlayer.getSettings (). GetBoolean ("hide_status_bar", true)) {getWindow () .setFlags (WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);} ((ViewGroup) findViewById (android.R.id.content)) .addView (mUnityPlayer.getView (), 0); mUnityPlayer.requestFocus ();}}
MUnityPlayer is added as a FrameLayoutView to the view collection for display. Note that the id you are looking for here is android.R.id.content. According to the official interpretation of the id:
Android.R.id.content gives you the root element of a view, without having to know its actual name/type/ID. Check out Get root view from current activity
Thus it can be seen that the implementation principle of GoogleUnityActivity is to create an empty frame layout containing only FrameLayout, and then load the View in UnityPlayer into GoogleUnityActivity for display through addView.
It looks similar to UnityPlayerActivity, and the classes involved are UnityPlayer.
What kind of 2.3.UnityPlayer is it?
Decompile the classes.jar package to get part of the code of UnityPlayer:
Public class UnityPlayer extends FrameLayout implements com.unity3d.player.a.a {public static Activity currentActivity = null; public UnityPlayer (ContextWrapper var1) {super (var1); if (var1 instanceof Activity) {currentActivity = (Activity) var1;}} public View getView () {return this;} public static native void UnitySendMessage (String var0, String var1, String var2); private final native boolean nativeRender () Public void onCameraFrame (final com.unity3d.player.a var1, final byte [] var2) {final int var3 = var1.a (); final Size var4 = var1.b (); this.a (new UnityPlayer.c ((byte) 0) {public final void a () {UnityPlayer.this.nativeVideoFrameCallback (var3, var2, var4.width, var4.height); var1.a (var2) });}}
From the code, you can see:
UnityPlayer actually inherits from FrameLayout
And comes with a member variable of currentActivity, which is directly passed into the relevant parameters of Activity in the constructor.
Return the FrameLayout directly in the getView function
GoogleUnityActivity passes its context to UnityPlayer through the constructor of UnityPlayer, and assigns a value to its member variable currentActivity.
Due to the confusion of the UnityPlayer class, the core functions of rendering are also encapsulated in the native code. About the conversion of Scene to UnityPlayer as FrameLayout, we can only make a simple conjecture: by calling Android's GL rendering engine, render on the native layer, and synchronize to FrameLayout for display on UnityPlayerActivity.
3. How to display Scene in a custom Activity
As can be seen from the above research, if you want to display Scene in a fixed Activity, you need to deal with countview and unityplayer in the oncreate part of Activity. The easiest way is to write a class that inherits directly from UnityPlayerActivity or GoogleUnityActivity, and write the required Unity calling Android method in the class.
In this way, the Scene will be loaded in a specific Activity, and Unity c # can get the Activity and call the functions in it by getting the currentActivity variable.
IV. Problems that should be paid attention to in the Unity Android plug-in
If the Android studio project contains multiple module dependencies, you need to copy the corresponding module-compiled plug-ins into the Plugins/Android/lib directory.
In the first step, you can delete the packaged aar library directory directly, especially if there is an Android plug-in classesjar with unity, otherwise an error will be compiled.
When compiling multiple module, pay attention to the settings related to manifest lablel, as well as the minSDKVersion information of build.gradle. Otherwise, there will be an error of manifest merger failure.
About Android Manifest file merging for Unity:
Unity write a Scene,Android studio write an aar package containing the main Activity and put it in the Plugins/Android directory. After compiling apk with Unity, decompile his AndroidManifest file, two main Activity, and display the Activity containing Scene by default.
Solution: merge Unity's Manifest files, put a manifest in the Plugins/Android directory, and the manifest will not be merged.
5. Research on the structure of Unity packaged Android apk.
Because when Unity develops Android, it is often designed to switch to the environment of Unity + Visual and Android studio, the development of Unity tends to be faster, and more code writing and debugging are needed on the Android java side.
In this case, is there a way to package the Unity Scene and c # files compiled by Unity into Android studio so that you can debug directly in Android studio?
The principle of the method is very simple. By comparing the apk packaged by Unity with the ordinary Android apk files, we can find out the directory where the Unity files are stored, then store them in the Android studio project directory, and finally complete the packaging of Unity-related files through Android studio.
First, add the suffix of zip to apk to make it easy to compare with beyond compare:
It is found that there is only an extra assert/bin directory, under which you can see the unity-related dll library
Copy this file to the src/main/assert directory of the Android studio project
When debugging Android studio, you can set the aar library project to the app project so that you can compile the apk and run it on the phone.
Compile the project with Android studio and find that the assert/bin directory has been successfully packaged.
If you run apk install directly, you can see that it has the same effect as Unity compiles and packaged apk.
On the contrary, if the Android project is debugged, it will be compiled directly into app mode and modified into library mode, and after build, the aar library will be generated. Copy the aar library to the Plugins/Android/lib directory at this time, and pay attention to delete the assert/bin in the aar library, because this directory was previously copied from Unity, and if it is not deleted, there will be file conflicts caused by repeated packaging in the unity.
Because when the packaged bin directory of Unity is copied to the Android studio project, Android studio is now a library project and needs to be converted to an app project.
For the conversion between Android studio library and app involved in this, set up the build.gradle file to achieve:
App mode: apply plugin: 'com.android.application'
Library mode: apply plugin: 'com.android.library'
However, when setting these two modes, you need to pay attention to the setting of applicationId "com.example.yin.myapplication". If it is library mode, you need to comment it out directly.
If the java part of Android is re-debugged, re-change the app mode to library mode, build, and copy the generated aar package to the Unity Android Plugin directory, you can directly see the running effect in Unity.
However, be sure to delete the assert/bin directory in the aar file packaged by Android studio to prevent repeated packaging in Unity.
4. Conclusion:
The Scene in Unity is in Android, which actually corresponds to the FrameLayout of Activity. Each Scene runs in its own Activity environment, which can be obtained through the currentActivity variable.
To implement a custom Activity with the ability to load Scene directly, you need to inherit it from UnityPlayerActivity or GoogleUnityActivity, or directly customize the implementation of the UnityActivity class.
Ways to improve the efficiency of Unity+Android Plugin project development:
● directly copies the assert/bin directory in the apk packaged with Unity to the src/main/assert directory of the Android studio project, and configures the Android project in app mode, so you can debug the entire Unity+android plugin project directly on the Android studio.
After the ● Android studio part is debugged, you need to modify the build.gradle file, change the app mode to library mode again, compile the aar package file, delete the original copied unity part, and put it into the Plugins/Android/lib directory of unity for use.
On the principle of Unity compilation Android parsing and apk packaging analysis is shared here, I hope that the above content can be of some help to you, can learn more knowledge. If you think the article is good, you can share it for more people to see.
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.