অ্যান্ড্রয়েড স্টুডিওতে * .so লাইব্রেরি কীভাবে অন্তর্ভুক্ত করবেন?


123

আমি কীভাবে অ্যান্ড্রয়েড স্টুডিওতে * .so লাইব্রেরি যুক্ত করতে পারি তার অনেকগুলি থ্রেড পড়েছি তবে এগুলির কোনওটিই কাজ করে না, বিশেষত এটি যখন পাঠ্যের বিন্দুতে আসে: এটি নতুন এক্সএক্সএক্সের সাথে কাজ করে না (অ্যান্ড্রয়েড স্টুডিও, গ্রেডেল, ...)

দয়া করে আমরা কি নতুন করে শুরু করতে পারি? আমি পেয়েছি:

অ্যান্ড্রয়েড স্টুডিও 0.6.0

প্রকল্পের কাঠামো থেকে আমি দেখতে পাচ্ছি:

এসডিকে অবস্থান:

/usr/share/android-studio/data/sdk
/usr/lib/jvm/default-java

প্রকল্প:

Gradle version 1.10
Android Plugin Version 0.11.+

মডিউল / অ্যাপ: বৈশিষ্ট্য:

এসডিকে সংস্করণ 19 বিল্ড সরঞ্জাম সংস্করণ 19.1.0 সংকলন করুন

নির্ভরতা:

{dir=libs, include=[*.jar]} Compile

{dir=libs, include=[*.so]}  Provided

m com.android.support: appcompat -v7:19.+   Compile

আমি * .so ফাইলগুলি প্রাক-সংকলিত এবং ডেমো অ্যাপে তারা কাজ করছে got আমাকে অ্যাপের উত্স কোডটি পরিবর্তন করতে হবে, সুতরাং একই * .so ফাইলগুলি দিয়ে আমার পুনর্নির্মাণ করা দরকার।


: Android প্রকল্পের বাইরে ডিরেক্টরি থেকে একটি .so ফাইল যোগ stackoverflow.com/questions/50713933/...
user1506104

এখানে উত্তর চেক করুন: stackoverflow.com/a/54977264/8034839
shizhen

উত্তর:


108

বর্তমান সমাধান

ফোল্ডারটি তৈরি করুন project/app/src/main/jniLibs, এবং তারপরে আপনার *.soফাইলগুলিকে তাদের অ্যাবি ফোল্ডারগুলির মধ্যে সেই জায়গায় রেখে দিন। যেমন,

project/
├──libs/
|  └── *.jar       <-- if your library has jar files, they go here
├──src/
   └── main/
       ├── AndroidManifest.xml
       ├── java/
       └── jniLibs/ 
           ├── arm64-v8a/                       <-- ARM 64bit
              └── yourlib.so
           ├── armeabi-v7a/                     <-- ARM 32bit
              └── yourlib.so
           └── x86/                             <-- Intel 32bit
               └── yourlib.so

অবমানিত সমাধান

আপনার মডিউল গ্রেডলে উভয় কোড স্নিপেট যুক্ত করুন file বিল্ড ফাইলটিকে নির্ভরতা হিসাবে:

compile fileTree(dir: "$buildDir/native-libs", include: 'native-libs.jar')

এই কাস্টম জারটি কীভাবে তৈরি করবেন:

task nativeLibsToJar(type: Jar, description: 'create a jar archive of the native libs') {
    destinationDir file("$buildDir/native-libs")
    baseName 'native-libs'
    from fileTree(dir: 'libs', include: '**/*.so')
    into 'lib/'
}

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

একই উত্তর সম্পর্কিত প্রশ্নেও পাওয়া যাবে: অ্যান্ড্রয়েড স্টুডিওতে এপিকে গ্রন্থাগার অন্তর্ভুক্ত করুন


6
Compileকাজটি হ্রাস করা হয়েছে। JavaCompileপরিবর্তে ব্যবহার করুন (সম্পর্কিত উত্তরগুলি থেকে)
সেরগেই

আমি কোথায় কাজগুলি করা উচিত?
মাসউদ ভালি

2
প্রথমে jniLibs ফোল্ডার সমাধান চেষ্টা করুন। এই কাজগুলি আপনার অ্যাপ্লিকেশন / লাইব্রেরিতে গ্রেড.বিল্ড ফাইলের মধ্যে রাখা উচিত।
nenick


এখানে দেখতে (তালিকা বিভিন্ন স্থাপত্য উপ-ফোল্ডার): cumulations.com/blogs/9/...
NorbertM

222

অ্যান্ড্রয়েড স্টুডিওতে .so লাইব্রেরি যুক্ত করা হচ্ছে 1.0.2

  1. "Src / main /" এর ভিতরে ফোল্ডার "jniLibs" তৈরি করুন
  2. আপনার সমস্ত .so লাইব্রেরিগুলিকে "src / main / jniLibs" ফোল্ডারের ভিতরে রাখুন
  3. ফোল্ডারের কাঠামোটি দেখতে,
    |
    - অ্যাপ: | - | - এসআরসি: | -
    | - | --মেনেন
    | - | - | - - --jniLibs
    | - | - | - - | - | --আরমেবী
    | - | - | - | - | - | - তাই ফাইলগুলি
    | - | - | - | - | --x86
    | - | - | - | - | - | -। তাই ফাইল
  4. কোনও অতিরিক্ত কোডের জন্য আপনার প্রকল্পটি কেবল সিঙ্ক করে আপনার অ্যাপ্লিকেশনটি চালানো দরকার।

    রেফারেন্স
    https://github.com/commonsguy/sqlcipher-gradle/tree/master/src/main

6
এটি 16 জুন, 2015 স্টুডিওর বিটা সংস্করণ নিয়ে কাজ করছে না
বাগফিক্সার

6
এটি সঠিক উত্তর, অ্যান্ড্রয়েড স্টুডিও ১.২.২ এ কাজ করছে। চেক এবং যাচাই করা হয়েছে।
আখিল জৈন

3
অ্যান্ড্রয়েড স্টুডিও 1.3.1 এর সাথে কাজ করা।
জাইমে হাবলুটজেল

3
আমার জন্য কাজ করেছেন। অ্যান্ড্রয়েড স্টুডিওতে 2.1.2 :)
শুজাতআলি

3
অ্যান্ড্রয়েড স্টুডিও 3.2.1 সঙ্গে দুর্দান্ত কাজ করে! এখনও কোথাও নথিভুক্ত করা হয়নি! ???
নর্বার্টএম

29

সমাধান 1: একটি JniLibs ফোল্ডার তৈরি

আপনার অ্যাপ্লিকেশনটিতে "jniLibs" নামে একটি ফোল্ডার এবং ভিতরে আপনার * .সো ফোল্ডার তৈরি করুন। "JniLibs" ফোল্ডারটি আপনার "জাভা" বা "সম্পদ" ফোল্ডারগুলির মতো একই ফোল্ডারে তৈরি করা দরকার।

সমাধান 2: বিল্ড.gradle ফাইলের পরিবর্তন

আপনি যদি কোনও নতুন ফোল্ডার তৈরি করতে না চান এবং আপনার * .so ফাইলগুলি লিব্স ফোল্ডারে রাখতে না চান, এটি সম্ভব!

সেক্ষেত্রে কেবল আপনার * .so ফাইলগুলি libs ফোল্ডারে যুক্ত করুন (উদাহরণস্বরূপ সমাধান 1: libs / armeabi / .so হিসাবে একই আর্কিটেকচারকে সম্মান করুন) এবং উত্স ডিরেক্টরি যুক্ত করতে আপনার অ্যাপ্লিকেশনটির বিল্ড.gradle ফাইলটি সংশোধন করুন JniLibs এর।

sourceSets {
    main {
        jniLibs.srcDirs = ["libs"]
    }
}

এখানে আপনাকে সহায়তা করার জন্য স্ক্রিনশট সহ আপনার আরও ব্যাখ্যা থাকবে (Step ধাপ):

http://blog.guillaumeagis.eu/setup-andengine-with-android-studio/

সম্পাদনা করুন এটি jniLibs.srcDirs হতে হবে, jni.srcDirs নয় - কোড সম্পাদিত। ডিরেক্টরিটি একটি [আত্মীয়] পথ হতে পারে যা প্রকল্প ডিরেক্টরিটির বাইরের দিকে নির্দেশ করে।


1
সমাধান 2 আমার পক্ষে কাজ করে না। আমি একটি বিল্ড ত্রুটি পেয়েছি: "উত্স সেট 'প্রধান' তে 'jni' সম্পত্তি পাওয়া যায়নি" "
গ্রেগ ব্রাউন

