Search code examples
javaandroidandroid-studiojava-native-interface

View.isInEditMode() statically?


I'm using JNI in my app. In Java classes which need native things I load the native library like so:

static
{
    System.loadLibrary("nativeegl");
}

To be honest I don't know what the static thing does exactly, but I guess this is to make sure that the nativeegl library is loaded before anything else. Don't remember where I got this pattern from.

Now if this is a View subclass, and I'm using the graphical editor in Android Studio, the editor can't load the view subclass because of this exception:

java.lang.UnsatisfiedLinkError: no nativeegl in java.library.path

Since View.isInEditMode() is an instance method, I can't use it within the static{} block.

Is there an alternative? Maybe I can load the library differently?


Solution

  • Now that I think about it, one possible workaround is to split your View code into two classes: the actual View, and a separate standalone class that contains your JNI code, including the static block. For the purposes of the rest of this answer, I'll call these FooView and BarWrapper, respectively.

    Then, only reference BarWrapper from code in FooView that is inside an if (isInEditMode()) block.

    This may prevent BarWrapper from being loaded by the Java/pseudoAndroid environment used by the GUI builder, and therefore not trigger the attempt to load your native library. Leastways, the Dalvik classloading rules would cause BarWrapper to be ignored, as classes only get loaded when they are first used, and in your case you would be skipping over all code that uses BarWrapper. Hopefully, the GUI builder code adheres to how Dalvik handles it, though that's far from assured, since it's running on a Java VM, not an Android VM (Dalvik or ART).

    It may make your code a bit more clunky, as you have to split out your logic between two classes instead of just one. But, it may be worth an experiment.