সিস্টেম.লোডলিবারি (…) আমার ক্ষেত্রে নেটিভ লাইব্রেরিটি খুঁজে পেল না


91

আমি অন্য একটি অ্যান্ড্রয়েড প্রকল্প থেকে একটি বিদ্যমান নেটিভ লাইব্রেরিটি ব্যবহার করতে চাই , তাই আমি কেবলমাত্র আমার নতুন অ্যান্ড্রয়েড প্রকল্পে এনডিকে নির্মিত লাইব্রেরি ( libcalculate.so ) অনুলিপি করেছি। আমার নতুন অ্যান্ড্রয়েড প্রকল্পে আমি একটি ফোল্ডার তৈরি করেছি libs/armeabi/এবং সেখানে libcalculate.so রেখেছি । নেই কোন jni / ফোল্ডার। আমার পরীক্ষার ডিভাইসে এআরএম আর্কিটেকচার রয়েছে।

আমার জাভা কোডগুলিতে আমি লাইব্রেরিটি লোড করেছি:

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

আমি যখন আমার নতুন অ্যান্ড্রয়েড প্রকল্পটি চালাচ্ছি তখন আমার ত্রুটি হয়েছিল:

java.lang.UnsatisfiedLinkError:  ...
nativeLibraryDirectories=[/vendor/lib, /system/lib]]] couldn't find "libcalculate.so"

সুতরাং, ত্রুটি হিসাবে যেমন বলা হয়েছে, অনুলিপি নেটিভ লাইব্রেরিটি / রায় / লিব বা / সিস্টেম / লাইব নয়, আমার ক্ষেত্রে এই সমস্যাটি কীভাবে সমাধান করবেন?

(আমি apk প্যাকেজটি আনজিপ করেছি, lib এর অধীনে / সেখানে libcalculate.so রয়েছে)

==== আপডেট =====

আমি প্রকল্পের মূলের অধীনে একটি জনি / ফোল্ডার তৈরি করার চেষ্টা করেছি এবং jni / এর অধীনে একটি Android.mk ফাইল যুক্ত করতে চাইছি। Android.mk এর সামগ্রীটি হ'ল:

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)
LOCAL_MODULE    := libcalculate
LOCAL_SRC_FILES := libcalculate.so
include $(PREBUILT_SHARED_LIBRARY)

তারপরে, প্রকল্পের মূলের অধীনে, আমি এনডিকে-বিল্ড সম্পাদন করেছি। এর পরে, আরডিবি / এবং আরমেবি-ভি 7 এ / ডিরেক্টরিগুলি এনডিকে-বিল্ড দ্বারা উত্পাদিত হয় (ফোল্ডারের অভ্যন্তরে libcalculate.so সহ)।

তারপরে আমি আমার মেভেনটি প্রকল্পটি সফলভাবে তৈরিতে চালিত করছি। চূড়ান্ত এপিপি প্যাকেজে রয়েছে:

lib/armeabi/libcalculate.so
lib/armeabi-v7a/libcalculate.so

তবে আমি যখন আমার অ্যাপ্লিকেশনটি চালাচ্ছি তখন একই ত্রুটিটি ছুঁড়ে ফেলা হবে:

java.lang.UnsatisfiedLinkError:  ...
nativeLibraryDirectories=[/vendor/lib, /system/lib]]] couldn't find "libcalculate.so"

4
আপনি সরাসরি লাইব্রেরির নীচে রেখেছেন libs/? আপনার সম্ভবত লক্ষ্য ABI- র প্রতি একটি উপ-ডিরেক্টরি তৈরি করতে হবে যা আপনি সমর্থন করতে চান (আরমেবি, আরমেবি-ভি 7 এ, x86, মিপস, ইত্যাদি) এবং প্রতিটি উপ-ডিরেক্টরিতে যথাযথ .so ফাইল স্থাপন করতে হবে (অর্থাত্ আরমেবির জন্য নির্মিত .so ফাইলটি প্রবেশ করে libs/armeabi/, ইত্যাদি)।
মাইকেল

