- Home /
Accessing static nested class of AndroidJavaClass
I am trying to use some functionality from a java JAR file, and specifically need to initialize it before usage of the API functions. This is done by accessing a static "builder" member of an "ApiClient" class which is itself an instance of a static class defined within the "ApiClient" class. Here is that java class:
package com.gs.common.client;
public class ApiClient {
public static Builder builder;
public static class Builder {
public Builder setContext(Context context) {}
public Builder addApi(String api) {}
public ApiClient build() {}
public void destroy() {}
}
public static class ApiCallBack {}
public static ApiClient getInstance() {}
}
FWIW, this is part of the GrandStream IP phone API for their Android line of devices.
The issue I'm having is that when I import ApiClient as an AndroidJavaClass, and then call GetStatic on it to get the "builder" member as an AndroidJavaObject, that works. But then when I try to call any functions of that member, I get a NullReferenceException. Here is my code:
AndroidJavaClass playerClass = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
AndroidJavaObject currentActivityObject = playerClass.GetStatic<AndroidJavaObject>("currentActivity");
AndroidJavaClass clientClass = new AndroidJavaClass("com.gs.common.client.ApiClient");
AndroidJavaClass builderClass = new AndroidJavaClass("com.gs.common.client.ApiClient$Builder");
AndroidJavaObject builder = clientClass.GetStatic<AndroidJavaObject>("builder");
// Any of these calls will result in a NullReferenceException
AndroidJavaObject junk1 = builder.Call<AndroidJavaObject>("setContext", currentActivityObject);
AndroidJavaObject junk2 = builder.Call<AndroidJavaObject>("addApi", "com.gs.phone.api.setting.CallSettingApi");
AndroidJavaObject junk3 = builder.Call<AndroidJavaObject>("build");
It looks like my call to access the static member is returning a null object, but I'm not sure why. I'm pretty sure the JAR is imported properly, because I'm able to get some other Exceptions that it implements when I run different code.
I've looked all over at existing answers on this topic, but none seem relevant to my case. I can only assume that I am doing something wrong when trying to access a static member of an AndroidJavaClass. Do I call it through some kind of '.' notation instead? I've tried all kinds of combinations of AndroidJavaClass vs AndroidJavaObject, call vs get, void vs static, etc. I'm hoping that I've simply missed some edge case in the documentation or something.
PS: I know that that I should be enclosing some of these calls inside of some "using" blocks so that the objects are destroyed after they're done being used, but I got rid of that in the interest of troubleshooting and eli$$anonymous$$ating variables.
Answer by Bunny83 · Oct 22, 2019 at 06:13 PM
I'm not a Java developer and the bit of Java experience I had was about 15 years ago. However as far as I know there is no thing as a static class in Java. There are static nested classes but they have a completely different purpose when compared to the concept of a static class here in C#. In C# a static class is simply a class you can not create an instance of and every member has to be static as well. In Java there are no top level static classes. Classes can simply have static members. The point of nested classes in Java is that the nested class inherits the scope of the outer class. There are two kinds of nested classes in Java:
non-static nested classes (called inner classes)
static nested classes
While the inner class requires an instance of the outer class in order to be created, a static nested class does not. An inner class does inherit the instance and static scope of the outer class. In other words an instance of an inner class has a hidden reference to the outer class.
An instance of a nested static class only inherits the static scope of the outer class since no instance of the outer class is required to create an instance of the nested static class. Yes, in Java you can create an instance of such a nested static class and since in your code you actually have a reference to your Builder class you actually need to create an instance and store that reference in that variable. In your code you never create an instance of your Builder class so the variable of course is null by default.
Maybe you had the wrong idea about what a nested static class is. I'm not sure if Java has the same field-initializer support as C#. If it has you probably can simply do
public static Builder builder = new Builder();
to create an instance of your Builder class.
Wow, alright so I got it working. I don't have access to the JAR sources so I couldn't add any code as suggested at the bottom of your answer. BUT, the solution ended up being to call:
AndroidJavaObject builderClass = new AndroidJavaObject("com.gs.common.client.ApiClient$Builder");
Ins$$anonymous$$d of:
AndroidJavaClass builderClass = new AndroidJavaClass("com.gs.common.client.ApiClient$Builder");
So, using AndroidJavaObject ins$$anonymous$$d of AndroidJavaClass.
Reading a bit further into the documentation of those classes, it looks like AndroidJavaClass does not create an instance of that class whereas AndroidJavaObject does. And from what you said about java classes, it makes sense that it made all the difference. Frustrating, but glad it's working. Thanks.
Your answer
Follow this Question
Related Questions
Android plugins add View 1 Answer
Call function From JAR Lib ? 3 Answers
How do I use Java callbacks? 1 Answer