Search code examples
javaandroidmultithreadingandroid-ndkjava-native-interface

How to pass native method to thread in android?


I have one MainActivity, one Thread(RunJNIThread) and one jniClass.c. Because JNI will block UI thread, so I use Thread to run jniClass.cpp. I used Activity to call MainActivity.StartJNI() in Thread, after I find this that said "Passing an Activity into another object is usually a bad idea ".

So how to pass a native method which defined in MainActivity to Thread? Not using Activity.

MainActivity.java

public RunJNIThread thread;
thread = new RunJNIThread(this);
....
static {
   System.loadLibrary("jniClass");
}
public native void StartJNI();
...

RunJNIThread.java

private MainActivity mainActivity;
getFrameThread(MainActivity mainActivity){
    this.mainActivity = mainActivity; //Not Good
}
public void run(){
    while(!Stop){
        mainActivity.StartJNI(); //how to replace this with better way
        try {
            Thread.sleep(5);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}
...

Solution

  • You can create a new view as interface

    interface MyView{
        void callMethod();
    }
    

    then you implement this view in your Main Activity

    MainActivity implements MyView
    

    when your create the thread class you can pass context if it is needed , and view as parameters.

    thread = new RunJNIThread(this,this) 
    

    and your Thread class' constructor should be ;

    public class RunJNIThread{
        public void RunJNIThread(Context context , MyView view){
            this.context = context;
            this.view = view;
        }
    }
    

    when you want to call your main activity function. you can call "callMethod()"

    public void run(){
    while(!Stop){
        view.callMethod();
        try {
            Thread.sleep(5);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
    

    in your main activity, overrided callMethod

    @Override
    public void callMethod(){
        StartJNI();
    }