JNI,让native callback Java methods

今天试验了通过JNI,让native回调java层的方法。


试验的代码很简单,让native回调java层的方法,让java层的方法想主线程发送消息更新UI。

下面是project的目录结构:


MainActivity.java的code

package com.example.jnicallback;

import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;
import android.view.View;
import android.widget.TextView;

public class MainActivity extends Activity {
	
	private TextView mStopWatch;
	private MessageExt mMessageExt;
	private MessageExt.TimeListener mListener = new MessageExt.TimeListener() {
		@Override
		public void updateTime(String timer) {
			mStopWatch.setText(timer);
		}
	};
	
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mStopWatch = (TextView) findViewById(R.id.stop_watch);
        mMessageExt = new MessageExt(mListener, this.getMainLooper());
        mMessageExt.process();
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }
    
}
逻辑很简单,通过MessageExt回调updateTime() method更新UI。


MessageExt.java的code

package com.example.jnicallback;

import java.lang.ref.WeakReference;

import android.os.Handler;
import android.os.Looper;
import android.os.Message;

public class MessageExt {
	
	private MainHanlder mMainHandler;
	private static final int UPDATE_TIMER = 1;
	private TimeListener mListener;
	
	public interface TimeListener {
		public void updateTime(String time);
	}
	
	public MessageExt(TimeListener listener, Looper looper) {
		mListener = listener;
		mMainHandler = new MainHanlder(looper);
		nativeSetup(new WeakReference<MessageExt>(this));
	}
	
	private class MainHanlder extends Handler {
		public MainHanlder(Looper looper) {
			super(looper);
		}
		
		@Override
		public void handleMessage(Message msg) {
			switch(msg.what) {
			case UPDATE_TIMER:
				String time = "2013";
				mListener.updateTime(time);
			}
		}
		
	}
	
	private static void callbackFromNative(Object messageExt) {
		MessageExt msgExt = (MessageExt)((WeakReference)messageExt).get();
		if (msgExt.mMainHandler != null) {
			msgExt.mMainHandler.sendEmptyMessage(UPDATE_TIMER);
		}
	}
	
	public void process() {
		nativeProcess();
	}
	
	static {
		System.loadLibrary("test_jni");
	}
	
	private native void nativeSetup(Object messageExt);
	private native void nativeProcess();
}
callbackFromNative()方法就是native要回调的方法。主要定义为static类型,为class所拥有。之所以要用static修饰是为了避免在runing的时候会有
can't call callbackFromNative on instance of Ljava/lang/Class;
接下来看JNI下的jni_MessageExt.cpp的code
#include <jni.h>

extern "C" {
jobject mMsgExtJObjectWeak;
jmethodID mCallbackJmethodId;
jclass mMsgExtClass;

/*
 * Class:     com_example_jnicallback_MessageExt
 * Method:    setup
 * Signature: (Ljava/lang/Object;)V
 */
JNIEXPORT void JNICALL Java_com_example_jnicallback_MessageExt_nativeSetup(JNIEnv *env, jobject thiz, jobject weak_this) {
	jclass clazz = env->GetObjectClass(thiz);
	mMsgExtJObjectWeak = env->NewGlobalRef(weak_this);
	mMsgExtClass = (jclass)env->NewGlobalRef(clazz);
	mCallbackJmethodId = env->GetStaticMethodID(clazz, "callbackFromNative", "(Ljava/lang/Object;)V");
}

/*
 * Class:     com_example_jnicallback_MessageExt
 * Method:    process
 * Signature: ()V
 */
JNIEXPORT void JNICALL Java_com_example_jnicallback_MessageExt_nativeProcess(JNIEnv *env, jobject thiz) {
	env->CallStaticVoidMethod(mMsgExtClass, mCallbackJmethodId, mMsgExtJObjectWeak);
}

}
注意的地方如果是.cpp文件,extern "C"{}, JNIEXPORT, JNICALL这些关键词是必要的,或者runing的时候会报找不到native的方法。好像.c文件就不需要这样。
不知道你注意到了没GetStaticMethodID(), CallStaticVoidMethod()这些方法没,那和java层的callbackFromNative用static修饰是关系的。
好吧,demo很简单,希望你们实验成功,
在windows上配置NDK,可以参考下面的这边文章http://blog.csdn.net/yangchang999/article/details/11880771

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值