Aylwyn Lake
Aylwyn Lake

Reputation: 2057

android native code call java method success, but ui method failed

I success go the flow of native call java method, but when the java method contains ui method, ui method always failed, and logcat will print VM aborting error:

E/ListenerTest( 1399): virtual void JNIListenerContext::postEv(int32_t)
W/dalvikvm( 1399): JNI WARNING: JNI method called with exception pending
W/dalvikvm( 1399):              in Ldalvik/system/NativeStart;.run:()V (CallStaticVoidMethodV)
W/dalvikvm( 1399): Pending exception is:
I/dalvikvm( 1399): "Binder Thread #2" prio=5 tid=10 NATIVE
I/dalvikvm( 1399):   | group="main" sCount=0 dsCount=0 obj=0x413f0b98 self=0x89b7e8
I/dalvikvm( 1399):   | sysTid=1411 nice=0 sched=0/0 cgrp=default handle=8998000
I/dalvikvm( 1399):   | schedstat=( 0 0 0 ) utm=0 stm=0 core=0
I/dalvikvm( 1399):   at dalvik.system.NativeStart.run(Native Method)
I/dalvikvm( 1399):
E/dalvikvm( 1399): VM aborting

In my native code:

JNIEnv *env = AndroidRuntime::getJNIEnv();
env->CallStaticVoidMethod( jclass, jmethod, arg);// call java method postEv(arg)

In my java code:

class ListenerClass {
    ... ...
    private static Listener mListener = null;
    public interface Listener {
        public void onMyListener( int arg );
    }

    public void registerListener (Listener listener) {
        Log.d( TAG,"registerListener");
        mListener = listener;
    }

    public static void postEv( int arg ) {
        Log.d( TAG,"postEv");
        if( mListener != null ) {
            mListener.onMyListener( arg );
        } else {
            Log.d( TAG,"no Listener");
        }
    }
}

public class ListenerDemo extends Activity implements ListenerClass.Listener
    ... ...
    private TextView info;
    private ListenerClass lisener = null;

    public void onCreate(Bundle savedInstanceState) {

        info = (TextView) findViewById(R.id.info);
        info.setTextColor(Color.WHITE);
        info.setTextSize(20);

        info.setText("haha");  // this works

        lisener = new ListenerClass();

        Log.d( TAG,"lisener.registerListener");
        lisener.registerListener(this);

    }

    public void onMyListener( int arg ) {
        Log.d(TAG,"arg is: " + arg );  // this works
        info.setText("haha");  // this not works
    }
    ... ...
}

I really don't know why this happaned. And I want the TextView to show, when an event has push to java's onMyListener.

Upvotes: 3

Views: 2519

Answers (1)

Aylwyn Lake
Aylwyn Lake

Reputation: 2057

At last, I found the reason why ui method can not be called.

My Native Call Java uses CallStaticVoidMethod(...), which means class method.

"private TextView info" is none static, which means object variable.

Although onMyListener is none static, it can use none static member info.

Native static method -> Java none-static method -> Java none-static variable seems ok. => Native static method --> Java none-static variable is not ok.

You can't use object variable in class method. The reason is very clear but the jni process hide the reason.

My good job! At the beginning I doubt this static use, today i try CallVoidMethod and it success.

Upvotes: 2

Related Questions