1. 程式人生 > >Android studio jni 入門helloworld

Android studio jni 入門helloworld

最近忙著面試 ,基本上每個面試官都會問一句 會不會jni?會不會ndk?像我這麼厲害的c和c++,難道真的要荒廢了嗎,說了你會別人又不聽,那麼 我就得寫個jni來試試了,說了這麼多,要不是一本正經的胡言亂語 我差點都信了 話不多說 開始擼碼
1:先建一個as project 這個就省略了,太難了 你們自己摸索
2: 建一個類 名字叫myJNI

package com.bril.jni;

/**
 * Created by brill on 2016/9/8.
 */
public class myJNI {

    static {
        System.loadLibrary("JniTest"
); } public static native String sayHello(); }

對了 先看下我的目錄結構
這裡寫圖片描述
我們繼續
3:開啟terminal 定位到 這個位置輸入 javac生成class檔案
C:\android\TestWork\Jni\app\src\main\java\com\bril\jni>javac myJNI.java
4:使用javah生成.h檔案 cd.. 到com的上層目錄

C:\android\TestWork\Jni\app\src\main\java>javah -jni com.bril.jni.myJNI

發現在java目錄下生成了.h檔案
這裡寫圖片描述
然後 new ->folder->jnifolder 然後勾點點 選擇finish
4:然後new -> c/c++ source file 輸入main 生成main.c
5:把那個生成的檔案內容全部拷進來 實現裡面的

JNIEXPORT jstring JNICALL Java_com_bril_jni_myJNI_sayHello
  (JNIEnv *, jclass);

Java_com_bril_jni_myJNI_sayHello根據每個人的專案路徑名不同 實現這個方法為

JNIEXPORT jstring JNICALL Java_com_bril_jni_myJNI_sayHello
        (JNIEnv *env, jclass jobj){
    return
(*env)->NewStringUTF(env,"vvvv lq"); }

6:再新建一個c/c++ source file 因為android studio的bug 必須下面放兩個檔案 所以。。。。
7 在app 下的gradle檔案下新增

 ndk {
            moduleName "JniTest"
            ldLibs "log", "z", "m"
            abiFilters "armeabi", "armeabi-v7a", "x86"
        }

我的gradle檔案

apply plugin: 'com.android.application'

android {
    compileSdkVersion 24
    buildToolsVersion "23.0.3"

    defaultConfig {
        applicationId "com.bril.jni"
        minSdkVersion 15
        targetSdkVersion 24
        versionCode 1
        versionName "1.0"
        ndk {
            moduleName "JniTest"
            ldLibs "log", "z", "m"
            abiFilters "armeabi", "armeabi-v7a", "x86"
        }
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
    sourceSets { main { jni.srcDirs = ['src/main/jni', 'src/main/jni/'] } }
}

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    testCompile 'junit:junit:4.12'
    compile 'com.android.support:appcompat-v7:24.2.0'
}

8:rebuild生成.so檔案 build->rebuild project
這裡寫圖片描述
9在main資料夾下建立 jinLIB資料夾 把.so按資料夾複製進去
這裡寫圖片描述
10呼叫jni

package com.bril.jni;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.TextView;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        TextView text = (TextView) findViewById(R.id.txt);
        text.setText(myJNI.sayHello());
    }
}

如果其中報錯的話看看 local.properties 和 gradle.properties
local.properties 檔案

## This file is automatically generated by Android Studio.
# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
#
# This file must *NOT* be checked into Version Control Systems,
# as it contains information specific to your local configuration.
#
# Location of the SDK. This is only used by Gradle.
# For customization when using a Version Control System, please read the
# header note.
#Thu Sep 08 10:12:30 SGT 2016
ndk.dir=C\:\\android\\sdk\\ndk-bundle
sdk.dir=C\:\\android\\sdk

gradle.properties 檔案

## Project-wide Gradle settings.
#
# For more details on how to configure your build environment visit
# http://www.gradle.org/docs/current/userguide/build_environment.html
#
# Specifies the JVM arguments used for the daemon process.
# The setting is particularly useful for tweaking memory settings.
# Default value: -Xmx10248m -XX:MaxPermSize=256m
# org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
#
# When configured, Gradle will run in incubating parallel mode.
# This option should only be used with decoupled projects. More details, visit
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
# org.gradle.parallel=true
#Thu Sep 08 10:34:51 SGT 2016
android.useDeprecatedNdk=true