Android Gradle Plugin 3.6.0 (ফেব্রুয়ারি, ২০২০)

Android প্লাগ-ইনের এই ভার্সনের জন্য নিম্নলিখিত বিষয়গুলি প্রয়োজন:

ন্যূনতম ভার্সন ডিফল্ট ভার্সন নোট
Gradle ৫.৬.৪ ৫.৬.৪ আরও জানতে, Gradle আপডেট করা দেখুন।
SDK Build Tools ২৮.০.৩ ২৮.০.৩ SDK বিল্ড টুল ইনস্টল বা কনফিগার করুন।

নতুন বৈশিষ্ট্য

Android Gradle প্লাগ-ইনের এই ভার্সনে নিম্নলিখিত নতুন ফিচার অন্তর্ভুক্ত।

View Binding

আপনার কোডে ভিউ রেফারেন্স করার সময় ভিউ বাইন্ডিং কম্পাইল-টাইম নিরাপত্তা প্রদান করে। আপনি এখন findViewById()-এর জায়গায় অটোমেটিক তৈরি হওয়া বাইন্ডিং ক্লাস রেফারেন্স ব্যবহার করতে পারবেন। ভিউ বাইন্ডিং ব্যবহার করা শুরু করতে, প্রতিটি মডিউলের build.gradle ফাইলে নিম্নলিখিত কোড যোগ করুন:

      android {
          viewBinding.enabled = true
      }
      
      android {
          viewBinding.enabled = true
      }
      

আরও জানতে, View বাইন্ডিং ডকুমেন্টেশন পড়ুন।

Maven Publish প্লাগ-ইনের জন্য সহায়তা

Android Gradle প্লাগ-ইনে Maven প্রকাশ করার Gradle প্লাগ-ইন সংক্রান্ত সহায়তা অন্তর্ভুক্ত থাকে, যা আপনাকে Apache Maven রিপোজিটরিতে বিল্ড আর্টিফ্যাক্ট প্রকাশ করতে দেয়। Android Gradle প্লাগ-ইন আপনার অ্যাপ বা লাইব্রেরি মডিউলে প্রতিটি বিল্ড ভ্যারিয়েন্ট আর্টিফ্যাক্টের জন্য একটি কম্পোনেন্ট তৈরি করে যা আপনি Maven রিপোজিটরিতে প্রকাশনা কাস্টমাইজ করতে ব্যবহার করতে পারেন।

আরও জানতে, কীভাবে Maven Publish প্লাগ-ইন ব্যবহার করতে হয় সেই সম্পর্কিত পৃষ্ঠায় যান।

নতুন ডিফল্ট প্যাকেজিং টুল

আপনার অ্যাপের ডিবাগ ভার্সন তৈরি করার সময়, প্লাগ-ইনটি আপনার APK তৈরি করতে, zipflinger নামের একটি নতুন প্যাকেজিং টুল ব্যবহার করে। এই নতুন টুলটি বিল্ড স্পিড উন্নত করবে। নতুন প্যাকেজিং টুল আপনার প্রত্যাশা মতো কাজ না করলে, সমস্যার ব্যাপারে অভিযোগ জানান। আপনি gradle.properties ফাইলে এগুলি যোগ করে পুরনো প্যাকেজিং টুলে ফিরে যেতে পারবেন:

        android.useNewApkCreator=false
      

নেটিভ বিল্ড অ্যাট্রিবিউশন

আপনার প্রোজেক্টে প্রতিটি C/C++ ফাইল তৈরি ও লিঙ্ক করতে Clang-এর কত সময় লাগে তা এখন আপনি নির্ধারণ করতে পারবেন। Gradle একটি Chrome ট্রেস আউটপুট করতে পারে যেটিতে এইসব কম্পাইলার ইভেন্টের জন্য টাইমস্ট্যাম্প থাকে, যাতে আপনি আরও ভালোভাবে বুঝতে পারেন যে আপনার প্রোজেক্ট তৈরি করতে কত সময় লাগে। এই বিল্ডের অ্যাট্রিবিউশন ফাইল আউটপুট করতে, নিম্নলিখিত কাজগুলি করুন:

  1. Gradle বিল্ড চালানোর সময় ফ্ল্যাগ -Pandroid.enableProfileJson=true যোগ করুন। যেমন:

    gradlew assembleDebug -Pandroid.enableProfileJson=true

  2. Chrome ব্রাউজার খুলে সার্চ বারে chrome://tracing টাইপ করুন।

  3. লোড করুন বোতামে ক্লিক করুন এবং <var>project-root</var>/build/android-profile ফাইলটি খুঁজে পেতে নেভিগেট করুন। ফাইলটির নাম হল profile-<var>timestamp</var>.json.gz.

আপনি ভিউয়ারের উপরের দিকে নেটিভ বিল্ড অ্যাট্রিবিউশন ডেটা দেখতে পাবেন:

Chrome-এ নেটিভ বিল্ড অ্যাট্রিবিউশন ট্রেস

আচরণগত পরিবর্তন

এই প্লাগ-ইনের এই ভার্সন ব্যবহার করার সময়, আপনি নিম্নলিখিত আচরণগত পরিবর্তন দেখতে পেতে পারেন।

ডিফল্ট হিসেবে কম্প্রেস না করা নেটিভ লাইব্রেরি প্যাকেজ করা হয়

আপনি অ্যাপ তৈরি করলে, প্লাগ-ইন এখন ডিফল্ট হিসেবে extractNativeLibs-কে "false" হিসেবে সেট করে। অর্থাৎ, আপনার নেটিভ লাইব্রেরি পৃষ্ঠা-অ্যালাইন করা এবং প্যাকেজ করা কম্প্রেস করা হয়নি। এর ফলে আপলোড সাইজ বড় হলেও, আপনার ব্যবহারকারীরা নিচে উল্লেখ করা সুবিধাগুলি পাবেন:

  • ছোট অ্যাপ ইনস্টল সাইজ কারণ প্ল্যাটফর্ম ইনস্টল করা APK থেকে সরাসরি নেটিভ লাইব্রেরি অ্যাক্সেস করতে পারে, লাইব্রেরির কপি তৈরি না করেই এটি করা যায়।
  • ডাউনলোডের সাইজ ছোট হয় কারণ Play Store-এর কম্প্রেশন সাধারণত আপনার APK বা Android অ্যাপ বান্ডেলে আনকমপ্রেসড নেটিভ লাইব্রেরি যোগ করলে আরও ভালো হয়।

আপনি যদি চান যে Android Gradle প্লাগ-ইন পরিবর্তে কম্প্রেস করা নেটিভ লাইব্রেরি প্যাকেজ করুক, তাহলে আপনার অ্যাপের ম্যানিফেস্টে নিম্নলিখিতগুলি অন্তর্ভুক্ত করুন:

        <application
          android:extractNativeLibs="true"
          ... >
        </application>
        
      

মনে রাখবেন: extractNativeLibs ম্যানিফেস্ট অ্যাট্রিবিউটটি useLegacyPackaging DSL বিকল্প দিয়ে পরিবর্তন করা হয়েছে। আরও তথ্যের জন্য, রিলিজ নোট দেখুন কম্প্রেস করা নেটিভ লাইব্রেরি প্যাকেজ করতে DSL ব্যবহার করুন।

ডিফল্ট NDK ভার্সন

আপনি NDK-এর একাধিক ভার্সন ডাউনলোড করলে, Android Gradle প্লাগ-ইন এখন আপনার সোর্স কোড ফাইল কম্পাইল করার জন্য একটি ডিফল্ট ভার্সন বেছে নেয়। আগে, প্লাগ-ইনটি NDK-এর লেটেস্ট ডাউনলোড করা ভার্সন বেছে নিত। প্লাগ-ইন বেছে নেওয়া ডিফল্ট ওভাররাইড করতে, মডিউলের build.gradle ফাইলে android.ndkVersion প্রপার্টি ব্যবহার করুন।