@ মিশেল, আমি কেবল আমার পোস্টে মিস করেছি, আমি আসলে এটিকে লিবিস / আরমেবি /
ইউজার 842225

পরীক্ষা করুন যে libcalculate.so আসলে প্যাকেজিং প্রক্রিয়াটি গ্রহণ করেছে - উদাহরণস্বরূপ চেষ্টা করুন unzip -l package.apk, বা অ্যাপ্লিকেশনটিকে .zip নামকরণ করুন এবং কিছু অ্যাপ্লিকেশন দিয়ে এটি খুলুন। এটি যদি না থাকে তবে এটি প্যাকেজিংয়ে কিছু ভুল হয়েছে (আপনার আইডিই ফোল্ডারটি লক্ষ্য করেছেন, আপনার কি প্রকল্পটি রিফ্রেশ করার দরকার আছে?)।
mstorsjo

@ এমস্টোরসো, আমি apk প্যাকেজটি আনজিপ করেছি, lib এর অধীনে / সেখানে libcalculate.so আছে
ব্যবহারকারী 842225

4
আপনার একটি Android.mk বা কোনও সংকলন সম্পর্কিত ফাইল থাকতে হবে না। এই জাতীয় ফাইলগুলি কেবল এখানে যেমন jniLibs এ তাদের সাব-ডাইরেক্টরিগুলিতে রেখে দিন: github.com/Ph1b/MaterialAudiobookPlayer/tree/master/audiobook/…
পল ওয়ারিটচেক

উত্তর:


177

মূল কারণের জন্য (এবং একই সাথে আপনার সমস্যার সমাধান হতে পারে), আপনি যা করতে পারেন তা এখানে:

  1. Jni ফোল্ডার এবং সমস্ত .mk ফাইল সরান । আপনি যদি কিছু সংকলন না করে থাকেন তবে আপনার প্রয়োজন নেই বা এনডিকে দরকার নেই।

  2. আপনার কপি libcalculate.soফাইল ভিতরে <project>/libs/(armeabi|armeabi-v7a|x86|...)। অ্যান্ড্রয়েড স্টুডিও ব্যবহার করার সময়, এটি <project>/app/src/main/jniLibs/(armeabi|armeabi-v7a|x86|...)কিন্তু আমি দেখতে পাচ্ছি আপনি গ্রহণ ব্যবহার করছেন।

  3. আপনার ফাইলটি লাইব / (আরমেবি | আরমেবি-ভি 7 এ | x86 | ...) এর ভিতরে আছে কিনা তা পরীক্ষা করতে আপনার এপিএকে তৈরি করুন এবং এটিকে জিপ ফাইল হিসাবে খুলুন ।libcalculate.so

  4. আপনার অ্যাপ্লিকেশন সরান এবং ইনস্টল করুন

  5. পাম্প প্যাকেজ চালান | yourpackagename grep পেতে nativeLibraryPath বা legacyNativeLibraryDir আপনার আবেদনের।

  6. চালান উপর nativeLibraryPath আপনি ছিল বা legacyNativeLibraryDir / armeabi যদি আপনার libcalculate.so প্রকৃতপক্ষে নেই, বার করো।

  7. যদি এটি সেখানে থাকে তবে এটি আপনার মূল লাইব্যালকুলেট.সো ফাইল থেকে পরিবর্তন করা হয়নি কিনা তা পরীক্ষা করুন: এটি কি সঠিক আর্কিটেকচারের বিপরীতে সংকলিত হয়েছে, এতে কি প্রত্যাশিত প্রতীক রয়েছে, কোনও অনুপস্থিত নির্ভরতা রয়েছে কি? আপনি রিডফেল ব্যবহার করে libcalculate.so বিশ্লেষণ করতে পারেন।

