লাইব্রেরি লেখকদের জন্য অপ্টিমাইজেশান

একজন লাইব্রেরি লেখক হিসাবে, আপনাকে নিশ্চিত করতে হবে যে অ্যাপ বিকাশকারীরা একটি উচ্চ মানের শেষ ব্যবহারকারীর অভিজ্ঞতা বজায় রেখে সহজেই তাদের অ্যাপে আপনার লাইব্রেরি অন্তর্ভুক্ত করতে পারে। আপনার নিশ্চিত করা উচিত যে আপনার লাইব্রেরি অতিরিক্ত সেটআপ ছাড়াই Android অপ্টিমাইজেশানের সাথে সামঞ্জস্যপূর্ণ—অথবা Android-এ ব্যবহারের জন্য লাইব্রেরিটি অনুপযুক্ত হতে পারে এমন নথি।

এই ডকুমেন্টেশনটি প্রকাশিত লাইব্রেরির ডেভেলপারদের লক্ষ্য করা হয়েছে, তবে একটি বড়, মডুলারাইজড অ্যাপে অভ্যন্তরীণ লাইব্রেরি মডিউলগুলির বিকাশকারীদের জন্যও এটি কার্যকর হতে পারে৷

আপনি যদি একজন অ্যাপ ডেভেলপার হন এবং আপনার অ্যান্ড্রয়েড অ্যাপ অপ্টিমাইজ করার বিষয়ে জানতে চান, অ্যাপ অপ্টিমাইজেশন সক্ষম করুন দেখুন। কোন লাইব্রেরি ব্যবহার করা উপযুক্ত সে সম্পর্কে জানতে, বুদ্ধিমানের সাথে লাইব্রেরি চয়ন করুন দেখুন।

প্রতিফলনের উপর কোডজেন ব্যবহার করুন

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

  • কোডজেনের সাথে, বিল্ড প্রক্রিয়া চলাকালীন কোড বিশ্লেষণ এবং সংশোধন করা হয়। যেহেতু কম্পাইল সময়ের পরে কোন বড় পরিবর্তন নেই, অপ্টিমাইজার জানে শেষ পর্যন্ত কোন কোডের প্রয়োজন এবং কোনটি নিরাপদে সরানো যেতে পারে।
  • প্রতিফলনের সাথে, কোড বিশ্লেষণ করা হয় এবং রানটাইমে ম্যানিপুলেট করা হয়। যেহেতু কোডটি কার্যকর না হওয়া পর্যন্ত এটি সত্যিই চূড়ান্ত হয় না, অপ্টিমাইজার জানে না কোন কোডটি নিরাপদে সরানো যেতে পারে। এটি সম্ভবত রানটাইমের সময় প্রতিফলনের মাধ্যমে গতিশীলভাবে ব্যবহৃত কোডগুলি সরিয়ে ফেলবে, যা ব্যবহারকারীদের জন্য অ্যাপ ক্র্যাশের কারণ হয়।

অনেক আধুনিক লাইব্রেরি প্রতিফলনের পরিবর্তে কোডজেন ব্যবহার করে। একটি সাধারণ এন্ট্রিপয়েন্টের জন্য KSP দেখুন, Room , Dagger2 এবং আরও অনেকের দ্বারা ব্যবহৃত।

যখন প্রতিফলন ঠিক আছে

আপনি যদি প্রতিফলন ব্যবহার করতে চান তবে আপনাকে শুধুমাত্র নিম্নলিখিতগুলির মধ্যে প্রতিফলিত করা উচিত:

  • নির্দিষ্ট লক্ষ্যযুক্ত প্রকার (নির্দিষ্ট ইন্টারফেস বাস্তবায়নকারী বা উপশ্রেণী)
  • একটি নির্দিষ্ট রানটাইম টীকা ব্যবহার করে কোড

এইভাবে প্রতিফলন ব্যবহার করা রানটাইম খরচ সীমিত করে, এবং লক্ষ্যযুক্ত ভোক্তা রাখার নিয়ম লিখতে সক্ষম করে।

প্রতিফলনের এই নির্দিষ্ট এবং লক্ষ্যযুক্ত ফর্মটি হল একটি প্যাটার্ন যা আপনি অ্যান্ড্রয়েড ফ্রেমওয়ার্ক (উদাহরণস্বরূপ যখন ক্রিয়াকলাপ, দৃশ্য এবং অঙ্কন করা যায়) এবং অ্যান্ড্রয়েডএক্স লাইব্রেরি (উদাহরণস্বরূপ WorkManager ListenableWorkers , বা RoomDatabases নির্মাণের সময়) উভয় জুড়েই দেখতে পারেন। বিপরীতে, Gson-এর ওপেন এন্ডেড প্রতিফলন Android অ্যাপে ব্যবহারের জন্য উপযুক্ত নয়

লাইব্রেরিতে রাখার নিয়মের ধরন

দুটি স্বতন্ত্র ধরনের রাখার নিয়ম রয়েছে যা আপনি লাইব্রেরিতে রাখতে পারেন:

  • ভোক্তা রাখার নিয়মগুলি অবশ্যই এমন নিয়মগুলি নির্দিষ্ট করতে হবে যা লাইব্রেরিতে প্রতিফলিত যাই হোক না কেন। যদি একটি লাইব্রেরি তার কোডে কল করার জন্য প্রতিফলন বা JNI ব্যবহার করে, বা একটি ক্লায়েন্ট অ্যাপ দ্বারা সংজ্ঞায়িত কোড, এই নিয়মগুলি বর্ণনা করতে হবে কোন কোড রাখা দরকার। লাইব্রেরিগুলিকে ভোক্তা রাখার নিয়মগুলি প্যাকেজ করা উচিত, যা অ্যাপ রাখার নিয়মগুলির মতো একই বিন্যাস ব্যবহার করে। এই নিয়মগুলি লাইব্রেরি আর্টিফ্যাক্টগুলিতে (AARs বা JARs) একত্রিত করা হয় এবং যখন লাইব্রেরি ব্যবহার করা হয় তখন অ্যান্ড্রয়েড অ্যাপ অপ্টিমাইজেশানের সময় স্বয়ংক্রিয়ভাবে ব্যবহার হয়ে যায়। এই নিয়মগুলি আপনার build.gradle.kts (বা build.gradle ) ফাইলে consumerProguardFiles সম্পত্তির সাথে নির্দিষ্ট ফাইলে বজায় রাখা হয়। আরও জানতে, ভোক্তা রাখার নিয়ম লিখুন দেখুন।
  • আপনার লাইব্রেরি নির্মিত হলে লাইব্রেরি বিল্ড রাখার নিয়ম প্রয়োগ করা হয়। আপনি বিল্ড টাইমে আপনার লাইব্রেরিটি আংশিকভাবে অপ্টিমাইজ করার সিদ্ধান্ত নিলেই এগুলি প্রয়োজন। তাদের অবশ্যই লাইব্রেরির পাবলিক API সরানো থেকে রাখতে হবে, অন্যথায় সর্বজনীন API লাইব্রেরি বিতরণে উপস্থিত থাকবে না, যার অর্থ অ্যাপ বিকাশকারীরা লাইব্রেরি ব্যবহার করতে পারবেন না। এই নিয়মগুলি আপনার build.gradle.kts (বা build.gradle ) ফাইলে proguardFiles সম্পত্তির সাথে নির্দিষ্ট ফাইলে বজায় রাখা হয়। আরও জানতে, অপ্টিমাইজ AAR লাইব্রেরি বিল্ড দেখুন।

ভোক্তা রাখার নিয়ম লিখুন

