您的位置:首页 > 移动开发 > Android开发

Android Studio开发NDK工程

2017-02-25 11:05 309 查看

14 JNI与NDK编程

Java的跨平台特性导致其本地交互的能力不够强大,一些和操作系统相关的特性Java无法完成,于是Java提供了JNI专门用于和本地代码交互。通过Java JNI,用户可以调用C、C++所编写的本地代码。
NDK是Android所提供的一个工具集合,通过NDK可以再Android中更加方便地通过JNI来访问本地代码(C/C++)。NDK还提供了交叉编译器,开发人员只需要简单修改mk文件就可以生成特定CPU平台的动态库。NDK的用途和优点:
代码的保护。由于apk的java层代码很容易被反编译,而C/C++库反汇难度较大。
可以方便地使用C/C++开源库。
便于移植,用C/C++写的库可以方便在其他平台上再次使用
提供程序在某些特定情形下的执行效率,但是并不能明显提升Android程序的性能。

14.1 JNI的开发流程

在Java中声明natvie方法
用C/C++实现natvie方法
编译运行

14.2 NDK的开发流程

1 下载并配置NDK

下载好NDK开发包,并且配置好NDK的全局变量。

2 创建一个Android项目,并声明所需的native方法

public static native String getStringFromC();

3 实现Android项目中所声明的native方法

生成C/C++的头文件
打开控制台,用cd命令切换到当前项目当前目录

使用javah命令生成头文件
这步可以不要,利用Android Studio ctrl+1提示,自动生成头
javah -classpath bin\classes;C:\MOX\AndroidSDK\platforms\android-23\android.jar -d jni cn.hudp.hellondk.MainActivity


说明:bin\classes 为项目的class文件的相对路径 ; C:\MOX\AndroidSDK\platforms\android-23\android.jar 为android.jar的全路径,因为我们的的Activity使用到了Android SDK,所以生成头文件时需要他; -d jni就是生成的头文件输出到项目的jni文件夹下; 最后跟的cn.hudp.hellondk.MainActivity是native方法所在的类的包名和类名。

编写修改对应的android.mk文件(mk文件是NDK开发所用到的配置文件)
# 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.
#
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
## **看这里看这里** 对应Java部分 System.loadLibrary(String libName) 的libname
LOCAL_MODULE    := hello
## **看这里看这里** 对应c/c++的实现文件名,请看图2
LOCAL_SRC_FILES := hello.c
include $(BUILD_SHARED_LIBRARY)


编写Application.mk,来指定需生成的平台对应的动态库,这里是全平台支持,也可以特殊指定。
APP_ABI := all

4 切换到jni目录的父目录,然后通过ndk-build命令编译产生so库

ndk-build
命令会默认指定jni目录为本地源码的目录

将编译好的so库放到Android项目中的
app/src/main/jniLbis
目录下,或者通过如下app的gradle设置新的存放so库的目录:
android{
……
sourceSets.main{
jniLibs.srcDir 'src/main/jni_libs'
}
}

还可以通过
defaultConfig
区域添加NDK选项
android{
……
defaultConfig{
……
ndk{
moduleName "jni-test"
}
}
}


这步可以不要:还可以在
productFlavors
设置动态打包不同平台CPU对应的so库进apk(缩小APK体积)
```gradle
android{
……
productFlavors{
arm{
ndk{
adiFilter "armeabi"
}
}
x86{
ndk{
adiFilter "x86"
}
}
}
}
```

5 在Android中调用

public class MainActivity extends Activity {
public static native String getStringFromC();static{//在静态代码块中调用所需要的so文件,参数对应.so文件所对应的LOCAL_MODULE;
System.loadLibrary("hello");
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//在需要的地方调用native方法
Toast.makeText(getApplicationContext(), get(), Toast.LENGTH_LONG).show();
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: