zoukankan      html  css  js  c++  java
  • 《Android进阶》之第七篇 NDK的使用

    《Android进阶》之第一篇 在Java中调用C库函数

    这一篇列举的方法是在NDK没有出来时候用的方式

    在Android发布NDK之后,可以这样使用

    一、首先下载android-ndk
     
    下载后把压缩包解压出来,例如:D:android-ndk-r10e,目录下的ndk-build.cmd就是用来编译的批处理命令。

     为了编译方便,推荐添加环境变量

    Path目录下添加D:android-ndk-r10e;

    以NDK自带的例子sampleshello-jni为例

    将例子导入安卓工程:

    HelloJni.java如下:

    /*
     * Copyright (C) 2009 The Android Open Source Project
     *
     * Licensed under the Apache License, Version 2.0 (the "License");
     * you may not use this file except in compliance with the License.
     * You may obtain a copy of the License at
     *
     *      http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     * See the License for the specific language governing permissions and
     * limitations under the License.
     */
    package com.example.hellojni;
    
    import android.app.Activity;
    import android.widget.TextView;
    import android.os.Bundle;
    
    
    public class HelloJni extends Activity
    {
        /** Called when the activity is first created. */
        @Override
        public void onCreate(Bundle savedInstanceState)
        {
            super.onCreate(savedInstanceState);
    
            /* Create a TextView and set its content.
             * the text is retrieved by calling a native
             * function.
             */
            TextView  tv = new TextView(this);
            tv.setText( stringFromJNI() );
            setContentView(tv);
        }
    
        /* A native method that is implemented by the
         * 'hello-jni' native library, which is packaged
         * with this application.
         */
        public native String  stringFromJNI();
    
        /* This is another native method declaration that is *not*
         * implemented by 'hello-jni'. This is simply to show that
         * you can declare as many native methods in your Java code
         * as you want, their implementation is searched in the
         * currently loaded native libraries only the first time
         * you call them.
         *
         * Trying to call this function will result in a
         * java.lang.UnsatisfiedLinkError exception !
         */
        public native String  unimplementedStringFromJNI();
    
        /* this is used to load the 'hello-jni' library on application
         * startup. The library has already been unpacked into
         * /data/data/com.example.hellojni/lib/libhello-jni.so at
         * installation time by the package manager.
         */
        static {
            System.loadLibrary("hello-jni");
        }
    }

    观察上面代码会发现:

    有个导入 System.loadLibrary的过程

    还定义了两个Nativie函数

    在查看其中的c源文件

    /*
     * Copyright (C) 2009 The Android Open Source Project
     *
     * Licensed under the Apache License, Version 2.0 (the "License");
     * you may not use this file except in compliance with the License.
     * You may obtain a copy of the License at
     *
     *      http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     * See the License for the specific language governing permissions and
     * limitations under the License.
     *
     */
    #include <string.h>
    #include <jni.h>
    
    /* This is a trivial JNI example where we use a native method
     * to return a new VM String. See the corresponding Java source
     * file located at:
     *
     *   apps/samples/hello-jni/project/src/com/example/hellojni/HelloJni.java
     */
    jstring
    Java_com_example_hellojni_HelloJni_stringFromJNI( JNIEnv* env,
                                                      jobject thiz )
    {
    #if defined(__arm__)
      #if defined(__ARM_ARCH_7A__)
        #if defined(__ARM_NEON__)
          #if defined(__ARM_PCS_VFP)
            #define ABI "armeabi-v7a/NEON (hard-float)"
          #else
            #define ABI "armeabi-v7a/NEON"
          #endif
        #else
          #if defined(__ARM_PCS_VFP)
            #define ABI "armeabi-v7a (hard-float)"
          #else
            #define ABI "armeabi-v7a"
          #endif
        #endif
      #else
       #define ABI "armeabi"
      #endif
    #elif defined(__i386__)
       #define ABI "x86"
    #elif defined(__x86_64__)
       #define ABI "x86_64"
    #elif defined(__mips64)  /* mips64el-* toolchain defines __mips__ too */
       #define ABI "mips64"
    #elif defined(__mips__)
       #define ABI "mips"
    #elif defined(__aarch64__)
       #define ABI "arm64-v8a"
    #else
       #define ABI "unknown"
    #endif
    
        return (*env)->NewStringUTF(env, "Hello from JNI !  Compiled with ABI " ABI ".");
    }
    因为我们是拿这个c源码文件来使用,如果迁就Java_com_example_hellojni_HelloJni_stringFromJNI
    函数名的话,在我们的android工程中java类的声明就要是:com/example/hellojni/HelloJni.java。
     
    二、编译,打开cmd命令行窗口
    D:>cd D:android-ndk-r10esampleshello-jnijni
    
    D:android-ndk-r10esampleshello-jnijni>ndk-build
    [arm64-v8a] Gdbserver      : [aarch64-linux-android-4.9] libs/arm64-v8a/gdbserve
    r
    [arm64-v8a] Gdbsetup       : libs/arm64-v8a/gdb.setup
    [x86_64] Gdbserver      : [x86_64-4.9] libs/x86_64/gdbserver
    [x86_64] Gdbsetup       : libs/x86_64/gdb.setup
    [mips64] Gdbserver      : [mips64el-linux-android-4.9] libs/mips64/gdbserver
    [mips64] Gdbsetup       : libs/mips64/gdb.setup
    [armeabi-v7a] Gdbserver      : [arm-linux-androideabi-4.8] libs/armeabi-v7a/gdbs
    erver
    [armeabi-v7a] Gdbsetup       : libs/armeabi-v7a/gdb.setup
    [armeabi] Gdbserver      : [arm-linux-androideabi-4.8] libs/armeabi/gdbserver
    [armeabi] Gdbsetup       : libs/armeabi/gdb.setup
    [x86] Gdbserver      : [x86-4.8] libs/x86/gdbserver
    [x86] Gdbsetup       : libs/x86/gdb.setup

    编译成功会在D:~sampleshello-jnilibsarmeabi目录下生成libhello-jni.so文件。

    不光是armeabi 其他所有平台都会生成.so文件

    现在程序就能运行啦

    stringFromJNI()其实调用的是.so文件中的方法
    程序运行结果:

  • 相关阅读:
    告别alert,拥抱console
    LeetCode之Max Points on a Line Total
    LeetCode之Maximum Product Subarray
    LeetCode之Reverse Words in a String
    LeetCode之Min Stack
    MySQL之系系统信息函数
    MySQL之日期时间函数
    MysqL之数值函数
    XML文件解析之JDOM解析
    XML文件解析之DOM4J解析
  • 原文地址:https://www.cnblogs.com/hixin/p/4775901.html
Copyright © 2011-2022 走看看