অতিরিক্ত নিয়মের ধরণ

R8 আপনাকে Keep নিয়ম ছাড়াও আপনার অ্যাপের অপ্টিমাইজেশনকে প্রভাবিত করে এমন নিয়ম যোগ করতে দেয়। এই নিয়মগুলি একই proguard-rules.pro ফাইলে যোগ করুন যেখানে আপনি আপনার Keep নিয়মগুলি বজায় রাখেন।

নিয়মগুলি নিম্নলিখিত বিভাগগুলিতে পড়ে:

  • অনুমান
    • -assumevalues
    • -assumenosideeffects
  • অন্যান্য অপ্টিমাইজেশন
    • -convertchecknotnull
    • -maximumremovedandroidloglevel

অনুমান

এই নিয়মগুলি R8 কে বলে যে এটি রানটাইমে নির্দিষ্ট কোড আচরণ সম্পর্কে নির্দিষ্ট অনুমান করতে পারে।

-assumevalues

-assumevalues ​​নিয়ম R8 কে বলে যে একটি ক্ষেত্রের মান, অথবা একটি পদ্ধতির রিটার্ন মান, সর্বদা একটি নির্দিষ্ট ধ্রুবক বা রানটাইমে একটি নির্ধারিত পরিসরের মধ্যে পড়ে। -assumevalues ​​পতাকা মানের মতো জিনিসগুলির জন্য তৈরি করা হয়েছে যা বিল্ড টাইমে রানটাইমে নির্দিষ্ট মান হিসাবে পরিচিত।

R8 এর স্ট্যান্ডার্ড স্ট্যাটিক বিশ্লেষণ সদস্যদের রানটাইম মান নির্ধারণ করতে সক্ষম নাও হতে পারে। -assumevalues ​​এর মাধ্যমে, আপনি কোডটি অপ্টিমাইজ করার সময় R8 কে নির্দিষ্ট মান বা পরিসর ধরে নিতে বলেন। এটি R8 কে আক্রমণাত্মক অপ্টিমাইজেশন করতে দেয়।

-assumevalues ​​এর সিনট্যাক্স member_specification রাখার সিনট্যাক্সের অনুরূপ, তবে অতিরিক্তভাবে নিম্নরূপ একটি return clause অন্তর্ভুক্ত করে:

<member_specification> return <value> | <range>

<value> এবং <range> আর্গুমেন্টগুলি নিম্নলিখিত মান এবং প্রকারগুলিকে সমর্থন করে:

  • বিশেষ মান: true, false, null, @NonNull
  • আদিম মান: int
  • স্ট্যাটিক ফিল্ড রেফারেন্স (এনাম ফিল্ড সহ)

একটি পরিসর নির্ধারণ করতে, min..max অন্তর্ভুক্ত ফর্ম্যাট ব্যবহার করুন। উদাহরণস্বরূপ, নিম্নলিখিত স্নিপেটটি দেখায় যে CUSTOM_VAL চলকটি 26 থেকে 2147483647 পর্যন্ত গ্রহণ করে:

-assumevalues public class com.example.Foo {
    public static int CUSTOM_VAL return 26..2147483647;
}

আপনি নিম্নলিখিত পরিস্থিতিতে এই নিয়মটি ব্যবহার করতে পারেন:

  • লাইব্রেরির জন্য : অ্যাপগুলি অপ্টিমাইজ করার সময় পাবলিক লাইব্রেরি কোড থেকে সমস্ত স্থানীয় ডিবাগিং হুক সরানো হয়েছে তা নিশ্চিত করার জন্য।
  • অ্যাপের জন্য : রিলিজ অ্যাপ থেকে ডিবাগ কোডের মতো জিনিসগুলি সরাতে। নির্দিষ্ট সোর্স সেট বা ধ্রুবকের বিল্ড ভেরিয়েন্ট এবং ভেরিয়েন্ট ব্যবহার করা বাঞ্ছনীয়, তবে যদি ভেরিয়েন্ট সোর্স সেটগুলি আপনার ক্ষেত্রে কাজ না করে, অথবা যদি আপনার একটি শক্তিশালী গ্যারান্টির প্রয়োজন হয় যে কোড পাথগুলি সম্পূর্ণরূপে সরানো হয়েছে, তাহলে -assumevalues ​​ব্যবহার করুন।

নিম্নলিখিত উদাহরণে এমন একটি ক্লাস দেখানো হয়েছে যেখানে R8 একটি অ্যাপের অপ্টিমাইজড সংস্করণ থেকে ডিবাগ টুলগুলি সরিয়ে দেয়:

package com.example;

public class MyConfig {
    // This field is initialized to false but is overwritten by a resource
    // value or other mechanism in the final build process. R8's static analysis
    // might see the initial 'false' but the runtime value is known to be
    // 'true'.
    public static final boolean IS_OPTIMIZED_VERSION = false;
}

// In another class:
public void initFeatures() {
    if (MyConfig.IS_OPTIMIZED_VERSION) {
        System.out.println("Starting optimized features...");
        android.util.Log.d(TAG, "Starting optimized features...");
        initOptimizedService();
    } else {
        android.util.Log.d(TAG, "Starting debug/logging features...");
        initDebugTools();
    }
}

নিম্নলিখিত নিয়মটি দেখায় কিভাবে R8 কে বলা যায় যে IS_OPTIMIZED_VERSION ভেরিয়েবলটি সর্বদা true তে সেট করা হবে বলে আশা করা হচ্ছে।

-assumevalues class com.example.MyConfig {
    public static final boolean IS_OPTIMIZED_VERSION return true;
}

-assumenosideeffects

