2015-01-05 51 views
8

我一直致力於根據步驟here構建一個非常簡單的NDKSample應用程序。 我的問題是,我無法讓Android Studio生成.so文件,所以我沒有庫。使用NDK在Android Studio 1.0.2中生成.so文件

據我所知,NDK支持已被棄用,今年年初將會有一個替代品,不過目前似乎沒有任何東西阻止我使用該功能。當我建立我的項目,我給出下面的警告(不是錯誤):

WARNING [Project: :app] Current NDK support is deprecated. Alternative will be provided in the future.

我的項目的基礎,但是當我運行它崩潰(如預期),因爲它不能找到這些庫/ .apk文件。所以文件。我們希望這些是在項目建成時產生的,就像這個例子那樣,這是正確的嗎?以下是錯誤:

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"

關於我的環境

的Windows 7,Android的工作室1.0.2,亞行正在運行的Nexus 5(模擬器-5554)

我的代碼

按照示例:

主法案ivity.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中

<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

#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注:應用

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

## 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 

我的問題,如果有人能夠幫助請:

最終,我怎麼生成所需的.so文件!! ??

子問題,這可能會在回答的主要問題有幫助:

我的目錄佈局了下我的應用程序目錄JNI(所以NDKSample /應用/ JNI),這是正確的?我被建議here不要把c文件放在標準的jni目錄中。我對此進行了嘗試,並在構建該項目時崩潰。錯誤:

*失敗:生成失敗,出現異常。

  • 出錯: 任務':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*

英特爾上面的例子並不直接我建立一個Android.mk文件,示例不和他產生工作的應用程序。我試過把一個放在jni目錄中,但它沒有幫助。我應該創建一個,如果是的話,我應該把它放在哪裏

我的目錄下面的圖像是否正確? Directories

任何幫助將不勝感激。

凱爾

+0

我有一個問題關於如何在我的android項目中使用.so文件。你可以看到它.http://www.facebook.com/stackoverflow.com/questions/44929511/specify-so-files-in-build-gradle-file-android-studio –

回答

13

在Android Studio中當前NDK支持是最小的,因此它們與1.0棄用它。

使用它時,會自動生成一個Android.mk文件,並在生成項目時編譯源代碼。現在看來編譯失敗了,但你應該能夠從Gradle Console獲得最初的錯誤信息。

如果你沒有得到任何其他錯誤消息,我懷疑調用NDK-編譯失敗,因爲有你的NDK的安裝路徑的內部空間(Android NDK

您可以修復當前錯誤並繼續使用當前的設置或禁用默認NDK集成,創建Android.mk/Application.mk文件,並致電NDK建造(.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 
    } 
} 
+0

嗨@phOb, 謝謝你的擡頭。我從路徑中刪除了空白,然後將c文件移動到src/main/jni下的默認jni文件夾中。這會生成.so文件,但Gradle現在不會將它們打包到.apk中。 我已經嘗試過使用腳本gradle自己做它,但它試圖在實際生成它們之前將.so文件複製並壓縮爲.jar。我相信這應該是一個相當自動化的系統,並且深入描述這些事情意味着更深層次的問題? – KyleM

+0

com.md.NDKSample.MainActivity的.class文件位於目錄app/build/intermediates/classes/debug中,因此生成的.so文件轉到目錄應用/ build/intermediates/ndk/debug/lib - 但是,當我在資源管理器中瀏覽時,我只能看到這些文件; AndroidStudio只顯示應用程序/構建/中間體內的爆炸式目錄 - 其他子目錄(例如資產,類,ndk等)都不是這個問題嗎? – KyleM

+0

ph0b,謝謝。我現在已經解決了。它是從錯誤的目錄生成java頭文件的組合(應該從app/src/main按照你的例子調用它們,不管1.0中有新的dir結構),並且在我的ndk路徑中有空白區域。謝謝。 – KyleM

相關問題