Search code examples
android-ndkjava-native-interfaceandroid-buildnative-methods

Opportunity to using native methods systemwide. How to call method or how it should be named?


I want to use one native library for a plurality of applications. Library has compiled through android build system and now located in /system/lib/. It can be loaded in application through System.LoadLibrary("libexample"). But method in library which should be declared like

JNIEXPORT jstring JNICALL Java_application1_MainActivity_method1

turning out unusable because library should be used by several applications. And of course this several applications have their own unique names. So I tried to named my method just like

 JNIEXPORT jstring JNICALL method1

and call

public native String method1(String string);

But of course my application trying to find it as Java_application1_MainActivity_method1

How to call this method or how it should be named?

Updated:

I tried to use this(see post with green tick) tutorial to complete my project. I wrote a library for using native method:

package com.example.mylib;

import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;

public class MyClass extends Activity {
public native static String MyMethod(String string);
    static {
        System.loadLibrary("nativeLibrary");
    }
}

Then I trying to use it in my application:

// Some no interesting inclusions
import com.example.mylib.MyClass;

public class MainActivity extends ListActivity {
// Some no interesting code.
MyMethod(file.getAbsolutePath())
//Some no interesting code 
}

And it working as I need! But now I confused that my import com.example.mylib.MyClass; "never used" in eclipse. And if I will create image with this "Is Library" project the latest will no resolving. Any idea?


Solution

  • Yes, you can use the same JNI signature in many applications. Your class may not belong to the default package of the application, as defined in AndroidManifest.xml. So what?


    Example:

    Start with HelloJni sample from NDK (in Eclipse, use Import -> Android -> existing Android Code, and point to the ${android-ndk-root}/samples/hello-jni).

    Build it and run on device or emulator.

    Open a new Android Application project, call it TestCrossJni. The package name for our app will be: test.cross.jni - no relation to com.example.hellojni!

    Choose "Create Activity" -> create Blank Activity.

    Add new Java class to this project (src/com/example/hellojni/HelloJni.java):

    package com.example.hellojni;
    
    public class HelloJni
    {
        public static String gets() {
            return stringFromJNI();
        }
    
        /* A native method that is implemented by the
         * 'hello-jni' native library, which is packaged
         * with this application.
         */
        private native String  stringFromJNI();
    
        /* this is used to load the 'hello-jni' library on application
         * startup. The library has already been unpacked into
         * /data/data/com.example.hellojni/lib/libhello-jni.so at
         * installation time by the package manager.
         */
        static {
            System.load("/data/data/com.example.hellojni/lib/libhello-jni.so");
        }
    }
    

    Edit res/layout/activity_main.xml: replace

        line 12 android:text="@string/hello_world" />

        with android:id="@+id/hello_world" />

    In src/test/cross/jni/MainActivity.java, add the following after

        line 12 setContentView(R.layout.activity_main);

    ((android.widget.TextView)findViewById(R.id.hello_world)).setText(com.example.hellojni.HelloJni.gets());
    

    Profit!