-assumenosideeffects নিয়ম R8 কে বলে যে এটি ধরে নিতে পারে যে নির্দিষ্ট সদস্যদের কোনও পার্শ্ব প্রতিক্রিয়া নেই। R8 এমন পদ্ধতিতে কলগুলি সম্পূর্ণরূপে সরিয়ে দিতে পারে যার কোনও রিটার্ন মান নেই বা যা একটি নির্দিষ্ট মান প্রদান করে।

-assumenosideeffects এর সিনট্যাক্স member_specification রাখার সিনট্যাক্সের অনুরূপ।

নিম্নলিখিত নমুনাটি দেখায় যে কীভাবে R8 কে বলা যায় যে DebugLogger ক্লাসের মধ্যে log নামক সমস্ত public static পদ্ধতির কোনও পার্শ্বপ্রতিক্রিয়া থাকা উচিত নয়, যা এটিকে এই পদ্ধতিগুলিতে কলগুলি সরাতে দেয়।

-assumenosideeffects class com.example.DebugLogger {
    public static void log(...);
}

অন্যান্য অপ্টিমাইজেশন

এগুলি আরও কিছু উন্নত অপ্টিমাইজেশন যা ডিফল্টভাবে সক্রিয় থাকে না। এগুলি সক্ষম করার সময় আপনি R8 কে ডিফল্ট অপ্টিমাইজেশনের পাশাপাশি নির্দেশিত কোড অপ্টিমাইজ করার অনুমতি দেন।

-convertchecknotnull

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

যদি একটি -convertchecknotnull নিয়ম একটি প্রদত্ত পদ্ধতির সাথে মেলে, তাহলে সেই পদ্ধতিতে প্রতিটি কল প্রথম আর্গুমেন্টে getClass() এর কল দ্বারা প্রতিস্থাপিত হয়। getClass() এর কলগুলি একটি প্রতিস্থাপন null চেক হিসাবে কাজ করে এবং R8 কে মূল null চেকের যেকোনো অতিরিক্ত আর্গুমেন্ট, যেমন ব্যয়বহুল স্ট্রিং বরাদ্দকরণ, অপসারণ করতে দেয়।

-convertchecknotnull এর সিনট্যাক্স নিম্নরূপ:

-convertchecknotnull <class_specification> {
   <member_specification>;
}

উদাহরণস্বরূপ, যদি আপনার checkNotNull পদ্ধতিটি নিম্নরূপ সহ ক্লাস Preconditions থাকে:

class Preconditions {
    fun <T> checkNotNull(value: T?): T {
        if (value == null) {
            throw NullPointerException()
        } else {
            return value
        }
    }
}

নিম্নলিখিত নিয়মটি ব্যবহার করুন:

-convertchecknotnull class com.example.package.Preconditions {
  void checkNotNull(java.lang.Object);
}

এই নিয়মটি প্রথম আর্গুমেন্টে checkNotNull() এর সকল কলকে getClass এর কলে রূপান্তর করে। এই উদাহরণে, checkNotNull(bar) এর একটি কল bar.getClass() দ্বারা প্রতিস্থাপিত হয়েছে। যদি bar null হয়, তাহলে bar.getClass() একটি NullPointerException নিক্ষেপ করবে, যা একই রকম null-checking প্রভাব অর্জন করবে কিন্তু আরও দক্ষতার সাথে।

-maximumremovedandroidloglevel

এই নিয়মের ধরণটি একটি নির্দিষ্ট লগ স্তরে বা তার নিচে অ্যান্ড্রয়েড লগিং স্টেটমেন্ট (যেমন Log.w (...) এবং Log.isLoggable(...) ) সরিয়ে দেয়।

maximumremovedandroidloglevel এর সিনট্যাক্স নিম্নরূপ:

-maximumremovedandroidloglevel <log_level> [<class_specification>]

যদি আপনি ঐচ্ছিক class_specification প্রদান না করেন, তাহলে R8 সম্পূর্ণ অ্যাপে লগ অপসারণ প্রয়োগ করবে।

লগ স্তরগুলি নিম্নরূপ:

লগ লেবেল

লগ লেভেল

ক্রিয়াপদ

ডিবাগ

তথ্য

সতর্কতামূলক

ত্রুটি

দাবি করুন

উদাহরণস্বরূপ, যদি আপনার নিম্নলিখিত কোড থাকে:

class Foo {
  private static final String TAG = "Foo";
  void logSomething() {
    if (Log.isLoggable(TAG, WARNING)) {
      Log.e(TAG, "Won't be logged");
    }
    Log.w(TAG, "Won't be logged");
    Log.e(TAG, "Will be logged");
  }
}

নিম্নলিখিত নিয়ম অনুসারে:

# A level of 5 corresponds to a log level of WARNING.
-maximumremovedandroidloglevel 5 class Foo { void logSomething(); }

অপ্টিমাইজ করা কোডটি নিম্নরূপ:

class Foo {
  private static final String TAG = "Foo";
  void logSomething() {
    Log.e(TAG, "Will be logged");
  }
}

যদি আপনি একই পদ্ধতির জন্য একাধিক সর্বোচ্চ লগ স্তর প্রদান করেন, তাহলে R8 সর্বনিম্ন স্তর ব্যবহার করে। উদাহরণস্বরূপ, নিম্নলিখিত নিয়মগুলি দেওয়া হয়েছে:

-maximumremovedandroidloglevel 7 class ** { void foo(); }
-maximumremovedandroidloglevel 4 class ** { void foo(); }

তাহলে foo() এর জন্য সর্বাধিক সরানো লগ স্তর হল 4।