直接上源码:
package com.mayj.dyhellojni;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.TextView;
public class MainActivity extends AppCompatActivity {
TextView textView;
TextView textViewSum;
static {
System.loadLibrary("FirstJni");
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
@Override
protected void onResume() {
super.onResume();
textView = findViewById(R.id.text_id);
textViewSum = findViewById(R.id.text_sum);
textView.setText(JniClient.getInstance().getStr());
textViewSum.setText("" + JniClient.getInstance().addInt(2, 4));
}
}
package com.mayj.dyhellojni;
/**
* Created by Administrator on 2018/5/20 0020.
*/
public class JniClient {
public native String getStr();
public native int addInt(int a, int b);
static private JniClient instance = null;
static public JniClient getInstance(){
if (null == instance){
instance = new JniClient();
}
return instance;
}
}
Android.mk内容:
# 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)
LOCAL_MODULE := FirstJni
LOCAL_SRC_FILES := JniClient.c
include $(BUILD_SHARED_LIBRARY)
Application.mk内容:
APP_MODULES := FirstJni
APP_STL := stlport_static
APP_PLATFORM=android-16
APP_OPIM :=debug
APP_ABI := armeabi armeabi-v7a
JniClient.c源码如下:
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <jni.h>
#include <assert.h>
#define JNIREG_CLASS "com/mayj/dyhellojni/JniClient"//指定要注册的类
jstring get_str(JNIEnv* env, jobject thiz)
{
return (*env)->NewStringUTF(env, "Hello, 动态注册JNI");
}
jint add_int(JNIEnv* env, jobject jobj, jint num1, jint num2){
return num1 + num2;
}
/**
* 方法对应表
*/
static JNINativeMethod gMethods[] = {
{"getStr", "()Ljava/lang/String;", (void*)get_str},
{"addInt", "(II)I", (void*)add_int},
};
/*
* 为某一个类注册本地方法
*/
static int registerNativeMethods(JNIEnv* env
, const char* className
, JNINativeMethod* gMethods, int numMethods) {
jclass clazz;
clazz = (*env)->FindClass(env, className);
if (clazz == NULL) {
return JNI_FALSE;
}
if ((*env)->RegisterNatives(env, clazz, gMethods, numMethods) < 0) {
return JNI_FALSE;
}
return JNI_TRUE;
}
/*
* 为所有类注册本地方法
*/
static int registerNatives(JNIEnv* env) {
return registerNativeMethods(env, JNIREG_CLASS, gMethods,
sizeof(gMethods) / sizeof(gMethods[0]));
}
/*
* System.loadLibrary("lib")时调用
* 如果成功返回JNI版本, 失败返回-1
*/
JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM* vm, void* reserved) {
JNIEnv* env = NULL;
jint result = -1;
if ((*vm)->GetEnv(vm, (void**) &env, JNI_VERSION_1_4) != JNI_OK) {
return -1;
}
assert(env != NULL);
if (!registerNatives(env)) {//注册
return -1;
}
//成功
result = JNI_VERSION_1_4;
return result;
}
module的 build.gradle 要修改:
把def ndkDir = 'C:\\Users\\Administrator\\AppData\\Local\\Android\\Sdk\\ndk-bundle' 改成你的ndk路径
apply plugin: 'com.android.application'
def ndkDir = 'C:\\Users\\Administrator\\AppData\\Local\\Android\\Sdk\\ndk-bundle'
android {
compileSdkVersion 26
defaultConfig {
applicationId "com.mayj.dyhellojni"
minSdkVersion 19
targetSdkVersion 26
versionCode 1
versionName "1.0"
}
sourceSets.main{
jni.srcDirs=[]//禁用as自动生成mk
//以下两种写法都是一样的效果
jniLibs.srcDir 'src\\main\\libs'
// jniLibs.srcDirs = ['src/main/libs']
}
clean.dependsOn 'cleanNative'
tasks.withType(JavaCompile) {
compileTask -> compileTask.dependsOn buildNative
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
task buildNative(type: Exec, description: 'Compile JNI source via NDK') {
commandLine "$ndkDir\\ndk-build.cmd",
'-C', file('src\\main\\jni').absolutePath, // Change src/main/jni the relative path to your jni source
'-j', Runtime.runtime.availableProcessors(),
'all',
'NDK_DEBUG=1'
}
task cleanNative(type: Exec, description: 'Clean JNI object files') {
commandLine "$ndkDir\\ndk-build.cmd",
'-C', file('src\\main\\jni').absolutePath, // Change src/main/jni the relative path to your jni source
'clean'
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'com.android.support:appcompat-v7:26.1.0'
implementation 'com.android.support.constraint:constraint-layout:1.1.0'
}
源码路径: