NDK android studio中的java.lang.UnsatisfiedLinkError

时间:2016-04-25 13:07:22

标签: java android android-ndk

我正在尝试使用NDK创建一个简单的程序,但我一次又一次得到相同的错误我已经应用了堆栈溢出的所有解决方案,但我仍然得到相同的错误。尽管如此,我的代码正确编译并且我的库正确加载但是当我运行我的应用程序时它抛出“java.lang.UnsatisfiedLinkError”异常。这是我的完整代码。请帮助我。你的帮助将会受到欢迎

这是我的代码

package com.example.nasir.ndk2exmp;

import android.os.Bundle;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.Snackbar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.util.Log;
import android.view.View;
import android.view.Menu;
import android.view.MenuItem;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
        fab.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {

                Log.e("JNI Message", HelloJNI());
            }
        });
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();

        //noinspection SimplifiableIfStatement
        if (id == R.id.action_settings) {
            return true;
        }

        return super.onOptionsItemSelected(item);
    }
    static {
        System.loadLibrary("HelloJNI");
    }
    public native String HelloJNI();

}

这是我的头文件

#include <jni.h>


/* Header for class com_example_nasir_ndk2exmp_MainActivity */

#ifndef _Included_com_example_nasir_ndk2exmp_MainActivity
#define _Included_com_example_nasir_ndk2exmp_MainActivity
#ifdef __cplusplus
extern "C" {
#endif
#undef com_example_nasir_ndk2exmp_MainActivity_MODE_PRIVATE
#define com_example_nasir_ndk2exmp_MainActivity_MODE_PRIVATE 0L
#undef com_example_nasir_ndk2exmp_MainActivity_MODE_WORLD_READABLE
#define com_example_nasir_ndk2exmp_MainActivity_MODE_WORLD_READABLE 1L
#undef com_example_nasir_ndk2exmp_MainActivity_MODE_WORLD_WRITEABLE
#define com_example_nasir_ndk2exmp_MainActivity_MODE_WORLD_WRITEABLE 2L
#undef com_example_nasir_ndk2exmp_MainActivity_MODE_APPEND
#define com_example_nasir_ndk2exmp_MainActivity_MODE_APPEND 32768L
#undef com_example_nasir_ndk2exmp_MainActivity_MODE_MULTI_PROCESS
#define com_example_nasir_ndk2exmp_MainActivity_MODE_MULTI_PROCESS 4L
#undef com_example_nasir_ndk2exmp_MainActivity_MODE_ENABLE_WRITE_AHEAD_LOGGING
#define com_example_nasir_ndk2exmp_MainActivity_MODE_ENABLE_WRITE_AHEAD_LOGGING 8L
#undef com_example_nasir_ndk2exmp_MainActivity_BIND_AUTO_CREATE
#define com_example_nasir_ndk2exmp_MainActivity_BIND_AUTO_CREATE 1L
#undef com_example_nasir_ndk2exmp_MainActivity_BIND_DEBUG_UNBIND
#define com_example_nasir_ndk2exmp_MainActivity_BIND_DEBUG_UNBIND 2L
#undef com_example_nasir_ndk2exmp_MainActivity_BIND_NOT_FOREGROUND
#define com_example_nasir_ndk2exmp_MainActivity_BIND_NOT_FOREGROUND 4L
#undef com_example_nasir_ndk2exmp_MainActivity_BIND_ABOVE_CLIENT
#define com_example_nasir_ndk2exmp_MainActivity_BIND_ABOVE_CLIENT 8L
#undef com_example_nasir_ndk2exmp_MainActivity_BIND_ALLOW_OOM_MANAGEMENT
#define com_example_nasir_ndk2exmp_MainActivity_BIND_ALLOW_OOM_MANAGEMENT 16L
#undef com_example_nasir_ndk2exmp_MainActivity_BIND_WAIVE_PRIORITY
#define com_example_nasir_ndk2exmp_MainActivity_BIND_WAIVE_PRIORITY 32L
#undef com_example_nasir_ndk2exmp_MainActivity_BIND_IMPORTANT
#define com_example_nasir_ndk2exmp_MainActivity_BIND_IMPORTANT 64L
#undef com_example_nasir_ndk2exmp_MainActivity_BIND_ADJUST_WITH_ACTIVITY
#define com_example_nasir_ndk2exmp_MainActivity_BIND_ADJUST_WITH_ACTIVITY 128L
#undef com_example_nasir_ndk2exmp_MainActivity_CONTEXT_INCLUDE_CODE
#define com_example_nasir_ndk2exmp_MainActivity_CONTEXT_INCLUDE_CODE 1L
#undef com_example_nasir_ndk2exmp_MainActivity_CONTEXT_IGNORE_SECURITY
#define com_example_nasir_ndk2exmp_MainActivity_CONTEXT_IGNORE_SECURITY 2L
#undef com_example_nasir_ndk2exmp_MainActivity_CONTEXT_RESTRICTED
#define com_example_nasir_ndk2exmp_MainActivity_CONTEXT_RESTRICTED 4L
#undef com_example_nasir_ndk2exmp_MainActivity_RESULT_CANCELED
#define com_example_nasir_ndk2exmp_MainActivity_RESULT_CANCELED 0L
#undef com_example_nasir_ndk2exmp_MainActivity_RESULT_OK
#define com_example_nasir_ndk2exmp_MainActivity_RESULT_OK -1L
#undef com_example_nasir_ndk2exmp_MainActivity_RESULT_FIRST_USER
#define com_example_nasir_ndk2exmp_MainActivity_RESULT_FIRST_USER 1L
#undef com_example_nasir_ndk2exmp_MainActivity_DEFAULT_KEYS_DISABLE
#define com_example_nasir_ndk2exmp_MainActivity_DEFAULT_KEYS_DISABLE 0L
#undef com_example_nasir_ndk2exmp_MainActivity_DEFAULT_KEYS_DIALER
#define com_example_nasir_ndk2exmp_MainActivity_DEFAULT_KEYS_DIALER 1L
#undef com_example_nasir_ndk2exmp_MainActivity_DEFAULT_KEYS_SHORTCUT
#define com_example_nasir_ndk2exmp_MainActivity_DEFAULT_KEYS_SHORTCUT 2L
#undef com_example_nasir_ndk2exmp_MainActivity_DEFAULT_KEYS_SEARCH_LOCAL
#define com_example_nasir_ndk2exmp_MainActivity_DEFAULT_KEYS_SEARCH_LOCAL 3L
#undef com_example_nasir_ndk2exmp_MainActivity_DEFAULT_KEYS_SEARCH_GLOBAL
#define com_example_nasir_ndk2exmp_MainActivity_DEFAULT_KEYS_SEARCH_GLOBAL 4L
#undef com_example_nasir_ndk2exmp_MainActivity_MAX_NUM_PENDING_FRAGMENT_ACTIVITY_RESULTS
#define com_example_nasir_ndk2exmp_MainActivity_MAX_NUM_PENDING_FRAGMENT_ACTIVITY_RESULTS 65534L
#undef com_example_nasir_ndk2exmp_MainActivity_HONEYCOMB
#define com_example_nasir_ndk2exmp_MainActivity_HONEYCOMB 11L
#undef com_example_nasir_ndk2exmp_MainActivity_MSG_REALLY_STOPPED
#define com_example_nasir_ndk2exmp_MainActivity_MSG_REALLY_STOPPED 1L
#undef com_example_nasir_ndk2exmp_MainActivity_MSG_RESUME_PENDING
#define com_example_nasir_ndk2exmp_MainActivity_MSG_RESUME_PENDING 2L
/*
 * Class:     com_example_nasir_ndk2exmp_MainActivity
 * Method:    helloJNI
 * Signature: ()Ljava/lang/String;
 */



JNIEXPORT jstring JNICALL Java_com_example_nasir_ndk2exmp_MainActivity_HelloJNI
  (JNIEnv *, jobject);

#ifdef __cplusplus
}
#endif
#endif

这是我的C档

#include "com_example_nasir_ndk2exmp_MainActivity.h"

/*
 * Class:     com_example_nasir_ndk2exmp_MainActivity
 * Method:    helloJNI
 * Signature: ()Ljava/lang/String;
 */

JNIEXPORT jstring JNICALL Java_com_example_nasir_ndk2exmp_MainActivity_HelloJNI(JNIEnv * env, jobject obj)
{

  return (*env)->NewStringUTF(env, "Hello From JNI");

}

这是.mk文件

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

这是build.gradle

apply plugin: 'com.android.application'

android {
    compileSdkVersion 23
    buildToolsVersion "23.0.3"

    defaultConfig {
        applicationId "com.example.nasir.ndk2exmp"
        minSdkVersion 19
        targetSdkVersion 23
        versionCode 1
        versionName "1.0"

        ndk{
            moduleName "HelloJNI"
        }


    }

    sourceSets.main{
        jni.srcDirs = []
        jniLibs.srcDir 'src/main/libs'
    }


    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

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

1 个答案:

答案 0 :(得分:1)

您的build.gradle会在此处禁用对ndk-build的内置调用:

jni.srcDirs = []

您确定该库实际上正在构建吗?如果你没有在&#39; jniLibs&#39;下看到HelloJNI.so。或者&#39; libs&#39;目录,您实际上并没有构建任何本机代码。

你真的不需要这个项目的Android.mk文件这么简单,但如果你想走这条路线,ph0b就有great tutorial使用带有gradle的Android.mk。您需要在build.gradle中添加对ndk-build的调用,并使用来自ph0b教程的此片段:

// call regular ndk-build(.cmd) script from app directory
task ndkBuild(type: Exec) {
    if (Os.isFamily(Os.FAMILY_WINDOWS)) {
        commandLine 'ndk-build.cmd', '-C', file('src/main').absolutePath
    } else {
        commandLine 'ndk-build', '-C', file('src/main').absolutePath
    }
}

如果您选择使用实验性gradle支持,NDK samples文档将如何使用build.gradle构建和使用本机代码。 build.gradle file from hello-jni是一个很好的起点。