简体   繁体   English

使用NDK在Android Studio 1.0.2中生成.so文件

[英]Generating .so files in Android Studio 1.0.2 with NDK

I have been working on getting a very simple NDKSample application built as per the walk-through here . 我一直在努力获得一个非常简单的NDKSample应用程序,这个应用程序按照此处的步骤进行构建。 My problem is, I cannot get Android Studio to generate the .so files, so I have no libraries. 我的问题是,我无法让Android Studio生成.so文件,因此我没有库。

I understand that NDK Support is deprecated now and there will be an alternative provided early this year, however there doesn't appear to be anything actively stopping me from using this feature currently. 我知道NDK支持现在已被弃用,并且今年早些时候会提供替代方案,但是目前似乎没有任何东西阻止我使用此功能。 When I build my project, I am given the following Warning (Not an error): 当我构建我的项目时,我收到以下警告(不是错误):

WARNING [Project: :app] Current NDK support is deprecated. 警告[Project :: app]不推荐使用当前的NDK支持。 Alternative will be provided in the future. 将来会提供替代方案。

My project builds, but when I run the .apk it crashes (as expected) as it cant find the libraries/.so files. 我的项目构建,但当我运行.apk它崩溃(如预期),因为它无法找到库/ .so文件。 We would expect these to be generated when the project is built, as per the example, is this correct? 我们希望在构建项目时生成这些,根据示例,这是正确的吗? Here is the error: 这是错误:

java.lang.UnsatisfiedLinkError: dalvik.system.PathClassLoader[DexPathList[[zip file "/data/app/com.example.ndksample-1/base.apk"],nativeLibraryDirectories=[/vendor/lib, /system/lib]]] couldn't find "libMyLib.so" java.lang.UnsatisfiedLinkError:dalvik.system.PathClassLoader [DexPathList [[zip file“/data/app/com.example.ndksample-1/base.apk"],nativeLibraryDirectories=[/vendor/lib,/ system / lib] ]]找不到“libMyLib.so”

About my environment 关于我的环境

Windows 7, Android Studio 1.0.2, ADB is running Nexus 5 (emulator-5554) Windows 7,Android Studio 1.0.2,ADB正在运行Nexus 5(模拟器-5554)

My code 我的代码

As per the example: 根据例子:

Main Activity.java 主Activity.java

package com.example.ndksample;

//import android.support.v7.app.ActionBarActivity;
// This line is not needed as we are not targetting older devices
import android.app.Activity; //Import this app package to use onCreate etc.
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.TextView;


public class MainActivity extends Activity {

    static{
        System.loadLibrary("MyLib");
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        TextView tv = (TextView) findViewById(R.id.my_textview);
        tv.setText(getStringFromNative());
    }

    @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);
    }

    public native String getStringFromNative();
}

activity_main.xml activity_main.xml中

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
    android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:paddingBottom="@dimen/activity_vertical_margin" tools:context=".MainActivity">

    <TextView
        android:id="@+id/my_textview"
        android:text="@string/hello_world" android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

</RelativeLayout>

main.c main.c中

#include "com_example_ndksample_MainActivity.h"
/* Header for class com_example_ndksample_MainActivity */

JNIEXPORT jstring JNICALL Java_com_example_ndksample_app_MainActivity_getStringFromNative
    (JNIEnv * env, jobject obj)
    {
        return (*env)->NewStringUTF(env, "Hello from Kyle");
    }

build.gradle note: app build.gradle note:app

apply plugin: 'com.android.application'