পদক্ষেপ 5-7 চেক করতে, আপনি কমান্ড লাইন এবং রিডফেল: নেটিভ লিবস মনিটরের পরিবর্তে আমার অ্যাপ্লিকেশনটি ব্যবহার করতে পারেন

পিএস: .so ফাইলগুলি কোথায় রাখা বা ডিফল্টরূপে উত্পন্ন করা উচিত তা নিয়ে বিভ্রান্ত হওয়া সহজ, এখানে একটি সংক্ষিপ্তসার রয়েছে:

  • একটি গ্রহণ প্রকল্পের মধ্যে libs / CPU_ABI

  • একটি অ্যান্ড্রয়েড স্টুডিও প্রকল্পের মধ্যে jniLibs / CPU_ABI

  • জনি / সিপিইউআইবিআইএআর এর ভিতরে inside

  • চূড়ান্ত APK এর ভিতরে lib / CPU_ABI

  • অ্যাপের ভিতরে nativeLibraryPath একটি উপর <5.0 ডিভাইস, এবং অ্যাপ্লিকেশনের ভিতরে legacyNativeLibraryDir / CPU_ARCH একটি উপর> = 5.0 ডিভাইস।

যেখানে সিপিইউএবিআইবি হ'ল: আরমেবি, আরমেবি-ভি 7 এ, আর্ম 64-ভি 8 এ, এক্স 86, এক্স 86_64, মিপস, মিপস 64 । আপনি কোন আর্কিটেকচারকে টার্গেট করছেন তার উপর নির্ভর করে এবং আপনার লিবিগুলি সংকলিত হয়েছে।

নোট যে লিব CPU_ABI ডিরেক্টরি মধ্যে মিশিয়ে নয়: আপনি কি ব্যবহার করছেন পূর্ণ সেট, একটি শান্ত করে ভিতরে যে প্রয়োজন armeabi ফোল্ডারের একটি ইনস্টল করা হবে না armeabi-v7a ডিভাইস যদি ভিতরে কোন লিব হয় armeabi -পি 7 থেকে ফ7 ফোল্ডার।


4
দুর্দান্ত মানুষ, ধন্যবাদ! আমি অ্যান্ড্রয়েড স্টুডিও ব্যবহার করছি এবং আমার জনি বিল্ডগুলি জনিলিবগুলির পরিবর্তে লিবগুলিতে অনুলিপি করা হচ্ছে।
লুইস

4
পুরো সেটটি সম্পর্কে প্রয়োজনীয় সর্বশেষ নোটটি আমার জন্য অত্যন্ত গুরুত্বপূর্ণ। ওটাই ছিল আমার সমস্যা, ধন্যবাদ!
বেন ট্রেনগ্রোভ

জন্য 7অধ্যায়: আপনি বোঝাতে চেয়েছেন .so করা APK থেকে পরিবর্তিত করা যেতে পারে এটা ডিভাইসে ইনস্টল করা হয়েছে পরে? যদি এমন কোন সুযোগ থাকে তবে সিস্টেমটি .so ফাইলটি নষ্ট করতে পারে?
জয়াতুবি

4
অপূর্ব! আমার খুব বিস্ময়কর ক্ষেত্রে, আমি গ্র্যাডলের মাধ্যমে একটি পৃথক ২ য় পক্ষের লাইব্রেরি যুক্ত করার পরে আমি গ্রন্থাগারের একটি তৃতীয় পক্ষের গ্রন্থাগার ( ওপেনসিভি - আরমেবি ফোল্ডারে) ব্যবহার করছিলাম এবং সেই লাইব্রেরিগুলি লোড করা বন্ধ করে দিয়েছে। দেখা যাচ্ছে যে দ্বিতীয় লাইব্রেরি এআরএমভি 5 বা 6 সমর্থন করে না এবং এটি অন্তর্ভুক্ত করে আমার ওপেনসিভি লাইব্রেরিগুলি অদৃশ্য হয়ে গেছে (যদিও তারা আসলে সেখানে ছিল )। সম্পূর্ণ সেট সম্পর্কে আপনার বক্তব্য আমাকে ক্লু দিয়েছে - আরমেবি ফোল্ডারটির নাম পরিবর্তন করে এটিকে আরমেবি-ভি 7 এ বলা সমস্যাটি স্থির করেছে (যেহেতু আমি এখন এআরএম 5 বা 6 সমর্থন করি না)। দুষ্ট সমস্যা !!
মেটা

