android中的jni两种注册时机 base/core/jni & base/service/core/jni

https://www.jianshu.com/p/91321134207b

1基本要点

  • JavaVM:表示Java虚拟机。
  • JNIEnv:表示JNI环境的上下文,例如注册、查找类、异常等。
  • jclass:在JNI中表示的Java类。
  • jmethodID:在JNI中表示的Java类中的方法。
  • jfiledID:在JNI中表示的Java类中的属性。
  • 线程:JNI中通过AttachCurrentThread和DetachCurrentThread方法,实现和Java线程的结合。

它们都在一个叫jni.h的头文件中,这个头文件是JNI机制中很重要的一个头文件

/libnativehelper/include/nativehelper/jni.h

在libnativehelper目录下的源文件,编译后会生成一个libnativehelper.so的动态库。其实,jni.h是Android根据Java本地调用的标准写成的一个头文件,在它里面包括了基本类型(类型的映射),以及JavaVM,JNIEnv,jclass,jmethodID,jfiledID等数据结构的定义。

JavaVM对应于jni.h中JNIInvokeInterface结构体,表示虚拟机。JNIEnv对应于JNINativeInterface结构体,表示JNI的环境。在JNI的使用过程中,所调用的功能大都来自JNINativeInterface结构体。例如,处理Java属性和方法的查找,Java属性的访问,Java方法的调用等功能。另外,在JNINativeInterface结构体中,涉及到的一个JNINativeMethod结构体,它表示在本地实现的一个方法,即native方法,后面进行JNI注册的时候会用到。

在Android框架中,JNI库是一些普通的本地动态库,被放置在目标系统的/system/lib目录中。Java框架层,最主要的JNI内容源代码路径为:/frameworks/base/core/jni。 这里面的代码会生成一个libandroid_runtime.so的动态库。接下来要分析的Log中JNI的使用,就在这个目录之中。

2. android 中的jni

在Android框架中,JNI库是一些普通的本地动态库,被放置在目标系统的/system/lib目录中。
Java框架层,最主要的JNI内容源代码路径为:/frameworks/base/core/jni。
这里面的代码会生成一个libandroid_runtime.so的动态库。接下来要分析的Log中JNI的使用,就在这个目录之中。

2.1Framework base/core/jni 机制

  • Java框架层,最主要的JNI内容源代码路径为:/frameworks/base/core/jni,编译生成libandroid_runtime.so的动态库

  • 以Log为例:

    • /frameworks/base/core/java/android/util/Log.java 都会走println_native->android_util_Log_println_native

    • //frameworks/base/core/jni/android_util_Log.cpp。
      /*
       * JNI registration.
       */
      static const JNINativeMethod gMethods[] = {
          /* name, signature, funcPtr */
          { "isLoggable",      "(Ljava/lang/String;I)Z", (void*) android_util_Log_isLoggable },
          { "println_native",  "(IILjava/lang/String;Ljava/lang/String;)I", (void*) android_util_Log_println_native },
          { "logger_entry_max_payload_native",  "()I", (void*) android_util_Log_logger_entry_max_payload_native },
      };
      //android_util_Log.h
      typedef struct {
          const char* name;  //native方法名
          const char* signature; //参数,返回值,jni签名为了支持函数重载  (参数1类型标示;参数2类型标示;参数3类型标示...)返回值类型标示
          void*       fnPtr;//函数指针,指向这个natve对应的jni函数
      } JNINativeMethod;
      
    • println_native------>jni实现函数android_util_Log_println_native()---->native 的liblog库 __android_log_buf_write()

    • jni注册

      //android_util_Log.cpp
      int register_android_util_Log(JNIEnv* env)
      {
          jclass clazz = FindClassOrDie(env, "android/util/Log");
      
          levels.verbose = env->GetStaticIntField(clazz, GetStaticFieldIDOrDie(env, clazz, "VERBOSE", "I"));
        levels.debug = env->GetStaticIntField(clazz, GetStaticFieldIDOrDie(env, clazz, "DEBUG", "I"));
          levels.info = env->GetStaticIntField(clazz, GetStaticFieldIDOrDie(env, clazz, "INFO", "I"));
        levels.warn = env->GetStaticIntField(clazz, GetStaticFieldIDOrDie(env, clazz, "WARN", "I"));
          levels.error = env->GetStaticIntField(clazz, GetStaticFieldIDOrDie(env, clazz, "ERROR", "I"));
          levels.assert = env->GetStaticIntField(clazz, GetStaticFieldIDOrDie(env, clazz, "ASSERT", "I"));
      //RegisterMethodsOrDie()函数做了什么  后文分析
          return RegisterMethodsOrDie(env, "android/util/Log", gMethods, NELEM(gMethods));
      }
      
      
    • register_android_util_Log 被谁调用?

      cgrep register_android_util_Log 搜索

      /frameworks/base/include/android_runtime/AndroidRuntime.h。
      /frameworsk/base/core/jni/AndroidRuntime.cpp。

      //AndroidRuntime.cpp  ,gRegJNI数组
      static const RegJNIRec gRegJNI[] = {
          REG_JNI(register_com_android_internal_os_RuntimeInit),
        	REG_JNI(register_android_os_SystemClock),
          REG_JNI(register_android_util_EventLog),
        	REG_JNI(register_android_util_Log),
          REG_JNI(register_android_util_MemoryIntArray),
          //省略
      }
      
      /*
       * Register android native functions with the VM.
       */
      /*static*/ int AndroidRuntime::startReg(JNIEnv* env)
      {
          ATRACE_NAME("RegisterAndroidNatives");
      ...
      	//gRegJNI
          if (register_jni_procs(gRegJNI, NELEM(gRegJNI), env) < 0) {
              env->PopLocalFrame(NULL);
              return -1;
          }
          return 0;
      }
      //frameworks/base/core/jni/core_jni_helpers.h
      static inline int RegisterMethodsOrDie(JNIEnv* env, const char* className,
                                             const JNINativeMethod* gMethods, int numMethods) {
          int res = AndroidRuntime::registerNativeMethods(env, className, gMethods, numMethods);
          LOG_ALWAYS_FATAL_IF(res < 0, "Unable to register native methods.");
          return res;
      }
      //最终调用  libnativehelper/JNIHelp.cpp  的jniRegisterNativeMethods方法
      extern "C" int jniRegisterNativeMethods(C_JNIEnv* env, const char* className,
          const JNINativeMethod* gMethods, int numMethods)
      {
          JNIEnv* e = reinterpret_cast<JNIEnv*>(env);
      
          ALOGV("Registering %s's %d native methods...", className, numMethods);
      
          return 0;
      }
      //startReg哪里来的呢zygote->AndroidRuntime::start()->AndroidRuntime::startReg()
      if (zygote) {
          runtime.start("com.android.internal.os.ZygoteInit", args, zygote);
      } else if (className) {
          runtime.start("com.android.internal.os.RuntimeInit", args, zygote);
      } else {
          fprintf(stderr, "Error: no class name or --zygote supplied.\n");
          app_usage();
          LOG_ALWAYS_FATAL("app_process: no class name or --zygote supplied.");
          return 10;
      }
      
  • 此外还有一种方式,

因为只在启动的时候注册必要的部分,其他部分在使用时随着加载过程进行动态注册。注意 registerNativeMethods JNI_OnLoad,且看后面详解。