সাধারণ রাখার নিয়ম নির্দেশিকা ছাড়াও, নিম্নলিখিতগুলি বিশেষভাবে লাইব্রেরি লেখকদের জন্য সুপারিশ করা হয়েছে৷

  • অনুপযুক্ত বিশ্বব্যাপী নিয়মগুলি ব্যবহার করবেন না—আপনার লাইব্রেরির ভোক্তার নিয়ম ফাইলে -dontobfuscate বা -allowaccessmodification মতো গ্লোবাল সেটিংস রাখা এড়িয়ে চলুন, কারণ তারা আপনার লাইব্রেরি ব্যবহার করে এমন সমস্ত অ্যাপকে প্রভাবিত করে।
  • আপনার লাইব্রেরির ভোক্তার নিয়ম ফাইলে -repackageclasses ব্যবহার করবেন না। যাইহোক, আপনার লাইব্রেরি বিল্ড অপ্টিমাইজ করার জন্য, আপনি একটি অভ্যন্তরীণ প্যাকেজ নামের সাথে -repackageclasses ব্যবহার করতে পারেন, যেমন <your.library.package>.internal , আপনার লাইব্রেরির বিল্ডে নিয়ম ফাইল রাখুন। এটি আপনার লাইব্রেরিটিকে আরও দক্ষ করে তুলতে পারে এমনকি যে অ্যাপগুলি এটি ব্যবহার করে সেগুলি অপ্টিমাইজ করা না হলেও এটি সাধারণত প্রয়োজনীয় নয় যেহেতু অ্যাপগুলিকেও অপ্টিমাইজ করা উচিত৷ লাইব্রেরি অপ্টিমাইজ করার বিষয়ে আরও বিস্তারিত জানার জন্য, লাইব্রেরি লেখকদের জন্য অপ্টিমাইজেশন দেখুন।
  • proguard-android-optimize.txt এ সংজ্ঞায়িত বৈশিষ্ট্যগুলির সাথে একটি ওভারল্যাপ থাকলেও আপনার লাইব্রেরির নিয়ম ফাইলগুলিতে আপনার লাইব্রেরির কাজ করার জন্য আপনার প্রয়োজনীয় কোনো বৈশিষ্ট্য ঘোষণা করুন।
  • আপনার যদি আপনার লাইব্রেরি ডিস্ট্রিবিউশনে নিম্নলিখিত বৈশিষ্ট্যগুলির প্রয়োজন হয়, তবে সেগুলি আপনার লাইব্রেরির বিল্ড কিপ রুলস ফাইলে বজায় রাখুন, আপনার লাইব্রেরির ভোক্তার নিয়ম ফাইলে নয় :
    • AnnotationDefault
    • EnclosingMethod
    • Exceptions
    • InnerClasses
    • RuntimeInvisibleAnnotations
    • RuntimeInvisibleParameterAnnotations
    • RuntimeInvisibleTypeAnnotations
    • RuntimeVisibleAnnotations
    • RuntimeVisibleParameterAnnotations
    • RuntimeVisibleTypeAnnotations
    • Signature
  • লাইব্রেরি লেখকদের উচিত RuntimeVisibleAnnotations অ্যাট্রিবিউট তাদের ভোক্তা রাখার নিয়মে রাখা যদি টীকা রানটাইমে ব্যবহার করা হয়।
  • লাইব্রেরি লেখকদের তাদের ভোক্তা রাখার নিয়মগুলিতে নিম্নলিখিত বিশ্বব্যাপী বিকল্পগুলি ব্যবহার করা উচিত নয়:
    • -include
    • -basedirectory
    • -injars
    • -outjars
    • -libraryjars
    • -repackageclasses
    • -flattenpackagehierarchy
    • -allowaccessmodification
    • -overloadaggressively
    • -renamesourcefileattribute
    • -ignorewarnings
    • -addconfigurationdebugging
    • -printconfiguration
    • -printmapping
    • -printusage
    • -printseeds
    • -applymapping
    • -obfuscationdictionary
    • -classobfuscationdictionary
    • -packageobfuscationdictionary

AAR লাইব্রেরি

একটি AAR লাইব্রেরির জন্য ভোক্তা নিয়ম যোগ করতে, Android লাইব্রেরি মডিউলের বিল্ড স্ক্রিপ্টে consumerProguardFiles বিকল্পটি ব্যবহার করুন। আরও তথ্যের জন্য, লাইব্রেরি মডিউল তৈরির বিষয়ে আমাদের নির্দেশিকা দেখুন।