4
আপনার lib ফাইলটি কোথায় রাখবেন তা খুঁজে বের করার আরেকটি উপায় (* .so) আপনার অ্যাপ্লিকেশনটি চালাবেন এবং নেটিভ লাইবারিডির ব্যবহার করে মুদ্রণ করুন: System.out.println (getApplicationContext () আপনাকে এবিআই সরবরাহ করবে।
ডেভিড রাউকা

20

গ্রেডে, সমস্ত ফাইলের ফোল্ডারগুলিতে অনুলিপি করার পরে libs/

jniLibs.srcDirs = ['libs']

উপরোক্ত লাইন যোগ sourceSetsমধ্যে build.gradleফাইল কাজ করেন। আর কিছুই কিছুই করেনি।


4
বিল্ড.gradle ফাইলটিতে "উত্সসেটস" রয়েছে?
আশানা.জ্যাকল

12

আপনি গ্রেড ব্যবহার করছেন? যদি তাই হয় তবে .soফাইলটি .ুকিয়ে দিন<project>/src/main/jniLibs/armeabi/

আমি আসা করি এটা সাহায্য করবে.


না, আমি গ্রেড ব্যবহার করছি না, আমি গ্রহন +
maven

12

আমার ক্ষেত্রে অবশ্যই গ্রেড এবং লিব পাথ সেট করে সংকলন উত্সগুলি অবশ্যই বাদ দিতে হবে

android {

    ...
    sourceSets {
        ...
        main.jni.srcDirs = []
        main.jniLibs.srcDirs = ['libs']
    }
....

এটি আমার পক্ষেও সমাধান হয়েছে এবং আমি আরমেবি-ভি 7 এ এবং এক্স 86 ফোল্ডারে আরমেবি ফাইল যুক্ত করেছি তবে এটি প্রয়োজনীয় কিনা তা সম্পর্কে আমি নিশ্চিত নই।
dokam_scotland

8

এই ত্রুটির কারণ হ'ল আপনার অ্যাপ্লিকেশন এবং যে নেটিভ লাইব্রেরির সাথে আপনি লিঙ্ক করেছেন তার মধ্যে এবিআইয়ের অমিল রয়েছে। অন্য শব্দ, আপনার অ্যাপ্লিকেশন এবং আপনার .soবিভিন্ন এবিআইকে লক্ষ্য করছে।

আপনি যদি সর্বশেষে অ্যান্ড্রয়েড স্টুডিও টেম্পলেটগুলি ব্যবহার করে আপনার অ্যাপটি তৈরি করেন arm64-v8aতবে এটি সম্ভবত লক্ষ্যমাত্রা তৈরি করছে তবে উদাহরণস্বরূপ আপনার .soলক্ষ্য হতে পারে armeabi-v7a

এই সমস্যাটি সমাধান করার 2 উপায় রয়েছে:

  1. আপনার অ্যাপের সহায়তার জন্য প্রতিটি এবিআইয়ের জন্য আপনার নেটিভ লাইব্রেরি তৈরি করুন।
  2. আপনার .soবিপরীতে নির্মিত পুরানো এবিআইকে লক্ষ্য করতে আপনার অ্যাপ্লিকেশনটি পরিবর্তন করুন ।

পছন্দ 2 নোংরা তবে আমার মনে হয় আপনার সম্ভবত এতে আরও আগ্রহ রয়েছে:

আপনার অ্যাপ্লিকেশন পরিবর্তন build.gradle

android {
    defaultConfig {
        ...
        ndk {
            abiFilters 'armeabi-v7a'
        }
   }
}

আমার অ্যাপটি যদি আমি গ্রহণ করি? এই সমস্যাটি তখন আসছে যখন আমি একই কাস্টমাইজড অ্যাপ্লিকেশনটি 6 থেকে 9 এ স্থানান্তরিত করব
শ্যাডো

6

রেফারেন্সের জন্য, আমার এই ত্রুটি বার্তাটি ছিল এবং সমাধানটি হ'ল আপনি গ্রন্থাগারটি নির্দিষ্ট করার সময় আপনি সামনে থেকে 'লিবিব' এবং শেষ থেকে '.so' মিস করবেন।

সুতরাং, যদি আপনার কাছে libmyfablib.so ফাইল থাকে তবে আপনাকে কল করতে হবে:

   System.loadLibrary("myfablib"); // this loads the file 'libmyfablib.so' 

এপিকে দেখে, ইনস্টল / আনইনস্টল করা এবং সব ধরণের জটিল সমাধান চেষ্টা করে দেখতে পেলাম না যে সাধারণ সমস্যাটি আমার মুখের সামনে ঠিক ছিল!


ঐটা এটা ছিল. কিছু অজানা কারণে অ্যান্ড্রয়েড লাইব্রেরি ইনস্টল করে না যাদের ফাইলের নাম 'lib' দিয়ে শুরু হয় না, এমনকি প্যাকেজে উপস্থিত থাকলেও। চিত্র দেখুন ...
জর্জ ওয়াই।

প্রকল্পে আমি এটি কোথায় দেখতে পারি? আমি বলতে চাচ্ছি আমি কোথায় এই লাইন জানতে পারেন System.loadLibraryকোডে
aleksandrbel

ধন্যবাদ এই সাহায্য!
রিসখান

5

এটি একটি অ্যান্ড্রয়েড 8 আপডেট।

অ্যান্ড্রয়েডের পূর্ববর্তী সংস্করণে, লোডলাইবারি নেটিভ শেয়ারড লাইব্রেরিগুলিতে (উদাহরণস্বরূপ জেএনআই এর মাধ্যমে অ্যাক্সেসের জন্য) আমি বিভিন্ন এপিপি ইনস্টলেশন / আপগ্রেড অ্যালগরিদমের উপর ভিত্তি করে লাইব ফোল্ডারের জন্য সম্ভাব্য ডিরেক্টরি পথের একটি পরিসরটি পুনরাবৃত্তি করতে আমার নেটিভ কোডটি হার্ড-ওয়্যারযুক্ত করেছি:

/data/data/<PackageName>/lib
/data/app-lib/<PackageName>-1/lib
/data/app-lib/<PackageName>-2/lib
/data/app/<PackageName>-1/lib
/data/app/<PackageName>-2/lib

এই পদ্ধতির হকি এবং অ্যান্ড্রয়েড 8 এর জন্য কাজ করবে না; https://developer.android.com/about/versions/oreo/android-8.0-changes.html থেকে আপনি দেখতে পাবেন যে তাদের "সুরক্ষা" পরিবর্তনের অংশ হিসাবে আপনাকে এখন সোর্সডির ব্যবহার করতে হবে:

"আপনি আর ধরে নিতে পারবেন না যে APKs ডিরেক্টরিগুলির মধ্যে রয়েছে যার নাম -1 বা -2-এ শেষ হয় Apps

সংশোধন, উত্সডির আপনার স্থানীয় ভাগ করা লাইব্রেরিগুলি খুঁজে পাওয়ার উপায় নয়; মত কিছু ব্যবহার। Android 4.4.4 -> 8.0 এর জন্য পরীক্ষিত

// Return Full path to the directory where native JNI libraries are stored.
private static String getNativeLibraryDir(Context context) {
    ApplicationInfo appInfo = context.getApplicationInfo();
    return appInfo.nativeLibraryDir;
}

4

PREBUILT_SHARED_LIBRARYবিভাগ অন্তর্ভুক্ত করার পরে আপনার লাইব্রেরি কল করার চেষ্টা করুন :

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)
LOCAL_MODULE    := libcalculate
LOCAL_SRC_FILES := <PATH>/libcalculate.so
include $(PREBUILT_SHARED_LIBRARY)

#...

LOCAL_SHARED_LIBRARIES += libcalculate

হালনাগাদ:

আপনি যদি জাভাতে এই লাইব্রেরিটি ব্যবহার করেন তবে আপনাকে এটি ভাগ করে নেওয়া লাইব্রেরি হিসাবে সংকলন করতে হবে

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)
LOCAL_MODULE    := libcalculate
LOCAL_SRC_FILES := <PATH>/libcalculate.so
include $(BUILD_SHARED_LIBRARY)