android {
    compileSdkVersion 21
    buildToolsVersion "21.1.2"

    defaultConfig {
        applicationId "com.example.ndksample"
        minSdkVersion 15
        targetSdkVersion 21
        versionCode 1
        versionName "1.0"

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

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

local.properties local.properties

## This file is automatically generated by Android Studio.
# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
#
# This file should *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.
sdk.dir=D\:\\Programs\\Android\\Android SDK
ndk.dir=D\:\\Programs\\Android\\Android NDK

My questions if anyone is able to help please: 如果有人能帮忙,我的问题是:

Ultimately, how do I generate the required .so files!!?? 最终,我如何生成所需的.so文件!! ??

Sub questions that may help in answering the main question: 可能有助于回答主要问题的子问题:

My directory layout had my jni dir under app (so NDKSample/app/jni), is this correct? 我的目录布局在app下有我的jni目录(所以NDKSample / app / jni),这是正确的吗? I was advised here not to place the c files in the standard jni directory. 我在这里建议不要将c文件放在标准的jni目录中。 I trialed this, and upon building the project, it crashed. 我试验了这个,在建设项目时,它崩溃了。 Error: 错误:

*FAILURE: Build failed with an exception. * FAILURE:构建因异常而失败。

  • What went wrong: Execution failed for task ':app:compileDebugNdk'. 出了什么问题:任务执行失败':app:compileDebugNdk'。

    com.android.ide.common.internal.LoggedErrorException: Failed to run command: D:\\Programs\\Android\\Android NDK\\ndk-build.cmd NDK_PROJECT_PATH=null APP_BUILD_SCRIPT=C:\\Users\\Kyle\\AndroidStudioProjects\\NDKSample\\app\\build\\intermediates\\ndk\\debug\\Android.mk APP_PLATFORM=android-21 NDK_OUT=C:\\Users\\Kyle\\AndroidStudioProjects\\NDKSample\\app\\build\\intermediates\\ndk\\debug\\obj NDK_LIBS_OUT=C:\\Users\\Kyle\\AndroidStudioProjects\\NDKSample\\app\\build\\intermediates\\ndk\\debug\\lib APP_ABI=all Error Code: 1* com.android.ide.common.internal.LoggedErrorException:无法运行命令:D:\\ Programs \\ Android \\ Android NDK \\ ndk-build.cmd NDK_PROJECT_PATH = null APP_BUILD_SCRIPT = C:\\ Users \\ Kyle \\ AndroidStudioProjects \\ NDKSample \\ app \\ build \\ intermediates \\ ndk \\ debug \\ Android.mk APP_PLATFORM = android-21 NDK_OUT = C:\\ Users \\ Kyle \\ AndroidStudioProjects \\ NDKSample \\ app \\ build \\ intermediates \\ ndk \\ debug \\ obj NDK_LIBS_OUT = C:\\ Users \\ Kyle \\ AndroidStudioProjects \\ NDKSample \\ app \\ build \\ intermediates \\ ndk \\ debug \\ lib APP_ABI = all错误代码:1 *

The example from Intel above does not direct me to build an Android.mk file, the example does not and he generates a working application. 上面的英特尔示例并没有指示我构建一个Android.mk文件,示例没有,他生成一个工作的应用程序。 I have trialed putting one in the jni directory, however it did not help. 我试过把一个放在jni目录中,但它没有帮助。 Should I be creating one, and if so, where should I put it 我应该创建一个,如果是的话,我应该把它放在哪里

Is the below image of my directories correct? 我的目录的下图是否正确? 目录

Any help would be greatly appreciated. 任何帮助将不胜感激。

Kyle 凯尔

the current NDK support in Android Studio is minimal, hence they deprecated it with 1.0. Android Studio中当前的NDK支持很少,因此他们将其弃用为1.0。

When using it, an Android.mk file is automatically generated and your sources compiled when you build your project. 使用它时,会自动生成Android.mk文件,并在构建项目时编译源代码。 Right now it seems the compilation is failing, but you should be able to get the initial error message from the Gradle Console. 现在似乎编译失败了,但您应该能够从Gradle控制台获取初始错误消息。

If you don't get any other error messages, I suspect that the call to ndk-build is failing because there is a space inside your NDK's installation path ( Android NDK ) 如果您没有收到任何其他错误消息,我怀疑对ndk-build的调用失败,因为NDK的安装路径中有一个空间( Android NDK

You can either fix the current error and continue with your current setup, or disable the default NDK integration, create Android.mk / Application.mk files and call ndk-build(.cmd) yourself or from a task: 您可以修复当前错误并继续当前设置,或者禁用默认的NDK集成,创建Android.mk / Application.mk文件并自行调用ndk-build(.cmd)或从任务中调用:

import org.apache.tools.ant.taskdefs.condition.Os

android {
    sourceSets.main {
        jniLibs.srcDir 'src/main/libs' //set .so files location to libs
        jni.srcDirs = [] //disable automatic ndk-build call
    }

    // 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
        }
    }
    tasks.withType(JavaCompile) {
        compileTask -> compileTask.dependsOn ndkBuild
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM