Android Jni中使用线程及回调更新UI,androidjni
投稿于 被查看 38249 次 评论:42
Android Jni中使用线程及回调更新UI,androidjni
在Android使用Jni时,为了能够使UI线程即主线程与工作线程分开,经常要创建工作线程,然后在工作线程中调用C/C++函数.为了在C/C++ 函数中更新Android的UI,又时常使用回调。为了保证C/C++的工作函数以及回调函数都能轻易同时被Java的UI线程和创建的工作线程识别,我们声明native时经常要把他们声明成静态函数.但静态函数更新UI又会出现麻烦.为了解决这个问题,本人查阅了相关的一些文档。有些文档中涉及的问题并不是为了解决我要阐述的问题,但利用一下,就把这个问题解决了. 我写了一个例子,来阐述整个过程的思路.1.EagleUI.java
package eagle.test; public class EagleUI extends Activity { TextView mTextView; MainHandler mMainHandler; static MainHandler mHandler; //------------------------------------------------------ static { System.loadLibrary("EagleZip");// 声明所要调用的库名称 } //------------------------------------------------------ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); mTextView=(TextView)findViewById(R.id.MyTextView); mMainHandler=new MainHandler(); mHandler=mMainHandler; WorkThread tThread = new WorkThread (); new Thread(tThread).start(); } //------------------------------------------------------ public static void myCallbackFunc(String nMsg) { Message tMsg=new Message(); Bundle tBundle=new Bundle(); tBundle.putString("CMD", nMsg); tMsg.setData(tBundle); mHandler.sendMessage(tMsg); } //------------------------------------------------------ public static native String myJni(String nParam);// 对要调用的方法做本地声明 //------------------------------------------------------ public class zipThread implements Runnable { @Override public void run() { myJni("Eagle is great"); } } //------------------------------------------------------ class MainHandler extends Handler { public MainHandler(){} public MainHandler(Looper L) { super(L); } public void handleMessage(Message nMsg) { super.handleMessage(nMsg); Bundle tBundle=nMsg.getData(); String tCmd=tBundle.getString("CMD"); EagleUI.this.mTextView.setText(tCmd); } } }
2.[C/C++]代码
#include <jni.h> jclass gJniClass; jmethodID gJinMethod; //--------------------------------------------------------------- JNIEXPORT jstring JNICALL Java_eagle_test_EagleUI_myJni(JNIEnv* env, jclass cls,jstring param) { char tChar[256]; const char *tpParam; gJniClass = cls; gJinMethod = 0; gJinMethod=(*env)->GetStaticMethodID(env,gJniClass,"myCallbackFunc","(Ljava/lang/String;)V"); if(gJinMethod == 0 || gJinMethod == NULL) return (*env)->NewStringUTF(env, "-2"); strcpy(tChar,"Hello Eagle"); (*env)->CallStaticVoidMethod(env,gJniClass,gJinMethod,(*env)->NewStringUTF(env, tChar)); DisplayCallBack(env,tChar); tpParam =(*env)->GetStringUTFChars(env,param,0); return param; } //--------------------------------------------------------------- void DisplayCallBack(JNIEnv* env,char nMsg[]) { char tChars[256]; strcpy(tChars,nMsg); (*env)->CallStaticVoidMethod(env,gJniClass,gJinMethod,(*env)->NewStringUTF(env, tChars)); }
用户评论