এবং আপনার /vendor/libডিরেক্টরিতে লাইব্রেরি স্থাপন করতে হবে ।


শুধুমাত্র বিভাগের শেষে।
অ্যালেক্স

2

আপনি পুরানো বিল্ডগুলি ব্যবহার করতে কেবল এবিআইকে পরিবর্তন করতে পারেন:

defaultConfig {
    ...

    ndk {
        abiFilters 'armeabi-v7a'
    }
    ...
}

আপনার এই লাইনটি যুক্ত করে অবহিত এনডিকেও ব্যবহার করা উচিত gradle.properties:

android.useDeprecatedNdk=true

0

সমস্ত suport যোগ করুন

app / build.gradle .g

ndk {
        moduleName "serial_port"
        ldLibs "log", "z", "m"
        abiFilters "arm64-v8a","armeabi", "armeabi-v7a", "x86","x86_64","mips","mips64"
}

অ্যাপ্লিকেশন \ src \ jni \ Application.mk

APP_ABI := arm64-v8a armeabi armeabi-v7a x86 x86_64 mips mips64

4
আপনি কি দয়া করে আরও নির্দিষ্ট করতে পারেন?
EFrank

আপনার প্রকল্পে .so ফাইল। আপনার আর্ম 64-v8a আরমেবি আরমেবি-ভি 7 এ x86 x86_64 ম্যাপস মিপস 64 সমর্থন করা উচিত। আমি যখন এটি করছিলাম তখন এটি ভালভাবে কাজ করে।
সিংহ 耿

-1

আমার অভিজ্ঞতায়, একটি আরমেবি-ভি 7 এ মোবাইলে, যখন আরএমবি এবং আরমেবি-ভি 7a ডিরেক্টরি দুটি এপিপিতে উপস্থিত থাকে, আরমেবি ডিরেক্টরিতে .so ফাইলগুলি সংযুক্ত হবে না, যদিও আরমেবিতে .so ফাইলগুলি লিঙ্কযুক্ত হবে একই আরমেবি-ভি 7 এ মোবাইল, যদি আরমেবি-ভি 7 এ উপস্থিত না থাকে।


-1

আসলে, আপনি কেবল একটি .so ফাইল রাখতে পারবেন না /libs/armeabi/এবং এটি লোড করতে পারবেন না System.loadLibrary। আপনাকে একটি Android.mk ফাইল তৈরি করতে হবে এবং একটি প্রাক বিল্ট মডিউল ঘোষণা করতে হবে যেখানে আপনি আপনার .so ফাইলটিকে উত্স হিসাবে নির্দিষ্ট করেছেন।

এটি করতে, আপনার .so ফাইল এবং Android.mk ফাইলটিকে jniফোল্ডারে রাখুন। আপনার অ্যান্ড্রয়েড.এমকে দেখতে এমন কিছু দেখা উচিত:

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)
LOCAL_MODULE    := libcalculate
LOCAL_SRC_FILES := libcalculate.so
include $(PREBUILT_SHARED_LIBRARY)

উত্স: প্রিল বিল্ট সম্পর্কে অ্যান্ড্রয়েড এনডিকে ডকুমেন্টেশন

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