2015-10-02 36 views
5

Sau khi dành hàng giờ để tìm kiếm giải pháp cho vấn đề của tôi và duyệt các diễn đàn khác nhau (bao gồm cả diễn đàn này), tôi đã quyết định đặt câu hỏi của mình, hy vọng nó chưa được trả lời đầy đủ ở nơi khác .Android Studio - Ứng dụng + Thư viện Mô-đun NDK

Tôi đang cố gắng để xây dựng một kiến ​​trúc khá phức tạp:

  • Tôi có nguồn C mà tôi biên soạn trong tách thư viện tĩnh (.a)
  • Tôi sử dụng chúng thông qua JNI trong một module Thư viện
  • Tôi muốn sử dụng thư viện này trong một dự án ứng dụng.

Lần đầu tiên tôi thực hiện các thử nghiệm sau đây - Tôi đã quản lý để tạo thư viện mô-đun mà không cần NDK và biên dịch nó bằng ứng dụng. - Tôi cũng đã quản lý để sử dụng các thư viện tĩnh và JNI trực tiếp trong ứng dụng nhưng

Tôi đang thất bại với bước sau: - Sự kết hợp của JNI bên trong mô-đun và ứng dụng gọi các lớp học không hoạt động .

Tôi nghĩ rằng vấn đề là với sự bao gồm của aar, bởi vì tôi không thể tìm thấy a-explar trong thư mục build của ứng dụng của tôi trong khi aar nằm trong thư mục build/output library. Bên cạnh đó, tất cả các bài kiểm tra trước đó (bao gồm cả việc sử dụng JNI đã thành công).

Tôi không sử dụng mô hình thử nghiệm vì nó là thử nghiệm và có những hạn chế đã biết với các thư viện tĩnh.

Cấu trúc của dự án của tôi là:

- App 
    - src 
     - main 
      - java 
       - activity 
- bar 
    - src 
     - main 
      - java 
       - class 
      - jni 
       - include 
        - *.h 
       - libs 
        - abis... 
         - libmod1.a 
         - libmod2.a 
       Android.mk 
       Application.mk 
       bar.c 
       bar.h 

Ứng dụng build.gradle trông như thế này:

apply plugin: 'com.android.application' 

android { 
    compileSdkVersion 23 
    buildToolsVersion "23.0.0" 

    defaultConfig { 
     applicationId "com.test.foo" 
     minSdkVersion 10 
     targetSdkVersion 23 
     versionCode 1 
     versionName "1.0" 
    } 

    buildTypes { 

     release { 
      debuggable   false 
      jniDebuggable  false 
      minifyEnabled  false 
     } 
     unsigned { 
      debuggable   false 
      jniDebuggable  false 
      minifyEnabled  false 
     } 
     debug { 
      debuggable   true 
      jniDebuggable  true 
      minifyEnabled  false 
     } 
    } 


    productFlavors { 
     x86 { 
      ndk { 
       abiFilter "x86" 
      } 
     } 
     mips { 
      ndk { 
       abiFilter "mips" 
      } 
     } 
     armv7 { 
      ndk { 
       abiFilter "armeabi-v7a" 
      } 
     } 
     arm { 
      ndk { 
       abiFilter "armeabi" 
      } 
     } 
     fat 
    } 

    project.ext.versionCodes = ['armeabi':1, 'armeabi-v7a':2, 'arm64-v8a':3, 'mips':5, 'mips64':6, 'x86':8, 'x86_64':9] 

    android.applicationVariants.all { variant -> 
     variant.outputs.each { output -> 
      output.versionCodeOverride = 
        project.ext.versionCodes.get(output.getFilter(com.android.build.OutputFile.ABI), 0) * 1000000 + defaultConfig.versionCode 
     } 
    } 
} 

dependencies { 
    compile fileTree(dir: 'libs', include: ['*.jar','*.aar']) 
    compile project(":bar") 
} 

Module build.gradle trông như thế này:

apply plugin: 'com.android.library' 