সরলীকৃত R ক্লাস জেনারেশন

Android Gradle প্লাগ-ইন, কম্পাইল ক্লাসপাথকে আরও সহজ করে তোলে। এটি আপনার প্রোজেক্টের প্রতিটি লাইব্রেরি মডিউলের জন্য শুধুমাত্র একটি R ক্লাস তৈরি করে এবং অন্যান্য মডিউল ডিপেন্ডেন্সির সাথে সেইসব R ক্লাস শেয়ার করে। এই অপ্টিমাইজেশনের ফলে বিল্ড আরও দ্রুত হবে, তবে এর জন্য আপনাকে নিম্নলিখিত বিষয়গুলি মনে রাখতে হবে:

  • কারণ, কম্পাইলার আপস্ট্রিম মডিউল ডিপেন্ডেন্সির সাথে R ক্লাস শেয়ার করে, তাই আপনার প্রোজেক্টের প্রতিটি মডিউল যেন অনন্য প্যাকেজের নাম ব্যবহার করে তা নিশ্চিত করা গুরুত্বপূর্ণ।
  • লাইব্রেরির R ক্লাসের ভিজিবিলিটি অন্যান্য প্রোজেক্টের ডিপেন্ডেন্সির কাছে নির্ধারণ করা হয়, লাইব্রেরিকে ডিপেন্ডেন্সি হিসেবে অন্তর্ভুক্ত করার জন্য ব্যবহৃত কনফিগারেশনের মাধ্যমে। যেমন, লাইব্রেরি 'ক'-তে যদি লাইব্রেরি 'খ' 'api' নির্ভরতা হিসেবে অন্তর্ভুক্ত থাকে, তাহলে লাইব্রেরি 'ক' ও লাইব্রেরি 'ক'-এর উপর নির্ভরশীল অন্যান্য লাইব্রেরির লাইব্রেরি 'খ'-এর R ক্লাসে অ্যাক্সেস থাকে। তবে, অন্যান্য লাইব্রেরির কাছে হয়ত লাইব্রেরি 'খ'-এর R ক্লাসের অ্যাক্সেস নাও থাকতে পারে। লাইব্রেরি 'ক' যদি implementation নির্ভরতা কনফিগারেশন ব্যবহার করে। আরও জানতে, ডিপেন্ডেন্সি কনফিগারেশন সম্পর্কে পড়ুন।

ডিফল্ট কনফিগারেশনে নেই এমন রিসোর্স সরিয়ে দিন কনফিগারেশন

লাইব্রেরি মডিউলের ক্ষেত্রে, আপনি যদি এমন কোনও ভাষার রিসোর্স যোগ করেন যা আপনি রিসোর্সের ডিফল্ট সেটে যোগ করেননি (যেমন, আপনি যদি /values-es/strings.xml-এ স্ট্রিং রিসোর্স হিসেবে hello_world যোগ করেন, কিন্তু আপনি সেই রিসোর্সটি /values/strings.xml-এ ডিফাইন না করেন), তাহলে Android Gradle প্লাগ-ইন আর আপনার প্রোজেক্ট কম্পাইল করার সময় সেই রিসোর্স যোগ করে না। এই আচরণগত পরিবর্তনের ফলে Resource Not Found রানটাইম ব্যতিক্রমের সংখ্যা কমে যাবে এবং বিল্ড স্পিড উন্নত হবে।

D8 এখন অ্যানোটেশনের জন্য CLASS রিটেনশন নীতি মেনে চলে

আপনার অ্যাপ কম্পাইল করার সময়, D8 এখন অ্যানোটেশন CLASS রিটেনশন নীতি প্রয়োগ করলে তা মেনে চলে এবং সেইসব অ্যানোটেশন আর রানটাইমে উপলভ্য থাকে না। এছাড়াও, অ্যাপের টার্গেট SDK-কে API লেভেল ২৩ হিসেবে সেট করলে এই আচরণ দেখা যায়। এর ফলে, Android Gradle প্লাগ-ইন ও D8-এর পুরনো ভার্সন ব্যবহার করে আপনার অ্যাপ কম্পাইল করার সময় রানটাইম চলাকালীন এই অ্যানোটেশন অ্যাক্সেস করার অনুমতি দেওয়া হয়।

