2015-12-02 92 views
0

切換到Android Studio之後,我開始看到了可怕的Android原生庫消失,一旦應用程序被安裝

java.lang.UnsatisfiedLinkError: dlopen failed: library 
'/data/app-lib/com.myapp.test-1/libmylib.so' not found 

錯誤。當我解壓縮apk時,我可以在lib/armeabi文件夾下看到libmylib.so以及所有其他本地庫(libmyotherlib.so和libtest.so),因此包裝不應該成爲問題...我決定根我的測試設備並查看/ data/app-lib下應用文件夾的實際內容,其中本機庫應該安裝後 - 我發現應用程序的一個本機庫(libmylib.so)在應用程序後失蹤安裝在設備上。 libmylib.so和libmyotherlib.so是預建的.so文件,位於src/main/jniLibs中,而libtest.so是從src/main/jni中的test.c編譯的。

這隻在我切換到Android Studio後纔開始;我已經驗證過,在Eclipse ADT中使用相同代碼構建的apks安裝後,所有必需的庫都存在於/data/app-lib/com.myapp.test-1下。

相關的build.gradle爲Android Studio生成:

apply plugin: 'com.android.application' 

android { 
    compileSdkVersion 23 
    buildToolsVersion "21.1.2" 

    defaultConfig { 
     applicationId "com.myapp.test" 
     minSdkVersion 17 
     targetSdkVersion 23 
     versionCode 1 
     versionName "1.0" 

     ndk{ 

      moduleName "test"//testing ndk integration 
     } 

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

} 

repositories { 
    // You can also use jcenter if you prefer 
    mavenCentral() 
} 

dependencies { 
    compile fileTree(dir: 'libs', include: ['*.jar']) 
    testCompile 'junit:junit:4.12' 

    //android support libs etc. 
    compile 'com.android.support:appcompat-v7:23.1.0' 
    compile 'com.android.support:support-v13:23.1.0' 

} 

相關gradle.properties文件

android.useDeprecatedNdk=true 

下的src/main/JNI我只有test.c的

#include <jni.h> 

int main(){ 

    return 0; 
} 

and under src/main/jniLibs/armeabi我有

libmylib.so 
libmyotherlib.so 

相關Android.mk爲Eclipse ADT編譯:

include $(CLEAR_VARS) 
LOCAL_MODULE := test 
LOCAL_SRC_FILES += test.c 
include $(BUILD_SHARED_LIBRARY) 

include $(CLEAR_VARS) 
LOCAL_MODULE := myotherlib 
LOCAL_SRC_FILES := $(TARGET_ARCH_ABI)/libmyotherlib.so 
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/include 
include $(PREBUILT_SHARED_LIBRARY) 

include $(CLEAR_VARS) 
LOCAL_MODULE := mylib 
LOCAL_SRC_FILES := $(TARGET_ARCH_ABI)/libmylib.so 
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/include 
include $(PREBUILT_SHARED_LIBRARY) 

相關/ data/app中-lib的內容安裝的應用程序由Android工作室建成後:

[email protected] SL-K40:/ # ls /data/app-lib/com.myapp.test-1    
libmyotherlib.so 
libtest.so 

相關/數據/ APP-安裝由Eclipse ADT構建的應用程序之後的lib內容:

[email protected] SL-K40:/ # ls /data/app-lib/com.myapp.test-1    
libmylib.so 
libmyotherlib.so 
libtest.so 

我不小心fo UND通過添加

sourceSets { 
     main { 
      jni.srcDirs = [] 
} 
} 

我的build.gradle我能得到libmylib.so在安裝後再次現身,但排除有在我的項目的任何NDK源代碼。

第一個問題: 任何想法可能會發生什麼嗎?難道是因爲mylib實際上是針對除armeabi以外的其他abi進行編譯的,Android會放棄它,因爲它的實際abi與它在apk內部進入的文件夾不匹配(我沒有mylib的源代碼)?我的問題聽起來很像here,但是這個人似乎在最終安裝的應用程序中只能看到一個共享庫;我看到的都是我的共享庫中的一個。

第二個問題: 在Android Studio構建中包含預構建.so文件的當前正確方法是什麼? Cluesaroundthe 'net似乎根據Android Studio版本(我使用的是Android Studio 1.5,Gradle版本2.4,Android插件版本1.3。0)是否仍然需要將jniLibs.srcDir變量重定向到src/main/libs?

+0

我的猜測是它的某些gradle任務正在破壞構建 – Bhargav

+0

首先,您不需要root來訪問**/data/app-lib/com.myapp.test-1/*中的庫。 * –

+1

@AlexCohn是真的,但你確實需要root通過adb shell'ls -al/data/app-lib'列出/ data/app-lib的內容,而且我不想讓我的應用程序的文件夾在運行時從名稱上下文:: getApplicationInfo()。nativeLibraryDir – CCJ

回答

1

是的,最好的方法是定義jniLibs.srcDir,這樣所有預建的庫都可以從那裏複製。

是的,ABI是最可能的問題來源。如果預建圖書館建於armeabi但設備(如當今絕大多數設備)支持armeabi-V7A,則安裝程序會很樂意的...... V7A版本的未預建庫複製到/data/app-lib/com.myapp.test-1,並且加載程序稍後會抱怨libmylib.so丟失。

您應該指示Android Studio僅構建一個ABI。如果你在Eclipse構建中沒有做特別的事情,那麼這很可能是armeabi

指示AS的方式取決於gradle插件的版本。

對於'com.android.tools.build:gradle:1.5.0'插件,我使用類似

android { 
    defaultConfig.ndk { 
     … 
     abiFilter 'armeabi' 
    } 

    splits { 
     abi { 
      enable true 
      reset() 
      include 'armeabi' 
     } 
    } 
} 

對於...... gradle這個實驗性:0.2.0,我用

model { 
    android.ndk { 
     … 
     abiFilters += 'armeabi' 
    } 
} 

我沒有必要啓用在實驗插件分裂,所以我不會誤導你對語法的變化出現。

+0

嗯,很奇怪。我想知道/爲什麼libmyotherlib通過了安裝過程呢?最終apk對所有的abis都有libtest,包括armeabi-v7a,但libmyotherlib只存在於armeabi中...... – CCJ

+1

安裝程序是否可以檢測到在設備的/ system/lib目錄中有一個名爲libmylib的庫?如果是這樣,這可以解釋爲什麼libmyotherlib通過安裝並且libmylib被拋出 - 我正在加載的實際庫是在我的測試設備上的/ system/lib下找到的一個修改版本,因此和/或abi你提到的最適合的過濾將解釋我看到的行爲 – CCJ

相關問題