গোপনীয়তাটি হ'ল "jniLibs" ফোল্ডারটি আপনার "জাভা" বা "সম্পদ" ফোল্ডারগুলির মতো একই ফোল্ডারে তৈরি করা উচিত। ধন্যবাদ!
সেরফিমের

পদ্ধতি 1 আমাকে সঠিকভাবে সংকলন করার অনুমতি দিয়েছে, দ্বিতীয়টি এএস-তে একটি "সিপিপি" ফোল্ডার তৈরি করেছে এবং সি ++ সংকলক অনুপস্থিত সম্পর্কে ত্রুটি দিয়েছে
ফিলোবোটো

সলিউশন 2-এ দেশীয় গ্রন্থাগারগুলির অবস্থান নির্দিষ্ট করার জন্য jni.srcDirs নয়, jniLibs.srcDirs ব্যবহার করতে হয়েছিল (পথটি আপেক্ষিক বা পরম হতে পারে এবং প্রকল্প ডিরেক্টরিটির বাইরেও নির্দেশ করতে পারে)।
অ্যাস্ট্রাজমস

সলিউশন 2 এর জন্য আপনার source Sets {কোডটি android {বিভাগের অধীনে রাখা দরকার
ইয়েনস্টার

26

অ্যান্ড্রয়েড স্টুডিওতে * .so লাইব্রেরি

আপনাকে অ্যান্ড্রয়েড স্টুডিও প্রকল্পগুলির মূল ভিতরে jniLibs ফোল্ডার তৈরি করতে হবে এবং আপনার সমস্ত .so ফাইল ভিতরে রেখে দিতে হবে। আপনি বিল্ড.gradle এ এই লাইন একীভূত করতে পারেন

ফাইল সঙ্কলন করুন (dir: 'libs', অন্তর্ভুক্ত করুন: [' .jar', ' .so'])

এটা পুরোপুরি কাজ

| --App:

| - | --src:

| - | - | --main

| - | - | - | --jniLibs

| - | - | - | - | --armeabi

| - | - | - | - | - | -। তাই ফাইল

এটি প্রকল্পের কাঠামো।


4
যোগ করার পদ্ধতি .so মধ্যে কম্পাইল fileTree (Dir: 'লিব', অন্তর্গত হল: [ '। তাই' 'জার',]) আমার prb সমাধান। thnx
বিএসটি কালের

এটি নীচের সমাধানের পরেও যদি হয় তবে অ্যান্ড্রয়েড এনডিকে আর
ভিনিত সেটিয়া

12

এটি আমার বিল্ড.gradle ফাইল, দয়া করে লাইনটি নোট করুন

jniLibs.srcDirs = ['libs']

এর মধ্যে apk থেকে libs এর * .so ফাইল অন্তর্ভুক্ত থাকবে।

sourceSets {
    main {
        manifest.srcFile 'AndroidManifest.xml'
        java.srcDirs = ['src']
        resources.srcDirs = ['src']
        aidl.srcDirs = ['src']
        renderscript.srcDirs = ['src']
        res.srcDirs = ['res']
        assets.srcDirs = ['assets']
        jniLibs.srcDirs = ['libs']
    }

    // Move the tests to tests/java, tests/res, etc...
    instrumentTest.setRoot('tests')

    // Move the build types to build-types/<type>
    // For instance, build-types/debug/java, build-types/debug/AndroidManifest.xml, ...
    // This moves them out of them default location under src/<type>/... which would
    // conflict with src/ being used by the main source set.
    // Adding new build types or product flavors should be accompanied
    // by a similar customization.
    debug.setRoot('build-types/debug')
    release.setRoot('build-types/release')
}

5

অ্যান্ড্রয়েড hello-libsএনডিকে অফিসিয়াল সিএমকে উদাহরণ

https://github.com/googlesamples/android-ndk/tree/840858984e1bb8a7fab37c1b7c571efbe7d6eb75/hello-libs

সবেমাত্র উবুন্টু 17.10 হোস্ট, অ্যান্ড্রয়েড স্টুডিও 3, অ্যান্ড্রয়েড এসডিকে 26 এ আমার জন্য কাজ করেছেন, তাই আমি দৃ strongly়ভাবে আপনাকে এই প্রকল্পটি বেস করার পরামর্শ দিচ্ছি।

ভাগ করা লাইব্রেরি বলা হয় libgperf, মূল কোড অংশগুলি হল:

  • হ্যালো- libs / app / src / main / cpp / CMakeLists.txt :

    // -L
    add_library(lib_gperf SHARED IMPORTED)
    set_target_properties(lib_gperf PROPERTIES IMPORTED_LOCATION
              ${distribution_DIR}/gperf/lib/${ANDROID_ABI}/libgperf.so)
    
    // -I
    target_include_directories(hello-libs PRIVATE
                               ${distribution_DIR}/gperf/include)
    // -lgperf
    target_link_libraries(hello-libs
                          lib_gperf)
  • অ্যাপ্লিকেশন / বিল্ড.gradle :

    android {
        sourceSets {
            main {
                // let gradle pack the shared library into apk
                jniLibs.srcDirs = ['../distribution/gperf/lib']

    তারপরে, আপনি যদি /data/appডিভাইসের নিচে নজর রাখেন তবে libgperf.soপাশাপাশি থাকবেন।

  • সি ++ কোডে, ব্যবহার করুন: #include <gperf.h>

  • শিরোনামের অবস্থান: hello-libs/distribution/gperf/include/gperf.h

  • lib অবস্থান: distribution/gperf/lib/arm64-v8a/libgperf.so

  • আপনি যদি কিছু আর্কিটেকচারকে সমর্থন করেন তবে দেখুন: গ্রেডল বিল্ড এনডিকে কেবলমাত্র এআরএম target

উদাহরণস্বরূপ গিট প্রাক-বিল্ট শেয়ার্ড লাইব্রেরিগুলি ট্র্যাক করে, তবে এগুলিতে প্রকৃতপক্ষে সেগুলি তৈরি করার জন্য এটি বিল্ড সিস্টেমও অন্তর্ভুক্ত করে: https://github.com/googlesferences/android-ndk/tree/840858984e1bb8a7fab37c1b7c571efbe7d6eb75/hello-libs/gen-libs


2

নেটিভ-লাইব্রেরি (সুতরাং ফাইলগুলি) ব্যবহার করতে আপনাকে "বিল্ড.gradle" ফাইলটিতে কিছু কোড যুক্ত করতে হবে।

এই কোডটি "আরমেবি" ডিরেক্টরিটি সাফ করার জন্য এবং 'পরিষ্কার' প্রকল্পের সময় 'তাই' ফাইলগুলি "আরমেবি" -তে অনুলিপি করার জন্য।

task copyJniLibs(type: Copy) {
    from 'libs/armeabi'
    into 'src/main/jniLibs/armeabi'
}
tasks.withType(JavaCompile) {
    compileTask -> compileTask.dependsOn(copyJniLibs)
}
clean.dependsOn 'cleanCopyJniLibs'

আমি নীচে থেকে উল্লেখ করা হয়েছে। https://gist.github.com/pocmo/6461138


2

জার ফাইলগুলির অভ্যন্তরে প্যাকেজযুক্ত বহিরাগত নেটিভ lib নির্ভরতা ব্যবহার করে আমি একই ধরণের সমস্যার সমাধান করেছি। কখনও কখনও এই আর্কিটেকচার নির্ভর নির্ভর গ্রন্থাগারগুলি পুরো এক পাত্রে প্যাকেজ করা হয়, কখনও কখনও সেগুলি কয়েকটি জার ফাইলগুলিতে বিভক্ত হয়। তাই আমি নেটিভ লিবসের জন্য জারের নির্ভরতাগুলি স্ক্যান করতে এবং এটিকে সঠিক অ্যান্ড্রয়েড লাইব ফোল্ডারে ভাগ করতে কিছু বিল্ডস্ক্রিপ্ট লিখেছিলাম। অতিরিক্তভাবে এটি নির্ভরতা ডাউনলোড করার একটি উপায়ও সরবরাহ করে যা ম্যাভেন রেপগুলিতে পাওয়া যায় নি যা বর্তমানে অ্যান্ড্রয়েডে জেএনএ কাজ করতে উপযোগী কারণ সমস্ত নেটিভ জারগুলি পাবলিক মেভেন রেপোগুলিতে প্রকাশিত হয় না।

android {
    compileSdkVersion 23
    buildToolsVersion '24.0.0'

    lintOptions {
        abortOnError false
    }


    defaultConfig {
        applicationId "myappid"
        minSdkVersion 17
        targetSdkVersion 23
        versionCode 1
        versionName "1.0.0"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }

    sourceSets {
        main {
            jniLibs.srcDirs = ["src/main/jniLibs", "$buildDir/native-libs"]
        }
    }
}

def urlFile = { url, name ->
    File file = new File("$buildDir/download/${name}.jar")
    file.parentFile.mkdirs()
    if (!file.exists()) {
        new URL(url).withInputStream { downloadStream ->
            file.withOutputStream { fileOut ->
                fileOut << downloadStream
            }
        }
    }
    files(file.absolutePath)
}
dependencies {
    testCompile 'junit:junit:4.12'
    compile 'com.android.support:appcompat-v7:23.3.0'
    compile 'com.android.support:design:23.3.0'
    compile 'net.java.dev.jna:jna:4.2.0'
    compile urlFile('https://github.com/java-native-access/jna/blob/4.2.2/lib/native/android-arm.jar?raw=true', 'jna-android-arm')
    compile urlFile('https://github.com/java-native-access/jna/blob/4.2.2/lib/native/android-armv7.jar?raw=true', 'jna-android-armv7')
    compile urlFile('https://github.com/java-native-access/jna/blob/4.2.2/lib/native/android-aarch64.jar?raw=true', 'jna-android-aarch64')
    compile urlFile('https://github.com/java-native-access/jna/blob/4.2.2/lib/native/android-x86.jar?raw=true', 'jna-android-x86')
    compile urlFile('https://github.com/java-native-access/jna/blob/4.2.2/lib/native/android-x86-64.jar?raw=true', 'jna-android-x86_64')
    compile urlFile('https://github.com/java-native-access/jna/blob/4.2.2/lib/native/android-mips.jar?raw=true', 'jna-android-mips')
    compile urlFile('https://github.com/java-native-access/jna/blob/4.2.2/lib/native/android-mips64.jar?raw=true', 'jna-android-mips64')
}
def safeCopy = { src, dst ->
    File fdst = new File(dst)
    fdst.parentFile.mkdirs()
    fdst.bytes = new File(src).bytes

}

def archFromName = { name ->
    switch (name) {
        case ~/.*android-(x86-64|x86_64|amd64).*/:
            return "x86_64"
        case ~/.*android-(i386|i686|x86).*/:
            return "x86"
        case ~/.*android-(arm64|aarch64).*/:
            return "arm64-v8a"
        case ~/.*android-(armhf|armv7|arm-v7|armeabi-v7).*/:
            return "armeabi-v7a"
        case ~/.*android-(arm).*/:
            return "armeabi"
        case ~/.*android-(mips).*/:
            return "mips"
        case ~/.*android-(mips64).*/:
            return "mips64"
        default:
            return null
    }
}

task extractNatives << {
    project.configurations.compile.each { dep ->
        println "Scanning ${dep.name} for native libs"
        if (!dep.name.endsWith(".jar"))
            return
        zipTree(dep).visit { zDetail ->
            if (!zDetail.name.endsWith(".so"))
                return
            print "\tFound ${zDetail.name}"
            String arch = archFromName(zDetail.toString())
            if(arch != null){
                println " -> $arch"
                safeCopy(zDetail.file.absolutePath,
                        "$buildDir/native-libs/$arch/${zDetail.file.name}")
            } else {
                println " -> No valid arch"
            }
        }
    }
}

preBuild.dependsOn(['extractNatives'])

0

আমি উপরের উত্তরে সমাধানগুলি চেষ্টা করেছিলাম কিন্তু কেউই আমার পক্ষে কাজ করেনি। আমার কাছে .so, .dll এবং .jar ফাইল সহ একটি গ্রন্থাগার ছিল। শেষে আমি এটি করেছি, আপনি বিশদটি এখানে দেখতে পাবেন: https://stackoverflow.com/a/54976458/7392868

আমি jniLibs নামে একটি ফোল্ডারে .so ফাইলগুলি অনুলিপি করে এটিকে অ্যাপ্লিকেশন / এসসিআর / প্রধান / ফোল্ডারের ভিতরে আটকানো করেছি। অন্যান্য নির্ভরতার জন্য আমি গ্রেড নির্ভরতা ব্যবহার করি।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.