Ubuntu 12.04 搭建ndk编译环境
| 
                         搭建ndk环境之前,请保证你能新建android项目并能在手机上正常运行 通过AS自动生成ndk环境更新AS到较新的版本,通过File-setting-Androd SDK下载sdktools(这里不需要启动manager界面)  然而,实际运行总那么不尽人意。下面讲讲本人在配置环境是遇到的坑。 坑1:cmake 3.6.3155560 报错,GLIBCXX_2.4.18 required by cmake  $ alien ***.rpm  但在没root权限的linux中,就算将alien安装成功,执行alien 转换 rpm安装包也会失败,非root用户不能转换文件格式。  直接使用ndk build坑2:将java文件生成h头文件失败  
 .h文件生成后,就开始写C(/C++)代码了 此时,你已经能得到一个h文件,里面包含了你声明的public native method(只是看起来怪怪的,仔细看你就能看懂了)。 /* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class com_lintan_jniapplication_JniJava */
#ifndef _Included_com_lintan_jniapplication_JniJava
#define _Included_com_lintan_jniapplication_JniJava
#ifdef __cplusplus
extern "C" {
#endif
/* * Class: com_lintan_jniapplication_JniJava * Method: max * Signature: (II)I */
JNIEXPORT jint JNICALL Java_com_lintan_jniapplication_JniJava_max
  (JNIEnv *,jobject,jint,jint);
/* * Class: com_lintan_jniapplication_JniJava * Method: strFromJni * Signature: ()Ljava/lang/String; */
JNIEXPORT jstring JNICALL Java_com_lintan_jniapplication_JniJava_strFromJni
  (JNIEnv *,jobject);
#ifdef __cplusplus
}
#endif
#endif 
 第15行末尾就是你的method名字,com开始就是你的包名类名等  package com.lintan.jniapplication;
/** * Created by **** on 11/5/16. */
public class JniJava {
    /** * 返回两个整数中较大的一个 */
    public native int max(int a,int b);
    /** * 看看熟悉的Hello World */
    public native String strFromJni();
} 
 此时,你需要创建一个jni(cpp 也行)的文件夹,路径为”src/main/jni”  //
// Created by **** on 11/5/16.
//
#include <jni.h>
#include "com_lintan_jniapplication_JniJava.h"
JNIEXPORT jint JNICALL Java_com_lintan_jniapplication_JniJava_max
        (JNIEnv * env,jobject obj,jint a,jint b) {
    return (a > b) ? a : b;
}
JNIEXPORT jstring JNICALL Java_com_lintan_jniapplication_JniJava_strFromJni
        (JNIEnv * env,jobject obj) {
    return env->NewStringUTF("Hello World"); 
 到这一步,代码写完了,怎么才能让java调用到这个max方法呢? 干货内容  #以下两行代码必须,call my-dir 将返回Android.mk所在的目录 LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) # native这个单词要记住了,你以后添加的就是这个库 LOCAL_MODULE := "native" # hello 这个是一个名字,可以随便起一个,此行代码也可以不要,注释而已 LOCAL_PACKAGE_NAME := hello #这个就是C(CPP)文件了,里面是你的native方法的实现 LOCAL_SRC_FILES := CalculateTest.cpp # 编译成共享库 include $(BUILD_SHARED_LIBRARY) 此时还没完,因为只告诉了需要编译,要编译出那些平台的呢,因此还需要在新建一个Application.mk的文件,编译出多个平台的so #注意字别写错了,平台之间用空格隔开。 #就算ndk-build 没报错,在点击AS的Build是会报错, #错误内容,大概是就setup.mk 说PROJECT_PATH NULL,这里注意。 #笔者当时将x86_64敲成了x86_62。。。 APP_ABI := x86_64 armeabi armeabi-v7a arm64-v8a x86 mips 然后ndk-build,成功后,你会发现在你的IDE工程窗口多一个libs目录,且里面就是你编译出来的so依赖库 好了,你可以用你的native方法了,笔者使用native方法的代码为: static {
        //加载你的so
        //libs文件夹下的so名字是添加了前缀的,不用管。
        System.loadLibrary("native");
    }
    // 这是包含native方法的类
    JniJava jniJava = new JniJava();
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        TextView tv = (TextView) findViewById(R.id.test);
        //调用max方法
        String txt = jniJava.strFromJni() + " from Jni !";
        tv.setText(txt);
    } 
 保险起见,还是在app的build.gradle文件(不是project的build.gradle)里添加依赖 compile fileTree(dir: 'libs',include: ['*.jar','**/*.so']) 此时,你可以尝试AS的build,没问题。  找不到这个so,哦,AS在Run的时候,还是已gradle的方式编译+run,那么,我们ndk编译出来的so不认识吗? 因此要告诉gradle(在app build.gradle)defaultConfig下添加如下代码 ndk{
        moduleName "native"
        abiFilters("x86","x86_64","armeabi","armeabi-v7a","arm64-v8a","mips","mips64")
    } 
 到此,点击AS的熟悉Run绿色三角形箭头,success ! 如果有讲得不对的地方,欢迎大家提出来,共同学习, 谢谢! (编辑:莱芜站长网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!  | 
                  
