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

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

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

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

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

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

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

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

যখন প্রতিফলন ঠিক থাকে

যদি আপনাকে প্রতিফলন ব্যবহার করতেই হয়, তাহলে আপনার কেবল নিম্নলিখিত যেকোনো একটিতে প্রতিফলন করা উচিত:

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

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

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

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

লাইব্রেরিতে দুটি স্বতন্ত্র ধরণের কিপ নিয়ম থাকতে পারে:

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

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

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

  • অনুপযুক্ত গ্লোবাল নিয়ম ব্যবহার করবেন না—আপনার লাইব্রেরির কনজিউমার কিপ রুলস ফাইলে -dontobfuscate বা -allowaccessmodification এর মতো গ্লোবাল সেটিংস রাখা এড়িয়ে চলুন, কারণ এগুলি আপনার লাইব্রেরি ব্যবহারকারী সমস্ত অ্যাপকে প্রভাবিত করে।
  • প্যাকেজ-ব্যাপী কিপ নিয়ম অন্তর্ভুক্ত করবেন না যেমন -keep class com.mylibrary.** { *; } । এই ধরনের নিয়ম সমগ্র লাইব্রেরিতে অপ্টিমাইজেশন সীমিত করে, যা লাইব্রেরি ব্যবহার করে এমন সমস্ত অ্যাপের আকারকে প্রভাবিত করে।
  • আপনার লাইব্রেরির কনজিউমার কিপ রুলস ফাইলে -repackageclasses ব্যবহার করবেন না। তবে, আপনার লাইব্রেরি বিল্ড অপ্টিমাইজ করার জন্য, আপনি আপনার লাইব্রেরির বিল্ড কিপ রুলস ফাইলে -repackageclasses একটি অভ্যন্তরীণ প্যাকেজ নামের সাথে ব্যবহার করতে পারেন, যেমন <your.library.package>.internal এটি আপনার লাইব্রেরিটিকে আরও দক্ষ করে তুলতে পারে, এমনকি যদি এটি ব্যবহার করে এমন অ্যাপগুলি অপ্টিমাইজ না করা হয়, তবে এটি সাধারণত প্রয়োজনীয় নয় কারণ অ্যাপগুলিকেও অপ্টিমাইজ করা উচিত। লাইব্রেরি অপ্টিমাইজ করার বিষয়ে আরও তথ্যের জন্য, লাইব্রেরি লেখকদের জন্য অপ্টিমাইজেশন দেখুন।
  • আপনার লাইব্রেরির Keep rules ফাইলগুলিতে আপনার লাইব্রেরির কাজ করার জন্য প্রয়োজনীয় যেকোনো অ্যাট্রিবিউট ঘোষণা করুন, এমনকি যদি 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 লাইব্রেরির জন্য কনজিউমার রুলস যোগ করতে, অ্যান্ড্রয়েড লাইব্রেরি মডিউলের বিল্ড স্ক্রিপ্টে consumerProguardFiles বিকল্পটি ব্যবহার করুন। আরও তথ্যের জন্য, লাইব্রেরি মডিউল তৈরির বিষয়ে আমাদের নির্দেশিকা দেখুন।

কোটলিন

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

খাঁজকাটা

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

JAR লাইব্রেরি

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

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

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

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

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

কোটলিন

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 উভয় ক্ষেত্রেই keep নিয়মগুলি সংজ্ঞায়িত করতে হতে পারে।

যদি আপনি আপনার লাইব্রেরির বিল্ডে -repackageclasses ব্যবহার করেন, তাহলে আপনার লাইব্রেরির প্যাকেজের ভিতরে একটি সাব-প্যাকেজে ক্লাসগুলি পুনরায় প্যাকেজ করুন। উদাহরণস্বরূপ, -repackageclasses ' -repackageclasses 'internal' -repackageclasses 'com.example.mylibrary.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-from-<X>-upto-<Y> আকারে নাম সহ একাধিক সাবডিরেক্টরি থাকতে পারে যা নির্দেশ করে যে কোন R8 সংস্করণের জন্য নিয়মগুলি লেখা হয়েছে। প্রতিটি সাবডিরেক্টরিতে 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 সংস্করণ পর্যন্ত ব্যবহার করা যেতে পারে কিন্তু অন্তর্ভুক্ত নয়

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