কোন সম্পদ রাখতে হবে তা কাস্টমাইজ করুন

আপনি যখন অ্যাপ অপ্টিমাইজেশান সক্ষম করেন , তখন isShrinkResources = true সেটিং অপ্টিমাইজারকে অব্যবহৃত সংস্থানগুলি সরাতে নির্দেশ দেয়, যা আপনার অ্যাপের আকার কমাতে সাহায্য করে৷ রিসোর্স সঙ্কুচিত করা শুধুমাত্র কোড সঙ্কুচিত করার সাথে কাজ করে, তাই আপনি যদি রিসোর্স অপ্টিমাইজ করে থাকেন, তাহলে isMinifyEnabled = true ও সেট করুন, উদাহরণস্বরূপ:

buildTypes {
    release {
        isMinifyEnabled = true
        isShrinkResources = true
        ...
    }
}

আপনি যদি নির্দিষ্ট সংস্থানগুলি রাখতে বা বাতিল করতে চান তবে আপনার প্রকল্প সংস্থানগুলিতে একটি XML Keep ফাইল তৈরি করুন, উদাহরণস্বরূপ res/raw/my.package.keep.xml । Keep ফাইলের নিম্নলিখিত উপাদান রয়েছে:

  • <resources> ট্যাগ — সমস্ত চাইল্ড রিসোর্স এলিমেন্ট ধারণ করে এবং অ্যাট্রিবিউটগুলি রাখা/বর্জন করে।
  • tools:keep অ্যাট্রিবিউট — সম্পদের নামগুলির একটি কমা-বিভক্ত তালিকা গ্রহণ করে যা রাখার জন্য সংস্থানগুলি সনাক্ত করে
  • tools:discard অ্যাট্রিবিউট — রিসোর্স নামের একটি কমা-বিভক্ত তালিকা গ্রহণ করে যা বাতিল করার জন্য রিসোর্স সনাক্ত করে

একই ফোল্ডারে একাধিক সংস্থান উল্লেখ করতে ওয়াইল্ডকার্ড হিসাবে তারকাচিহ্ন অক্ষর ব্যবহার করুন, উদাহরণস্বরূপ:

<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:tools="http://schemas.android.com/tools"
    tools:keep="@layout/l_used*_c,@layout/l_used_a,@layout/l_used_b*"
    tools:discard="@layout/unused2" />

কোন রিসোর্সগুলিকে বাতিল করতে হবে তা উল্লেখ করা অতিরিক্ত মনে হতে পারে যখন আপনি সেগুলিকে মুছে ফেলতে পারেন, কিন্তু বিল্ড ভেরিয়েন্ট ব্যবহার করার সময় রিসোর্স বাতিল করা কার্যকর হতে পারে।

লক্ষ্য নির্দিষ্ট বিল্ড বৈকল্পিক

শুধুমাত্র কিছু বিল্ড ভেরিয়েন্টে রিসোর্স অপসারণ করতে, আপনার সমস্ত রিসোর্সকে সাধারণ প্রোজেক্ট ডিরেক্টরিতে রাখুন, তারপর ভেরিয়েন্টের রিসোর্স ডিরেক্টরিতে প্রতিটি বিল্ড ভেরিয়েন্টের জন্য একটি আলাদা my.package.build.variant.keep.xml ফাইল তৈরি করুন। Keep ফাইলে, প্রদত্ত সংস্থান কোডে ব্যবহার করা হলে (এবং সেই কারণে সঙ্কুচিত দ্বারা সরানো হয় না) প্রদর্শিত হলে অপসারণ করার জন্য ম্যানুয়ালি সংস্থানগুলি নির্দিষ্ট করুন, তবে আপনি জানেন যে এটি প্রদত্ত বিল্ড ভেরিয়েন্টের জন্য আসলে ব্যবহার করা হবে না।

অব্যবহৃত বিকল্প সম্পদ সরান

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

আপনার অ্যাপের প্রয়োজন নেই এমন বিকল্প রিসোর্স ফাইলগুলি সরাতে আপনার অ্যাপের মডিউল build.gradle ফাইলে Android Gradle resConfigs সম্পত্তি ব্যবহার করুন।

উদাহরণস্বরূপ, আপনি যদি এমন একটি লাইব্রেরি ব্যবহার করেন যাতে ভাষা সংস্থানগুলি অন্তর্ভুক্ত থাকে (যেমন Google Play পরিষেবাগুলি), তাহলে আপনার অ্যাপটি সেই লাইব্রেরির বার্তাগুলির জন্য সমস্ত অনুবাদিত ভাষা স্ট্রিংগুলিকে অন্তর্ভুক্ত করে তা আপনার বাকি অ্যাপ একই ভাষায় অনুবাদ করা হোক বা না হোক৷ আপনার অ্যাপ আনুষ্ঠানিকভাবে যে ভাষাগুলিকে সমর্থন করে শুধুমাত্র সেই ভাষাগুলি রাখতে, resConfigs বৈশিষ্ট্য ব্যবহার করে সেই ভাষাগুলি নির্দিষ্ট করুন৷ নির্দিষ্ট না করা ভাষার জন্য কোনো সংস্থান সরানো হয়।

নিম্নলিখিত স্নিপেটগুলি দেখায় যে কীভাবে আপনার ভাষা সংস্থানগুলিকে শুধুমাত্র ইংরেজি এবং ফরাসি ভাষায় সীমাবদ্ধ করতে হয়:

android {
    defaultConfig {
        ...
        resourceConfigurations.addAll(listOf("en", "fr"))
    }
}

বা

android {
    defaultConfig {
        ...
        resConfigs "en", "fr"
    }
}

আপনি যখন অ্যান্ড্রয়েড অ্যাপ বান্ডেল (AAB) ফর্ম্যাট ব্যবহার করে একটি অ্যাপ প্রকাশ করেন, তখন ডিফল্টরূপে ব্যবহারকারীর ডিভাইসে কনফিগার করা ভাষাগুলি ডাউনলোড করা হয় যখন ব্যবহারকারী অ্যাপটি ইনস্টল করেন। একইভাবে, শুধুমাত্র ডিভাইসের স্ক্রীনের ঘনত্বের সাথে মেলে এমন রিসোর্স এবং ডিভাইসের ABI-এর সাথে মেলে নেটিভ লাইব্রেরি ডাউনলোডে অন্তর্ভুক্ত করা হয়েছে। আরও তথ্যের জন্য, কনফিগারেশন APK এর প্রকারগুলি পুনরায় সক্ষম বা নিষ্ক্রিয় করুন দেখুন৷

APK-এর সাথে রিলিজ হওয়া লিগ্যাসি অ্যাপগুলির জন্য (আগস্ট 2021 সালের আগে তৈরি), আপনি একাধিক APK তৈরি করে আপনার APK-এ অন্তর্ভুক্ত করার জন্য স্ক্রীনের ঘনত্ব বা ABI রিসোর্স কাস্টমাইজ করতে পারেন যা বিভিন্ন ডিভাইস কনফিগারেশনকে লক্ষ্য করে।

সম্পদ একত্রিত করার সময় দ্বন্দ্ব এড়িয়ে চলুন

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

রিসোর্স মার্জিং তখনই ঘটে যখন দুই বা ততোধিক ফাইল একটি অভিন্ন রিসোর্স নাম, প্রকার এবং কোয়ালিফায়ার ভাগ করে। AGP ফাইলটি নির্বাচন করে যা এটি ডুপ্লিকেটগুলির মধ্যে সেরা পছন্দ হিসাবে চিহ্নিত করে (নীচে বর্ণিত একটি অগ্রাধিকারের ভিত্তিতে) এবং চূড়ান্ত বিল্ড আর্টিফ্যাক্টে বিতরণের জন্য শুধুমাত্র একটি সংস্থান AAPT-কে পাস করে।

AGP নিম্নলিখিত অবস্থানগুলিতে সদৃশ সংস্থানগুলি সন্ধান করে:

  • প্রধান সম্পদ, প্রধান উৎস সেটের সাথে যুক্ত, সাধারণত src/main/res/ এ অবস্থিত
  • বিল্ড টাইপ এবং বিল্ড ফ্লেভার থেকে বৈকল্পিক ওভারলে
  • লাইব্রেরি প্রকল্প নির্ভরতা

AGP নিম্নলিখিত ক্যাসকেডিং অগ্রাধিকার ক্রমে সদৃশ সংস্থানগুলিকে একত্রিত করে:

নির্ভরতা → প্রধান → বিল্ড ফ্লেভার → বিল্ড টাইপ

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

যদি একই উত্স সেটে অভিন্ন সংস্থানগুলি উপস্থিত হয়, Gradle সেগুলিকে একত্রিত করতে পারে না এবং একটি সংস্থান মার্জ ত্রুটি নির্গত করতে পারে৷ এটি ঘটতে পারে যদি আপনি আপনার মডিউল build.gradle ফাইলের sourceSet প্রপার্টিতে একাধিক সোর্স সেট সংজ্ঞায়িত করেন, উদাহরণস্বরূপ, যদি src/main/res/ এবং src/main/res2/ উভয়েই অভিন্ন সম্পদ থাকে।

রিসোর্স সঙ্কুচিত সমস্যা সমাধান করুন

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

:android:shrinkDebugResources
Removed unused resources: Resource data reduced from 2570KB to 1711KB: Removed 33%
:android:validateDebugSigning

Gradle এছাড়াও <module-name>/build/outputs/mapping/release/ (ProGuard-এর আউটপুট ফাইলগুলির মতো একই ফোল্ডার) এ resources.txt নামে একটি ডায়াগনস্টিক ফাইল তৈরি করে। ফাইলটিতে বিশদ অন্তর্ভুক্ত রয়েছে যেমন কোন সংস্থানগুলি অন্যান্য সংস্থানগুলির উল্লেখ করে এবং কোন সংস্থানগুলি ব্যবহার করা বা সরানো হয়৷

উদাহরণস্বরূপ, কেন @drawable/ic_plus_anim_016 এখনও আপনার অ্যাপে আছে তা খুঁজে বের করতে, resources.txt ফাইলটি খুলুন এবং সেই ফাইলের নামটি খুঁজুন। আপনি হয়তো খুঁজে পেতে পারেন যে এটি অন্য সংস্থান থেকে উল্লেখ করা হয়েছে:

16:25:48.005 [QUIET] [system.out] @drawable/add_schedule_fab_icon_anim : reachable=true
16:25:48.009 [QUIET] [system.out] @drawable/ic_plus_anim_016

আপনাকে এখন জানতে হবে কেন @drawable/add_schedule_fab_icon_anim পৌঁছানো যায়; এবং যদি আপনি উপরের দিকে অনুসন্ধান করেন, আপনি শিরোনামের নীচে তালিকাভুক্ত সংস্থানগুলি পাবেন রুট পৌঁছানোর যোগ্য সংস্থানগুলি হল: resources.txt এ।

এর মানে হল add_schedule_fab_icon_anim এর জন্য একটি কোড রেফারেন্স আছে, অর্থাৎ, এটির R.drawable IDটি পৌঁছানো যায় এমন কোডে পাওয়া গেছে।

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

10:32:50.590 [QUIET] [system.out] Marking drawable:ic_plus_anim_016:2130837506
    used because its format-string matches string pool constant ic_plus_anim_%1$d.

আপনি যদি এই স্ট্রিংগুলির একটি দেখতে পান এবং আপনি নিশ্চিত হন যে প্রদত্ত রিসোর্সটি গতিশীলভাবে লোড করার জন্য স্ট্রিংটি ব্যবহার করা হচ্ছে না, তাহলে রিসোর্সটি সরাতে বিল্ড সিস্টেমকে জানাতে আপনার Keep ফাইলে tools:discard অ্যাট্রিবিউট ব্যবহার করুন।