android { 
    compileSdkVersion 23 
    buildToolsVersion "23.0.0" 

    defaultConfig { 
     minSdkVersion 10 
     targetSdkVersion 23 
     versionCode 1 
     versionName "1.0" 

     ndk { 
      moduleName "module" 
     } 
    } 
    buildTypes { 

     release { 
      debuggable  false 
      jniDebuggable false 
      minifyEnabled false 
     } 
     unsigned { 
      debuggable  false 
      jniDebuggable false 
      minifyEnabled false 
     } 
     debug { 
      debuggable  true 
      jniDebuggable true 
      minifyEnabled false 
     } 
    } 

    productFlavors { 
     x86 { 
      ndk { 
       abiFilter "x86" 
      } 
     } 
     mips { 
      ndk { 
       abiFilter "mips" 
      } 
     } 
     armv7 { 
      ndk { 
       abiFilter "armeabi-v7a" 
      } 
     } 
     arm { 
      ndk { 
       abiFilter "armeabi" 
      } 
     } 
     fat 
    } 
    sourceSets.main { 
     jniLibs.srcDir 'src/main/libs' 
     jni.srcDirs  = [] 
    } 

    task ndkBuild(type: Exec) { 
     commandLine android.ndkDirectory.getAbsolutePath()+'/ndk-build', '-C', file('src/main').absolutePath 
    } 

    tasks.withType(JavaCompile) { 
     compileTask -> compileTask.dependsOn ndkBuild 
    } 
} 

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

Android.mk của tôi bên trong thư mục jni của mô-đun là: LOCAL_PATH: = $ (hãy gọi cho tôi-dir)

#### Mod1 
include $(CLEAR_VARS) 
LOCAL_MODULE   := mod1 
LOCAL_SRC_FILES   := libs/$(TARGET_ARCH_ABI)/libmod1.a 
include $(PREBUILT_STATIC_LIBRARY) 

#### Mod2 
include $(CLEAR_VARS) 
LOCAL_MODULE   := pxnav 
LOCAL_SRC_FILES   := libs/$(TARGET_ARCH_ABI)/libmod2.a 
LOCAL_STATIC_LIBRARIES := pxfd 
include $(PREBUILT_STATIC_LIBRARY) 

##### Parser 
include $(CLEAR_VARS) 
LOCAL_MODULE   := module 
LOCAL_C_INCLUDES  := $(LOCAL_PATH)/include 
LOCAL_LDLIBS   += -landroid -llog 
LOCAL_SRC_FILES   := bar.c 
LOCAL_STATIC_LIBRARIES := mod1 mod2 
include $(BUILD_SHARED_LIBRARY) 
+0

Tôi thêm rằng nếu tôi sử dụng trực tiếp tạo ra aar: Mô-đun mới> Nhập .jar/.aar, nó hoạt động hoàn hảo. Tôi không muốn phải sao chép aar vào một thư mục chỉ định mỗi khi tôi biên dịch mặc dù. –

Trả lời

0

Tôi tìm thấy một workaround dễ dàng cho công việc tương tự: Tôi chỉ cần đặt jniLibs.srcDir cho ứng dụng module. Bây giờ tôi không phụ thuộc vào việc phát nổ aar để nhận các tệp .so tại chỗ. BTW, khi bạn quyết định chuyển sang plugin thử nghiệm (để sử dụng tính năng gỡ lỗi gốc, đánh dấu cú pháp C++ và tham chiếu chéo và các nội dung khác), bạn được mời kiểm tra define LOCAL_SRC_FILES in ndk{} DSL.

+0

Tôi không hiểu nó giúp như thế nào. Bạn đặt jniLibs.srcDir bên trong ứng dụng vào thư mục libs bên trong module? Trong trường hợp đó, làm thế nào để bạn quản lý để làm cho các ứng dụng xem các lớp học trong aar? Vấn đề của tôi là ngay cả lớp trong thư viện mô-đun thanh không thể sử dụng được trong ứng dụng. –

+0

Tôi đã thử giải pháp của bạn, tôi thực sự có libs được liên kết trong APK của tôi nhưng các lớp học của AAR vẫn bị thiếu trong APK và không thể được khởi tạo trong ứng dụng. –

+0

Thư viện không xây dựng mã gốc; nó giả vờ là một mô-đun Java thuần túy. Bạn nói rằng bạn đã thành công để sử dụng một thư viện trong một trong những thí nghiệm sơ bộ của bạn, phải không? –

Các vấn đề liên quan