Android NDK编程小试---实现java和c语言的互掉

实现功能

l  实现 java/C互相调用 android端java调用LibMain 进而执行C语言 并且传入字符数组

l  C语言回调java Natives类的OnMessage方法打印消息,实现一个日志打印功能

l  通过本次NDK学习,掌握NDK开发环境的配置、C语言的编译成.so库

Android java层代码

Natives类:


public class Natives {

   /***

    * 原生库主入口

    * @param argv

    * @return

    */

   public static native int LibMain(String []argv);

   /**

    * C语言调用实现日志打印

    * @param text

    * @param level

    */

   private static void OnMessage(String text,int level)

   {

     System.out.println("OnMessage text :"+text+" level="+level);

   }

该类只是声明一个原生方法nt LibMain(String[]argv)供远程层调用。并且一个打印消息的方法,用于远程层调用,可以打印日志,用于原生层的调试。该类通过javah –jni com.flying.NDKTest1.Natives.java 能够生成头文件。

 

MainActiity类

public class MainActivity extends Activity {

 

   @Override

   protected void onCreate(Bundle savedInstanceState) {

     super.onCreate(savedInstanceState);

     setContentView(R.layout.activity_main);

     String argv[]={"MyLib","arg1","arg2"};

     try

     {

     Natives.LibMain(argv);

     }

     catch(Exception e)

     {

        e.printStackTrace();

     }

   }

 

   static{

     System.loadLibrary("NDKTest1"); //加载.so库

   }

 

}

 

原生层代码

Natives生成的头文件

#include <jni.h>

/* Header for class com_flying_ndktest1_Natives */

 

#ifndef _Included_com_flying_ndktest1_Natives

#define _Included_com_flying_ndktest1_Natives

#ifdef __cplusplus

extern "C" {

#endif

/*

 * Class:     com_flying_ndktest1_Natives

 * Method:    LibMain

 * Signature: ([Ljava/lang/String;)I

 */

JNIEXPORT jint JNICALL Java_com_flying_ndktest1_Natives_LibMain

  (JNIEnv *, jclass, jobjectArray);

 

#ifdef __cplusplus

}

#endif

#endif

 

Lib.c

#include "com_flying_ndktest1_Natives.h"

#include <stdio.h>

#include <stdlib.h>

#define CB_CLASS "com_flying_ndktest1_Natives"

 

/**

 * OnMessage 回调方法

 */

#define CB_CLASS_CB "OnMessage"

#define CB_CLASS_MSG_SIG "(Ljava/lang/String;I)v"

 

 

int lib_main(int argc ,char **argv);

 

const int getArrayLen(JNIEnv *env,jobjectArray jarray);

 

void jni_printf(char *format,...);

 

static JavaVM *g_VM;

 

static jclass jNativesCls;

 

/*

 * Class:     com_flying_ndktest1_Natives

 * Method:    LibMain

 * Signature: ([Ljava/lang/String;)I

 */

JNIEXPORT jint JNICALL Java_com_flying_ndktest1_Natives_LibMain

  (JNIEnv * env, jclass class, jobjectArray jargv)

         {

                   (*env)->GetJavaVM(env,&g_VM);

 

                   jsize clen=getArrayLen(env,jargv);

 

                   char *args[(int)clen];

 

                   int i;

                   jstring jrow;

 

                   for(i=0;i<clen;i++)

                   {

                            jrow=(jstring)(*env)->GetObjectArrayElement(env,jargv,i);

                            const char *row=(*env)->GetStringUTFChars(env,jrow,0);

 

                            args[i]=malloc(strlen(row)+1);

                            strcpy(args[i],row);

 

                            jni_printf("Main argv[%d]=%s",i,args[i]);  //打印args参数对应的字符串

 

                            (*env)->ReleaseStringUTFChars(env,jrow,row); //释放java字符串jrow

 

                   }

 

                   //加载com_flying_ndktest1_Natives类

 

                   jNativesCls=(*env)->FindClass(env,CB_CLASS);

                   if(jNativesCls==0)

                   {

                            jni_printf("Unable to find class %s",CB_CLASS);

                            return -1;

                   }

                   lib_main(clen,args);

                   return 0;

 

         }

         /**

          * 向java层返回一个字符串

          */

         jmethodID mSendStr;

         static void jni_send_str(const char *text,int level)

         {

                   JNIEnv *env;

                   if(!g_VM)

                   {

                            printf("I_JNI_NOVM:%s\n",text);

                            return ;

                   }

                   (*g_VM)->AttachCurrentThread(g_VM,(void **)&env,NULL);

                   if(!jNativesCls)

                   {

                            jNativesCls=(*env)->FindClass(env,CB_CLASS);

                            if(jNativesCls==0)

                            {

                                     printf("Unable to find class %s\n",CB_CLASS);

                                     return ;

                            }

                   }

                   if(!mSendStr)

                   {

                            mSendStr=(*env)->GetStaticMethodID(env,jNativesCls,CB_CLASS_CB,CB_CLASS_MSG_SIG);

 

                   }

                   if(mSendStr)

                   {

                            (*env)->CallStaticVoidMethod(env,jNativesCls,mSendStr,(*env)->NewStringUTF(env,text),(jint) level);

 

                   }else

                   {

                            printf("Unable to find method :%s,signature :%s \n",CB_CLASS_CB,CB_CLASS_MSG_SIG);

 

                   }

         }

 

         void jni_printf(char *format,...)

         {

                   va_list argptr;

                   static char string[1024];

                   va_start(argptr,format);

                   vsprintf(string,format,argptr);

                   va_end(argptr);

                   jni_send_str(string,0);

         }

 

         const int getArrayLen(JNIEnv *env,jobjectArray jarray)

         {

                   return (*env)->GetArrayLength(env,jarray);

         }

 

         int lib_main(int argc,char **argv)

         {

                   int i;

                   jni_printf("Enteing LIB MAIN");

                   for(i=0;i<argc;i++)

                   {

                            jni_printf("LIB MAIN argv[%d]=%s",i,argv[i]);

                   }

                   return 0;

         }

至此,完成了java c语言的互掉,最主要的是实现了原生层日志打印的功能,这个功能可以为今后开发提供轻量级的日志调试功能!!

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值