//frameworks/base/service/core/jni/onload.cpp
extern "C" jint JNI_OnLoad(JavaVM* vm, void* /* reserved */)
{
    JNIEnv* env = NULL;
    jint result = -1;

    if (vm->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK) {
        ALOGE("GetEnv failed!");
        return result;
    }
    ALOG_ASSERT(env, "Could not retrieve the env!");

    register_android_server_ActivityManagerService(env);
    register_android_server_PowerManagerService(env);
    register_android_server_SerialService(env);
    register_android_server_InputApplicationHandle(env);
    register_android_server_InputWindowHandle(env);
。。。。。。。。。。。。。。。。。。。。。
    register_android_server_HardwarePropertiesManagerService(env);


    return JNI_VERSION_1_4;
}

//frameworks/base/media/jni/android_media_MediaPlayer.cpp
jint JNI_OnLoad(JavaVM* vm, void* /* reserved */)
{
    JNIEnv* env = NULL;
    jint result = -1;

    if (vm->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK) {
        ALOGE("ERROR: GetEnv failed\n");
        goto bail;
    }
    assert(env != NULL);

    if (register_android_media_ImageWriter(env) != JNI_OK) {
        ALOGE("ERROR: ImageWriter native registration failed");
        goto bail;
    }

    if (register_android_media_ImageReader(env) < 0) {
        ALOGE("ERROR: ImageReader native registration failed");
        goto bail;
    }

    if (register_android_media_MediaPlayer(env) < 0) {
        ALOGE("ERROR: MediaPlayer native registration failed\n");
        goto bail;
    }
    // 省略

    /* success -- return valid version number */
    result = JNI_VERSION_1_4;

bail:
    return result;
}


2.2 service的jni (另外一种方式)

先看下java框架组成

  • java框架库,framework.jar 系统核心,定义并实现andorid中大多数的java类,也提供作为标准

  • java服务库 service.jar,包含一些复杂服务,为框架层提供一部分功能的实现,服务库也具有java框架层中一个主要的程序入口,进入此入口运行后,服务库将形成java框架层一个在后台长时间运行的程序。

  • 资源包 framework-res.apk 没有java代码,纯资源组成的包,资源包是java框架层唯一的包含资源和工程描述文件的包。框架层所有的资源和组件定义均包含在资源包中。

  • 三个库之间耦合性比较像,且相互依赖。
    总结下上一节。

  • framework.jar 系统核心,

    • framework/base/core是主要目录,core目录下,jni包是同目录下java包中对应的jni实现,

      /frameworks/base/core/java/android/util/Log.java

      /frameworks/base/core/jni/android_util_Log.cpp

    • frameworks/base/core/jni/android_util_Log.cpp 实现jni,会生成一个libandroid_runtime.so动态库。启动zygote时,实例化AndroidRuntime.cpp类,将其中jni函数注册到虚拟机,所以core,media(部分),opengl等相关的JNI会在系统启动的时候进行注册

  • service.jar

    • Java框架层服务库部分的目录为:frameworks/base/services/java,同级目录下的Android.mk会将这个包编译,生成services.jar

    • frameworks/base/services/java/com/android/server中只包含一个入口部分的类 SystemServer.java SystemConfigService.java

      frameworks/base/services/core/java/com/android/server 其他类在这个目录下

    • service.jar的jni实现在frameworks/base/service/core/jni/com_android_server_xxx.cpp,其中内容生成libandroid_server.so的动态库。为service提供本地支持,这个库在frameworks/base/services/java/SystemServer.java类中被加载。注册示例:

      //frameworks/base/services/core/jni/com_android_server_ConsumerIrService.cpp
      namespace android {
      static jboolean getHidlHalService(JNIEnv * /* env */, jobject /* obj */) {。。。。}
      static const JNINativeMethod method_table[] = {
          /* name, signature, funcPtr */
              {"getHidlHalService", "()Z", (void *)getHidlHalService},
              {"halTransmit", "(I[I)I", (void *)halTransmit},
              {"halGetCarrierFrequencies", "()[I", (void *)halGetCarrierFrequencies},
      };
      int register_android_server_ConsumerIrService(JNIEnv *env) {
          return jniRegisterNativeMethods(env, "com/android/server/ConsumerIrService",
                  method_table, NELEM(method_table));
      }
      。。。。
      }
      

      生成libandroid_servers.so动态库,SystemServer main函数中加载libandroid_servers,调用其Onload,frameworks/base/service/core/jni/onload.cpp,将jni方法注册到java虚拟机中。

      //frameworks/base/services/core/jni/onload.cpp
      extern "C" jint JNI_OnLoad(JavaVM* vm, void* /* reserved */)
      {
         register_android_server_ConsumerIrService(env);     
      }
      
  • 此外,android框架层还包含其他jni实现库,比如,多媒体一部分jni实现在frameworks/base/media/jni/android_media_xxx.cpp,(一部分在libandroid_runtime.so中),生成libmedia.so,为framework.jar提供部分本地支持,(media目录划在了框架层的framework.jar部分)。这个动态库是在frameworks/base/media/java/android/media/MediaPlayer.java类中加载,加载本地库后,会执行其中的**JNI_OnLoad()**函数,进行JNI方法的注册。也就是说,程序在使用的时候进行加载,并进行jni注册。谷歌这样么做,是因为想在启动时注册必要的部分(zygote启动时实例化AndroidRuntime.cpp),其他部分随着加载so过程进行动态注册。

//frameworks/base/media/jni/android_media_MediaPlayer.cpp
	  jint JNI_OnLoad(JavaVM* vm, void* /* reserved */)
	  {
	      JNIEnv* env = NULL;
	      jint result = -1;
	  
	      if (vm->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK) {
	          ALOGE("ERROR: GetEnv failed\n");
	          goto bail;
	      }
	      assert(env != NULL);
	  
	      if (register_android_media_ImageWriter(env) != JNI_OK) {
	          ALOGE("ERROR: ImageWriter native registration failed");
	          goto bail;
	      }
	      // 省略
	      result = JNI_VERSION_1_4;
	  
	  bail:
	      return result;
	  }
	  //frameworks/base/media/java/android/media/MediaPlayer.java
	  static {
	      System.loadLibrary("media_jni");
	      native_init();
	  }

Java层调用System.loadLibrary()方法加载动态函数库时,执行JNI_OnLoad()函数,完成各个JNI方法的动态注册,这和前面Log相关的JNI方法注册稍有不同

下一篇jni详解

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
JDKTM 6 Documentation Legal Notices API, Language, and VM Specs Features Guides Release Notes Tool Docs Tutorials and Training JavaTM SE 6 Platform at a Glance This document covers the JavaTM Platform, Standard Edition 6 JDK. Its product version number is 6 and developer version number is 1.6.0, as described in Platform Name and Version Numbers. For information on a feature of the JDK, click on a component in the diagram below. JDK Java Language Java Language Tools & Tool APIs java javac javadoc apt jar javap JPDA jconsole Security Int'l RMI IDL Deploy Monitoring Troubleshoot Scripting JVM TI JRE Deployment Technologies Deployment Java Web Start Java Plug-in User Interface Toolkits AWT Swing Java 2D Accessibility Drag n Drop Input Methods Image I/O Print Service Sound Java SE API Integration Libraries IDL JDBCTM JNDITM RMI RMI-IIOP Scripting Other Base Libraries Beans Intl Support I/O JMX JNI Math Networking Override Mechanism Security Serialization Extension Mechanism XML JAXP lang and util Base Libraries lang and util Collections Concurrency Utilities JAR Logging Management Preferences API Ref Objects Reflection Regular Expressions Versioning Zip Instrument Java Virtual Machine Java HotspotTM Client VM Java HotspotTM Server VM Platforms SolarisTM Linux Windows Other -------------------------------------------------------------------------------- Release Notes Topics include New Features, Known Issues, Compatibility with Prior Releases, Supported System Configurations, Installation, and More) -------------------------------------------------------------------------------- API, Language, and Virtual Machine Documentation Java Platform API Specification (NO FRAMES) (included in the JDK documentation bundle and on java.sun.com ) Note About sun.* Packages The Java Language Specification (DOWNLOAD) The Java Virtual Machine Specification (DOWNLOAD) -------------------------------------------------------------------------------- Features Reference Guides - Java Platform All guides listed are included in the documentation download bundle as well as the java.sun.com website (unless otherwise noted). Java SE 6 Overview New Features and Enhancements (available only on the java.sun.com website) Java Language Java Programming Language Virtual Machine Virtual Machine Base Libraries java.lang, java.util Packages Instrumentation Language and Utility Packages Monitoring and Management Package Version Identification Reference Objects Reflection Collections Framework Concurrency Utilities Java Archive (JAR) Files Logging Preferences Regular Expressions Zip Files Other packages Math I/O Object Serialization Networking Endorsed Standards Override Mechanism Extension Mechanism Internationalization JavaBeansTM Component API Java Management Extensions (JMX) Java Native Interface (JNI) Security XML (JAXP) Integration Libraries Java Database Connectivity (JDBCTM) Java IDL Java Naming and Directory InterfaceTM (JNDI) Remote Method Invocation (RMI) RMI-IIOP Scripting for the Java Platform User Interface Libraries 2D Graphics and Imaging Accessibility Abstract Window Toolkit (AWT) Drag-and-Drop Data Transfer Image I/O Input Method Framework Print Service Sound Swing Components Deployment General Deployment Java Plug-in Java Web Start Tools Annotation Processing Tool Attach API javac Tool Javadoc Tool Java Platform Debugger Architecture (JPDA) Java Debug Interface (JDI) Java Debug Wire Protocol (JDWP) JVMTM Tool Interface (JVM TI) (replaces JVMPI and JVMDI) -------------------------------------------------------------------------------- JDK Tools and Utilities Reference documentation for the JDK tools and utilities. JDK Tool and Utility Documentation Including Troubleshooting and Diagnostic Information -------------------------------------------------------------------------------- Tutorials, Training, Demos, Samples, and Other Information Learning about Java. The Java Tutorial An example-filled guide to the Java programming language and core APIs. Java Technology Home Page Training for the Java programming language Directory of various training resources. Demonstration Applets and Applications (included in the JDK documentation bundle and on java.sun.com ) On-Line Courses for the Java Programming Language Java Web Start Samples (included in the JDK documentation bundle and on java.sun.com ) Java Series Books Effective Java Best selling guide about best programming practices. Java Documentation in HTMLHelp and WinHelp Formats For Windows users. Code Conventions for the Java Programming Language Standards and styles for coding Java programs. New-to-JavaTM Programming Center. New to the Java Platform. Java™ Platform Standard Ed. 6 All Classes Packages java.applet java.awt java.awt.color java.awt.datatransfer java.awt.dnd java.awt.event java.awt.font java.awt.geom java.awt.im java.awt.im.spi java.awt.image java.awt.image.renderable java.awt.print java.beans java.beans.beancontext java.io java.lang java.lang.annotation java.lang.instrument java.lang.management java.lang.ref java.lang.reflect java.math java.net java.nio java.nio.channels java.nio.channels.spi java.nio.charset java.nio.charset.spi java.rmi java.rmi.activation java.rmi.dgc java.rmi.registry java.rmi.server java.security java.security.acl java.security.cert java.security.interfaces java.security.spec java.sql java.text java.text.spi java.util java.util.concurrent java.util.concurrent.atomic java.util.concurrent.locks java.util.jar java.util.logging java.util.prefs java.util.regex java.util.spi java.util.zip javax.accessibility javax.activation javax.activity javax.annotation javax.annotation.processing javax.crypto javax.crypto.interfaces javax.crypto.spec javax.imageio javax.imageio.event javax.imageio.metadata javax.imageio.plugins.bmp javax.imageio.plugins.jpeg javax.imageio.spi javax.imageio.stream javax.jws javax.jws.soap javax.lang.model javax.lang.model.element javax.lang.model.type javax.lang.model.util javax.management javax.management.loading javax.management.modelmbean javax.management.monitor javax.management.openmbean javax.management.relation javax.management.remote javax.management.remote.rmi javax.management.timer javax.naming javax.naming.directory javax.naming.event javax.naming.ldap javax.naming.spi javax.net javax.net.ssl javax.print javax.print.attribute javax.print.attribute.standard javax.print.event javax.rmi javax.rmi.CORBA javax.rmi.ssl javax.script javax.security.auth javax.security.auth.callback javax.security.auth.kerberos javax.security.auth.login javax.security.auth.spi javax.security.auth.x500 javax.security.cert javax.security.sasl javax.sound.midi javax.sound.midi.spi javax.sound.sampled javax.sound.sampled.spi javax.sql javax.sql.rowset javax.sql.rowset.serial javax.sql.rowset.spi javax.swing javax.swing.border javax.swing.colorchooser javax.swing.event javax.swing.filechooser javax.swing.plaf javax.swing.plaf.basic javax.swing.plaf.metal javax.swing.plaf.multi javax.swing.plaf.synth javax.swing.table javax.swing.text javax.swing.text.html javax.swing.text.html.parser javax.swing.text.rtf javax.swing.tree javax.swing.undo javax.tools javax.transaction javax.transaction.xa javax.xml javax.xml.bind javax.xml.bind.annotation javax.xml.bind.annotation.adapters javax.xml.bind.attachment javax.xml.bind.helpers javax.xml.bind.util javax.xml.crypto javax.xml.crypto.dom javax.xml.crypto.dsig javax.xml.crypto.dsig.dom javax.xml.crypto.dsig.keyinfo javax.xml.crypto.dsig.spec javax.xml.datatype javax.xml.namespace javax.xml.parsers javax.xml.soap javax.xml.stream javax.xml.stream.events javax.xml.stream.util javax.xml.transform javax.xml.transform.dom javax.xml.transform.sax javax.xml.transform.stax javax.xml.transform.stream javax.xml.validation javax.xml.ws javax.xml.ws.handler javax.xml.ws.handler.soap javax.xml.ws.http javax.xml.ws.soap javax.xml.ws.spi javax.xml.xpath org.ietf.jgss org.omg.CORBA org.omg.CORBA_2_3 org.omg.CORBA_2_3.portable org.omg.CORBA.DynAnyPackage org.omg.CORBA.ORBPackage org.omg.CORBA.portable org.omg.CORBA.TypeCodePackage org.omg.CosNaming org.omg.CosNaming.NamingContextExtPackage org.omg.CosNaming.NamingContextPackage org.omg.Dynamic org.omg.DynamicAny org.omg.DynamicAny.DynAnyFactoryPackage org.omg.DynamicAny.DynAnyPackage org.omg.IOP org.omg.IOP.CodecFactoryPackage org.omg.IOP.CodecPackage org.omg.Messaging org.omg.PortableInterceptor org.omg.PortableInterceptor.ORBInitInfoPackage org.omg.PortableServer org.omg.PortableServer.CurrentPackage org.omg.PortableServer.POAManagerPackage org.omg.PortableServer.POAPackage org.omg.PortableServer.portable org.omg.PortableServer.ServantLocatorPackage org.omg.SendingContext org.omg.stub.java.rmi org.w3c.dom org.w3c.dom.bootstrap org.w3c.dom.events org.w3c.dom.ls org.xml.sax org.xml.sax.ext org.xml.sax.helpers
Java Native Interface(JNI)是Java平台的一项技术,它允许Java代码与本地代码(如C、C++)进行交互。在这种情况下,我们可以使用JNI来实现Base64加密和解密。 以下是一个示例代码,演示如何使用JNI实现Base64加密和解密: 1.创建一个名为"Base64.c"的C文件,其包含以下代码: #include<jni.h> #include<stdlib.h> #include<stdio.h> #include<errno.h> #include<string.h> #include<android/log.h> #include "android/bitmap.h" #include "android/log.h" #include "libjpeg/jpeglib.h" #include "com_example_bitmaptest_utils_CImageUtils.h" //Base64加密函数 JNIEXPORT jstring JNICALL Java_com_example_bitmaptest_utils_CImageUtils_encrypt(JNIEnv *env, jobject obj, jstring str) { const char *src = (*env)->GetStringUTFChars(env, str, NULL); if(src == NULL){ return NULL; } jsize len = (*env)->GetStringUTFLength(env, str); int mod = len % 3; int new_len = len + (mod == 0 ? 0 : (3 - mod)); unsigned char *input = (unsigned char *)malloc(new_len); memset(input, 0, new_len); memcpy(input, src, len); int i = 0, j = 0; unsigned char *output = (unsigned char *)malloc(new_len * 4 / 3); memset(output, 0, new_len * 4 / 3); while(i < new_len){ int c = input[i++] << 16 | input[i++] << 8 | input[i++]; output[j++] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"[c >> 18]; output[j++] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"[(c >> 12) & 0x3f]; output[j++] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"[(c >> 6) & 0x3f]; output[j++] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"[c & 0x3f]; } if(mod > 0){ output[new_len * 4 / 3 - 1] = '='; } if(mod == 1){ output[new_len * 4 / 3 - 2] = '='; } (*env)->ReleaseStringUTFChars(env, str, src); jstring result = (*env)->NewStringUTF(env, output); free(input); free(output); return result; } //Base64解密函数 JNIEXPORT jstring JNICALL Java_com_example_bitmaptest_utils_CImageUtils_decrypt(JNIEnv *env, jobject obj, jstring str) { const char *src = (*env)->GetStringUTFChars(env, str, NULL); if(src == NULL){ return NULL; } jsize len = (*env)->GetStringUTFLength(env, str); int new_len = len / 4 * 3; if(src[len - 1] == '='){ new_len--; } if(src[len - 2] == '='){ new_len--; } unsigned char *input = (unsigned char *)malloc(len); memset(input, 0, len); memcpy(input, src, len); int i = 0, j = 0; unsigned char *output = (unsigned char *)malloc(new_len); memset(output, 0, new_len); while(i < len){ unsigned char c[4]; int k = 0; while(k < 4 && i < len){ if(input[i] != '\n' && input[i] != '\r'){ c[k++] = input[i++]; }else{ i++; } } if(k == 4){ output[j++] = (c[0] << 2) | (c[1] >> 4); output[j++] = (c[1] << 4) | (c[2] >> 2); output[j++] = (c[2] << 6) | c[3]; } } (*env)->ReleaseStringUTFChars(env, str, src); jstring result = (*env)->NewStringUTF(env, output); free(input); free(output); return result; } 2.使用javac编译CImageUtils.java文件,生成CImageUtils.class文件。 3.使用javah命令生成.h头文件,命令为:javah -classpath . com.example.bitmaptest.utils.CImageUtils 4.将生成的CImageUtils.h文件拷贝到C文件所在目录下,并在C文件包含该头文件。 5.使用ndk-build命令编译C文件,生成动态库文件。 6.将生成的动态库文件拷贝到Android项目的libs目录下。 7.在Java代码调用JNI函数,例如: public class MainActivity extends AppCompatActivity { static { System.loadLibrary("base64"); } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); String str = "hello, world"; String encryptStr = CImageUtils.encrypt(str); Log.i("MainActivity", "encryptStr: " + encryptStr); String decryptStr = CImageUtils.decrypt(encryptStr); Log.i("MainActivity", "decryptStr: " + decryptStr); } } 通过以上步骤,我们就可以在Android项目使用JNI实现Base64加密和解密。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值