zoukankan      html  css  js  c++  java
  • Android学习笔记—Windows下NDK开发简单示例

    该示例假设Android开发环境已经搭建完成,NDK也配置成功;

    1、在Eclipse上新建Android工程,名称为ndkdemo。修改reslayoutactivity_main.xml

    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context="${relativePackage}.${activityClass}" >
    
        <TextView
            android:id="@+id/result"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/hello_world" />
    
    </RelativeLayout>

    2、在工程src的com.example.ndkdemo目录下右键新建类NativeLoad.java内容如下

    package com.example.ndkdemo;
    
    public class NativeLoad {
    
        static {
            /*在静态块中加载底层so库*/
            System.loadLibrary("calculator");
        }
        
        /*声明native方法,其实现有C代码实现*/
        public static native int add(int x, int y);
        public static native int sub(int x, int y);
        public static native int mul(int x, int y);
        public static native int div(int x, int y);
    }

    3、修改com.example.ndkdemo目录下的MainActivity.java,使计算结果显示在屏幕上

    package com.example.ndkdemo;
    
    import android.app.Activity;
    import android.os.Bundle;
    import android.view.Menu;
    import android.view.MenuItem;
    import android.widget.TextView;
    
    public class MainActivity extends Activity {
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            
            TextView textView = (TextView)findViewById(R.id.result);
            
            textView.setText("100 + 10 = " + NativeLoad.add(100, 10) + "
    ");
            textView.append("100 - 10 = " + NativeLoad.sub(100, 10)  + "
    ");
            textView.append("100 * 10 = " + NativeLoad.mul(100, 10)  + "
    ");
            textView.append("100 / 10 = " + NativeLoad.div(100, 10)  + "
    ");
        }
    }

    4、命令行进入工程目录,执行javah命令,生成头文件

    javah -classpath src com.example.ndkdemo.NativeLoad
    javah -classpath binclasses com.example.ndkdemo.NativeLoad

    这一步用了好长时间,有的提示com.example.ndkdemo.NativeLoad没有找到,有的提示Android.app.Activity没有找到。

    在网上找的有的说进入到src目录执行该命令,有的说进入bin目录下执行。<Android框架揭秘>上说类生成的class文件在bincomexample dkdemo目录下;莫衷一是,现根据自己的理解总结如下

    • 在哪个目录执行不是关键,主要是-classpath参数后指定的目录,可以指定class文件所在的包,也可以指定java文件所在的包
    • 可能以前版本的目录结构是bincomexample dkdemo这样的,但是我的这个版本上在bin目录下有套了一个classes目录,是这样的binclassesscomexample dkdemo
    • 上述两条分别指定的是java文件所在的包和生成的class文件所在包
    • classpath不是指定类所在的目录,而是指定类所在包的路径,及src或者binclassess目录下

    5、在工程上右键新建jni目录,在jni目录中新建calculator.c文件,内容如下

    #include <jni.h>
    
    JNIEXPORT jint JNICALL Java_com_example_ndkdemo_NativeLoad_add
      (JNIEnv *env, jclass jclazz, jint x , jint y)
    {
        return x + y;
    }
    
    /*
     * Class:     com_example_ndkdemo_NativeLoad
     * Method:    sub
     * Signature: (II)I
     */
    JNIEXPORT jint JNICALL Java_com_example_ndkdemo_NativeLoad_sub
      (JNIEnv *env, jclass jclazz, jint x , jint y)
    {
        return x - y;
    }
    
    /*
     * Class:     com_example_ndkdemo_NativeLoad
     * Method:    mul
     * Signature: (II)I
     */
    JNIEXPORT jint JNICALL Java_com_example_ndkdemo_NativeLoad_mul
      (JNIEnv *env, jclass jclazz, jint x , jint y)
    {
        return x * y;
    }
    
    /*
     * Class:     com_example_ndkdemo_NativeLoad
     * Method:    div
     * Signature: (II)I
     */
    JNIEXPORT jint JNICALL Java_com_example_ndkdemo_NativeLoad_div
      (JNIEnv *env, jclass jclazz, jint x , jint y)
    {
        return x/y;
    }

    6、在jni目录下新建编译脚本Android.mk

    LOCAL_PATH := $(call my-dir)
    
    include $(CLEAR_VARS)
    
    LOCAL_MODULE := calculator
    LOCAL_SRC_FILES := calculator.c
    
    include $(BUILD_SHARED_LIBRARY)

    LOCAL_PATH: 指定NDK编译的基本文件目录,my-dir是一个宏定义,用户返回mk文件所在的目录;这句话的意思是将$(call my-dir)获取的mk所在路径追加给LOCAL_PATH

    include $(CLEAR_VARS) : 用来初试化mk文件中以LOCAL_XXX格式的变量,作为全局变量

    LOCAL_MODULE:即生成的动态库的名称,必须与Java代码中System.loadLibrary中的名称保持一致

    LOCAL_SRC_FILES:生成动态库所需要的源码文件

    include $(BUILD_SHARED_LIBRARY): 要创建的是libXXX.so格式的动态库

    7、命令行进入工程所在目录,执行ndk-build命令,即在libs目录下生成相应的动态库文件,此时目录结构如下图所示

     image

    8、在工程上右键->run as->Android Application即可在真机上运行,运行结果如下图所示

    image

  • 相关阅读:
    UVa 1151 Buy or Build【最小生成树】
    UVa 216 Getting in Line【枚举排列】
    UVa 729 The Hamming Distance Problem【枚举排列】
    HDU 5214 Movie【贪心】
    HDU 5223 GCD
    POJ 1144 Network【割顶】
    UVa 11025 The broken pedometer【枚举子集】
    HDU 2515 Yanghee 的算术【找规律】
    Java基本语法
    Java环境变量,jdk和jre的区别,面向对象语言编程
  • 原文地址:https://www.cnblogs.com/gordon0918/p/5146148.html
Copyright © 2011-2022 走看看