কোটলিন

android {
    defaultConfig {
        consumerProguardFiles("consumer-proguard-rules.pro")
    }
    ...
}

গ্রোভি

android {
    defaultConfig {
        consumerProguardFiles 'consumer-proguard-rules.pro'
    }
    ...
}

JAR লাইব্রেরি

আপনার কোটলিন/জাভা লাইব্রেরির সাথে নিয়মগুলি বান্ডিল করতে যা JAR হিসাবে পাঠানো হয়, আপনার নিয়ম ফাইলটি যেকোন ফাইলের নাম সহ চূড়ান্ত JAR-এর META-INF/proguard/ ডিরেক্টরিতে রাখুন৷ উদাহরণস্বরূপ যদি আপনার কোড <libraryroot>/src/main/kotlin এ থাকে, তাহলে <libraryroot>/src/main/resources/META-INF/proguard/consumer-proguard-rules.pro এ একটি ভোক্তা নিয়ম ফাইল রাখুন এবং নিয়মগুলি আপনার আউটপুট JAR-এ সঠিক অবস্থানে বান্ডিল করা হবে।

META-INF/proguard ডিরেক্টরিতে নিয়মগুলি আছে কিনা তা পরীক্ষা করে নিশ্চিত করুন যে চূড়ান্ত JAR বান্ডেলগুলি সঠিকভাবে নিয়ম করেছে৷

AAR লাইব্রেরি বিল্ড অপ্টিমাইজ করুন (উন্নত)

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

আপনি যদি এখনও বিল্ড টাইমে আপনার লাইব্রেরি অপ্টিমাইজ করতে চান তবে এটি Android Gradle Plugin দ্বারা সমর্থিত।

কোটলিন

android {
    buildTypes {
        release {
            isMinifyEnabled = true
            proguardFiles(
                getDefaultProguardFile("proguard-android-optimize.txt"),
                "proguard-rules.pro"
            )
        }
        configureEach {
            consumerProguardFiles("consumer-rules.pro")
        }
    }
}

গ্রোভি

android {
    buildTypes {
        release {
            minifyEnabled true
            proguardFiles
                getDefaultProguardFile('proguard-android-optimize.txt'),
                'proguard-rules.pro'
        }
        configureEach {
            consumerProguardFiles "consumer-rules.pro"
        }
    }
}

উল্লেখ্য যে proguardFiles এর আচরণ consumerProguardFiles থেকে খুব আলাদা:

  • proguardFiles বিল্ড টাইমে ব্যবহার করা হয়, প্রায়ই getDefaultProguardFile("proguard-android-optimize.txt") এর সাথে, লাইব্রেরি তৈরির সময় আপনার লাইব্রেরির কোন অংশ রাখা উচিত তা নির্ধারণ করতে। সর্বনিম্ন, এটি আপনার সর্বজনীন API।
  • কনট্রাস্ট দ্বারা consumerProguardFiles আপনার লাইব্রেরি ব্যবহার করে এমন একটি অ্যাপ তৈরি করার সময় পরবর্তীতে কী অপ্টিমাইজেশান ঘটবে তা প্রভাবিত করতে লাইব্রেরিতে প্যাকেজ করা হয়।

উদাহরণস্বরূপ, যদি আপনার লাইব্রেরি অভ্যন্তরীণ ক্লাস তৈরি করতে প্রতিফলন ব্যবহার করে, তাহলে আপনাকে proguardFiles এবং consumerProguardFiles উভয় ক্ষেত্রেই রাখার নিয়মগুলি সংজ্ঞায়িত করতে হতে পারে।

আপনি যদি আপনার লাইব্রেরির বিল্ডে -repackageclasses ব্যবহার করেন, তাহলে আপনার লাইব্রেরির প্যাকেজের ভিতরে একটি সাব-প্যাকেজে ক্লাস রিপ্যাকেজ করুন। উদাহরণস্বরূপ, -repackageclasses 'com.example.mylibrary.internal' -repackageclasses 'internal' ব্যবহার করুন।

