Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 12 Next capture
2021 2022 2023
1 capture
12 Jun 22 - 12 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
This question was closed Nov 21, 2017 at 10:49 PM by Tulsisvt for the following reason:

The question is answered, right answer was accepted

avatar image
2
Question by Tulsisvt · Oct 25, 2017 at 06:33 PM · androidunity 5performance optimizationprofilinggarbage-collection

Calling a java method in android from Unity

Our project uses it's custom video player script and makes a call to the android side within the Update function - to update audio angles as this is a 360 degree video player. There is a large amount of garbage collection going on per frame based on profiler sample results. We are passing two float arguments to the java function. Does anyone know why there is a lot of GC happening in this call? Pasting the code here:

 horizontal = eulerAngles [1] * Mathf.Deg2Rad;
 vertical = eulerAngles [0] * Mathf.Deg2Rad;
 _JO.Call(SET_AUDIO_ANGLE, -horizontal, vertical);
Comment
Add comment
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

1 Reply

  • Sort: 
avatar image
3
Best Answer

Answer by Bunny83 · Oct 25, 2017 at 11:02 PM

Two things: First the signature of the Call method is

 public void Call(string methodName, params object[] args)

That means each time you call it you will create a new "object[]" with your two parameters. The second thing is your two float parameters need to be boxed in order to be stored in the array.

Unfortunately there's nothing you can do against the boxing beside avoid calling the method when the angles haven't changed. You may use a minimum difference threshold. The object array can be cached. So create the array once and reuse it.

edit

Well there's actually a way around that boxing problem. The "Call" method is rather convenient to use but creates a lot of "internal garbage". The actual JNI interface doesn't take an "object[]" but rather a "jvalue[]". jvalue is a struct with overlapping fields for the various types.

So the solution would be to:

  • Use AndroidJNIHelper.GetMethodID to get back an IntPtr to the method id . You have to pass the native class reference, the method name, the object[] with the parameters and "false" (since it's an instance method, not a static method). You store that reference next to your actual "_JO".

  • Beside that you create a jvalue array of size 2. This array should be cached and reused.

  • Finally you can call the method with AndroidJNI.CallVoidMethod. You need to pass the native object pointer which you get from _JO.GetRawObject(), the method ID we stored and the jvalue array. Before you call that method of course you have to update the values in the array. The struct type has a field named "f" which is of type float. There you can assign your two values.

So it would look something like this:

 AndroidJavaObject _JO;
 System.IntPtr methodID;
 jvalue[] parameters = new jvalue[2];
 
 void Init()
 {
     // make sure your _JO object is already created at this point.
     //methodID = AndroidJNIHelper.GetMethodID(_JO.GetRawClass(), SET_AUDIO_ANGLE, new object[]{0f,0f}, false);
     // just noticed that there is also a GetMethodID version that takes a signature string. This avoids
     // the temp object array. The array is only used to create that signature string from the types
     methodID = AndroidJNIHelper.GetMethodID(_JO.GetRawClass(), SET_AUDIO_ANGLE, "(FF)V", false);
 }
 
 void UpdateAudioAngles(Vector3 aEulerAngles)
 {
     parameters[0].f = -aEulerAngles.y * Mathf.Deg2Rad;
     parameters[1].f = aEulerAngles.x * Mathf.Deg2Rad;
     AndroidJNI.CallVoidMethod(_JO.GetRawObject(), methodID, parameters);
 }

Note: Be aware that "CallVoidMethod" might throw an exception. Unity actually has an internal class (in all their wiseness they makes all useful classes internal) that wraps the call in a try catch block and performs some special Java exception handling in case of an exception. This is missing in this case. AS long as there is no error in your java method you should be fine. Don't ask me what happens when an exception is thrown. You might just try it ^^.


ps: i guessed "SET_AUDIO_ANGLE" is actually a string constant that holds the method name, right?

Comment
Add comment · Show 2 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image Tulsisvt · Oct 26, 2017 at 03:19 PM 0
Share

Thanks a lot for your answer! It brought down GC allocation from 250 bytes per frame to 0.

avatar image Bunny83 Tulsisvt · Oct 26, 2017 at 09:31 PM 0
Share

Great to hear ^^. Recently i did not do any android development (my last android build was three years ago). Though i always was interested in the JNI interface. It provides direct access to the Java world (even though it's a hell to work with ^^).


Unity's JNI wrappers are intended to be "easy to use" but in turn generate a lot garbage. For example they gave the "Call" method a generic parameter to choose the return type. However all value types would get boxed in their wrapper code while the Android JNI bridge actually provides seperate call methods with the right managed return type (like "CallBoolean$$anonymous$$ethod", "CallByte$$anonymous$$ethod", "CallShort$$anonymous$$ethod", ...).

Follow this Question

Answers Answers and Comments

217 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

How to save and load a json file on android 1 Answer

Upgrade from 5.0.1 to 5.1.2f1, can't build in android now 1 Answer

pick image from android gallery 3 Answers

Failed to re-package resources. 0 Answers

My game crahses when I use it on a phone 0 Answers


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges