Android NDK开发JNI调用

时间:2026-01-21   来源:未知    
字号:

Android NDK开发(2)----- JNI多线程

2012-03-17 09:47:36 我来说两句

收藏我要投稿

上一篇:http://www.77cn.com.cn/kf/201203/123039.html

一、概述

JNI编程和Linux上的C/C++编程还是挺相似的,每次java调用JNI中的函数时都会传入有关JVM的一些参数(如JNIEnv,jobject),每次JNI回调java中的方法时都要通过JVM的有关参数来实现,当在JNI中涉及到多线程的话还是有一些不一样的地方,就是要在子线程函数里使用AttachCurrentThread()和

DetachCurrentThread()这两个函数,在这两个函数之间加入回调java方法所需要的代码。

二、要求

掌握JNI多线程编程的方法。

三、实现

新建工程MyThread,修改main.xml文件,在里面只有一个Button,如下: 1 <?xml version="1.0" encoding="utf-8"?>

2 <LinearLayout

xmlns:android="http://www.77cn.com.cn/apk/res/android"

3 android:layout_width="fill_parent"

4 android:layout_height="fill_parent"

5 android:orientation="vertical" >

6

7 <Button

8 android:id="@+id/button"

9 android:layout_width="fill_parent"

10 android:layout_height="wrap_content"

11 android:text="启动JNI线程"

12 />

13 14 </LinearLayout>

修改MyThreadActivity.java文件,实现按钮的监听,在里面调用JNI中的函数来启动JNI中的线程,比较简单,如下:

1 package com.nan.thread;

2

3 import android.app.Activity;

4 import android.os.Bundle;

5 import android.util.Log;

6 import android.view.View;

7 import android.widget.Button;

8

9 public class MyThreadActivity extends Activity

10 {

11 private Button mButton = null;

12

13 /** Called when the activity is first created. */

14 @Override

15 public void onCreate(Bundle savedInstanceState)

16 {

17 super.onCreate(savedInstanceState);

18 setContentView(http://www.77cn.com.cnyout.main);

19

20 mButton = (Button)this.findViewById(R.id.button);

21 //按钮监听

22 mButton.setOnClickListener(new View.OnClickListener()

23 {

24

25 @Override

26 public void onClick(View v)

27 {

28 // TODO Auto-generated method stub

29 //调用JNI中的函数来启动JNI中的线程

30 mainThread();

32 }

33 });

34 //初始化JNI环境

35 setJNIEnv();

36 }

37

38 //由JNI中的线程回调

39 private static void fromJNI(int i)

40 {

41 Log.v("Java------>", ""+i);

42 }

43

44 //本地方法

45 private native void mainThread();

46 private native void setJNIEnv();

47

48 static

49 {

50 //加载动态库

51 System.loadLibrary("JNIThreads");

52 }

53

54 }

编写JNI_Thread.c文件,在mainThread()函数里启动5个子线程,在子线程函数里回调java中的静态方法fromJNI()来输出当前子线程是第几个被启动的线程。完整的内容如下:

1 #include<stdio.h>

2 #include<stdlib.h>

3 #include<unistd.h>

4 #include<pthread.h>

6 #include<jni.h>

7 #include<android/log.h>

8

9 #define LOGI(...) ((void)__android_log_print(ANDROID_LOG_INFO, "native-activity", __VA_ARGS__))

10 #define LOGW(...) ((void)__android_log_print(ANDROID_LOG_WARN, "native-activity", __VA_ARGS__))

11 #define LOGE(...) ((void)__android_log_print(ANDROID_LOG_ERROR, "native-activity", __VA_ARGS__))

12

13 //线程数

14 #define NUMTHREADS 5

15

16 //全局变量

17 JavaVM *g_jvm = NULL;

18 jobject g_obj = NULL;

19

20

21 void *thread_fun(void* arg)

22 {

23 JNIEnv *env;

24 jclass cls;

25 jmethodID mid;

26

27 //Attach主线程

28 if((*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL) != JNI_OK) 29 {

30 LOGE("%s: AttachCurrentThread() failed", __FUNCTION__);

31 return NULL;

32 }

33 //找到对应的类

34 cls = (*env)->GetObjectClass(env,g_obj);

35 if(cls == NULL)

36 {

37 LOGE("FindClass() Error.....");

38 goto error;

39 }

40 //再获得类中的方法

41 mid = (*env)->GetStaticMethodID(env, cls, "fromJNI", "(I)V"); 42 if (mid == NULL)

43 {

44 LOGE("GetMethodID() Error.....");

45 goto error;

46 }

47 //最后调用java中的静态方法

48 (*env)->CallStaticVoidMethod(env, cls, mid ,(int)arg);

49

50

51 error:

52 //Detach主线程

53 if((*g_jvm)->DetachCurrentThread(g_jvm) != JNI_OK)

54 {

55 LOGE("%s: DetachCurrentThread() failed", __FUNCTION__);

56 }

57

58

59 pthread_exit(0);

60 }

61

62 //由java调用以创建子线程

63 JNIEXPORT void Java_com_nan_thread_MyThreadActivity_mainThread( JNIEnv* env, jobject obj)

64 {

65 int i;

66 pthread_t pt[NUMTHREADS];

67

68 for (i = 0; i < NUMTHREADS; i++)

69 //创建子线程

70 pthread_create(&pt[i], NULL, &thread_fun, (void *)i);

71 }

72

73

74 //由java调用来建立JNI环境

75 JNIEXPORT void Java_com_nan_thread_MyThreadActivity_setJNIEnv( JNIEnv* env, jobject obj)

76 {

77 //保存全局JVM以便在子线程中使用

78 (*env)->GetJavaVM(env,&g_jvm);

79 //不能直接赋值(g_obj = obj)

80 g_obj = (*env)->NewGlobalRef(env,obj);

81 }

82

8 …… 此处隐藏:2376字,全部文档内容请下载后查看。喜欢就下载吧 ……

Android NDK开发JNI调用.doc 将本文的Word文档下载到电脑,方便复制、编辑、收藏和打印
    × 游客快捷下载通道(下载后可以自由复制和排版)
    VIP包月下载
    特价:19 元/月 原价:99元
    低至 0.1 元/份 每月下载300
    全站内容免费自由复制
    VIP包月下载
    特价:19 元/月 原价:99元
    低至 0.1 元/份 每月下载300
    全站内容免费自由复制
    注:下载文档有可能出现无法下载或内容有问题,请联系客服协助您处理。
    × 常见问题(客服时间:周一到周五 9:30-18:00)