আচরণে অন্যান্য পরিবর্তন

  • aaptOptions.noCompress এখন আর সব প্ল্যাটফর্মে (APK ও বান্ডেল, দু'টির ক্ষেত্রেই) কেস-সংবেদনশীল নয় এবং বড় হাতের অক্ষর ব্যবহার করা পাথকে সম্মান করে।
  • ডেটা বাইন্ডিং এখন ডিফল্ট হিসেবে ইনক্রিমেন্টাল। আরও জানতে, issue #110061530 দেখুন।

  • Roboelectric ইউনিট টেস্ট সহ সমস্ত ইউনিট টেস্ট এখন সম্পূর্ণভাবে ক্যাশে করা যায়। আরও জানতে, issue #115873047 দেখুন।

সমস্যার সমাধান

Android Gradle প্লাগ-ইনের এই ভার্সনে নিম্নলিখিত সমস্যার সমাধান করা হয়েছে:

  • ডেটা বাইন্ডিং ব্যবহার করে এমন লাইব্রেরি মডিউলে Robolectric ইউনিট টেস্ট এখন কাজ করে। আরও জানতে, সমস্যা #126775542 দেখুন।
  • Gradle-এর প্যারালাল এক্সিকিউশন মোড চালু থাকাকালীন, আপনি এখন একাধিক মডিউল জুড়ে connectedAndroidTest টাস্ক রান করতে পারবেন।

পরিচিত সমস্যা

এই বিভাগে Android Gradle plugin 3.6.0-এ থাকা পরিচিত সমস্যাগুলি বর্ণনা করা হয়েছে।

Android Lint টাস্কের পারফর্ম্যান্স ধীর গতির হওয়া

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

সমস্যাটি IDEA-তে একটি বাগ হিসেবে রিপোর্ট করা হয়েছে এবং Android Gradle Plugin 4.0-এ এটি সমাধান করা হবে।

ম্যানিফেস্ট ক্লাস নেই {:#agp-missing-manifest}

আপনার অ্যাপের ম্যানিফেস্টে কাস্টম অনুমতি উল্লেখ করা থাকলে, Android Gradle প্লাগ-ইন সাধারণত এমন একটি Manifest.java ক্লাস তৈরি করে যা স্ট্রিং কনস্ট্যান্ট হিসেবে আপনার কাস্টম অনুমতি অন্তর্ভুক্ত করে। আপনার অ্যাপের সাথে এই ক্লাসটি প্লাগ-ইন প্যাকেজ করে, যাতে আপনি রানটাইমে আরও সহজে সেইসব অনুমতি রেফারেন্স করতে পারেন।

Android Gradle প্লাগ-ইন 3.6.0-এ ম্যানিফেস্ট ক্লাস তৈরি করা কাজ করছে না। আপনি যদি এই প্লাগ-ইনের ভার্সন দিয়ে অ্যাপ তৈরি করেন এবং এটি ম্যানিফেস্ট ক্লাসকে রেফার করে, তাহলে আপনি ClassNotFoundException ব্যতিক্রম দেখতে পেতে পারেন। এই সমস্যার সমাধান করতে, নিম্নলিখিতগুলির মধ্যে একটি করুন:

  • সম্পূর্ণ কোয়ালিফায়েড নাম দিয়ে আপনার কাস্টম অনুমতি রেফারেন্স করুন। যেমন, "com.example.myapp.permission.DEADLY_ACTIVITY".

  • নিচে দেখানো পদ্ধতিতে নিজের কনস্ট্যান্ট নির্ধারণ করুন:

                public final class CustomPermissions {
                  public static final class permission {
                    public static final String DEADLY_ACTIVITY="com.example.myapp.permission.DEADLY_ACTIVITY";
                  }
                }