বিভিন্ন R8 সংস্করণ সমর্থন করে (উন্নত)

আপনি R8 এর নির্দিষ্ট সংস্করণগুলিকে লক্ষ্য করার জন্য নিয়মগুলি তৈরি করতে পারেন৷ এটি আপনার লাইব্রেরিটিকে নতুন R8 সংস্করণ ব্যবহার করে এমন প্রকল্পগুলিতে সর্বোত্তমভাবে কাজ করতে সক্ষম করে, যেখানে বিদ্যমান নিয়মগুলি পুরানো R8 সংস্করণগুলির সাথে প্রকল্পগুলিতে ব্যবহার করা চালিয়ে যাওয়ার অনুমতি দেয়।

লক্ষ্যযুক্ত R8 নিয়মগুলি নির্দিষ্ট করতে, আপনাকে সেগুলিকে একটি AAR-এর classes.jar এর ভিতরে META-INF/com.android.tools ডিরেক্টরিতে বা একটি JAR-এর META-INF/com.android.tools ডিরেক্টরিতে অন্তর্ভুক্ত করতে হবে৷

In an AAR library:
    proguard.txt (legacy location, the file name must be "proguard.txt")
    classes.jar
    └── META-INF
        └── com.android.tools (location of targeted R8 rules)
            ├── r8-from-<X>-upto-<Y>/<R8-rule-files>
            └── ... (more directories with the same name format)

In a JAR library:
    META-INF
    ├── proguard/<ProGuard-rule-files> (legacy location)
    └── com.android.tools (location of targeted R8 rules)
        ├── r8-from-<X>-upto-<Y>/<R8-rule-files>
        └── ... (more directories with the same name format)

META-INF/com.android.tools ডিরেক্টরিতে, নিয়মগুলি কোন R8 সংস্করণের জন্য লেখা হয়েছে তা নির্দেশ করতে r8-from-<X>-upto-<Y> নামে একাধিক সাব-ডিরেক্টরি থাকতে পারে। প্রতিটি সাবডিরেক্টরিতে যেকোন ফাইলের নাম এবং এক্সটেনশন সহ R8 নিয়ম সমন্বিত এক বা একাধিক ফাইল থাকতে পারে।

মনে রাখবেন যে -from-<X> এবং -upto-<Y> অংশগুলি ঐচ্ছিক, <Y> সংস্করণটি একচেটিয়া , এবং সংস্করণের রেঞ্জগুলি সাধারণত অবিচ্ছিন্ন থাকে তবে ওভারল্যাপও করতে পারে৷

উদাহরণস্বরূপ, r8 , r8-upto-8.0.0 , r8-from-8.0.0-upto-8.2.0 , এবং r8-from-8.2.0 হল টার্গেট করা R8 নিয়মের একটি সেট প্রতিনিধিত্বকারী ডিরেক্টরির নাম। r8 ডিরেক্টরির অধীনে নিয়মগুলি যেকোন R8 সংস্করণ দ্বারা ব্যবহার করা যেতে পারে। r8-from-8.0.0-upto-8.2.0 ডিরেক্টরির অধীনে নিয়মগুলি R8 দ্বারা সংস্করণ 8.0.0 থেকে সংস্করণ 8.2.0 পর্যন্ত ব্যবহার করা যেতে পারে তবে সংস্করণ 8.2.0 অন্তর্ভুক্ত নয়

অ্যান্ড্রয়েড গ্রেডল প্লাগইন বর্তমান R8 সংস্করণ দ্বারা ব্যবহার করা যেতে পারে এমন সমস্ত নিয়ম নির্বাচন করতে সেই তথ্য ব্যবহার করে। যদি একটি লাইব্রেরি লক্ষ্যযুক্ত R8 নিয়মগুলি নির্দিষ্ট না করে, তাহলে Android Gradle প্লাগইন উত্তরাধিকার অবস্থান থেকে নিয়মগুলি নির্বাচন করবে (একটি AAR-এর জন্য proguard.txt অথবা META-INF/proguard/<ProGuard-rule-files> একটি JAR-এর জন্য)।