চাহিদা ডেলিভারি কনফিগার করুন

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

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

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

আপনি যদি সময়ের সাথে সাথে অ্যাপের বৈশিষ্ট্যগুলিকে ধীরে ধীরে মডুলারাইজ করতে চান, উন্নত ডেলিভারি বিকল্পগুলিকে সক্ষম না করে, যেমন অন ডিমান্ড ডেলিভারি, পরিবর্তে ইনস্টল-টাইম ডেলিভারি কনফিগার করুন

এই পৃষ্ঠাটি আপনাকে আপনার অ্যাপ প্রকল্পে একটি বৈশিষ্ট্য মডিউল যোগ করতে এবং চাহিদা অনুযায়ী বিতরণের জন্য কনফিগার করতে সহায়তা করে। আপনি শুরু করার আগে, নিশ্চিত হয়ে নিন যে আপনি Android Studio 3.5 বা উচ্চতর এবং Android Gradle Plugin 3.5.0 বা উচ্চতর ব্যবহার করছেন৷

চাহিদা অনুযায়ী ডেলিভারির জন্য একটি নতুন মডিউল কনফিগার করুন

একটি নতুন বৈশিষ্ট্য মডিউল তৈরি করার সবচেয়ে সহজ উপায় হল Android স্টুডিও 3.5 বা উচ্চতর ব্যবহার করে৷ কারণ বৈশিষ্ট্য মডিউলগুলির বেস অ্যাপ মডিউলের উপর অন্তর্নিহিত নির্ভরতা রয়েছে, আপনি সেগুলিকে শুধুমাত্র বিদ্যমান অ্যাপ প্রকল্পগুলিতে যোগ করতে পারেন।

অ্যান্ড্রয়েড স্টুডিও ব্যবহার করে আপনার অ্যাপ প্রজেক্টে একটি ফিচার মডিউল যোগ করতে, নিচের মত এগিয়ে যান:

  1. আপনি যদি ইতিমধ্যে এটি না করে থাকেন তবে IDE-তে আপনার অ্যাপ প্রকল্পটি খুলুন।
  2. মেনু বার থেকে ফাইল > নতুন > নতুন মডিউল নির্বাচন করুন।
  3. নতুন মডিউল তৈরি করুন ডায়ালগে, ডায়নামিক বৈশিষ্ট্য মডিউল নির্বাচন করুন এবং পরবর্তী ক্লিক করুন।
  4. আপনার নতুন মডিউল কনফিগার করুন বিভাগে, নিম্নলিখিতগুলি সম্পূর্ণ করুন:
    1. ড্রপডাউন মেনু থেকে আপনার অ্যাপ প্রকল্পের জন্য বেস অ্যাপ্লিকেশন মডিউল নির্বাচন করুন।
    2. একটি মডিউল নাম উল্লেখ করুন। IDE এই নামটি ব্যবহার করে আপনার Gradle সেটিংস ফাইলে একটি Gradle সাবপ্রজেক্ট হিসেবে মডিউলটিকে চিহ্নিত করতে। আপনি যখন আপনার অ্যাপ বান্ডেল তৈরি করেন, তখন বৈশিষ্ট্য মডিউলের ম্যানিফেস্টে <manifest split> অ্যাট্রিবিউট ইনজেক্ট করতে গ্র্যাডল সাবপ্রজেক্ট নামের শেষ উপাদানটি ব্যবহার করে।
    3. মডিউলটির প্যাকেজের নাম উল্লেখ করুন। ডিফল্টরূপে, অ্যান্ড্রয়েড স্টুডিও একটি প্যাকেজের নাম প্রস্তাব করে যা বেস মডিউলের রুট প্যাকেজ নাম এবং আগের ধাপে আপনার নির্দিষ্ট করা মডিউল নামকে একত্রিত করে।
    4. আপনি মডিউলটি সমর্থন করতে চান এমন ন্যূনতম API স্তরটি নির্বাচন করুন৷ এই মানটি বেস মডিউলের সাথে মিলিত হওয়া উচিত।
  5. পরবর্তী ক্লিক করুন.
  6. মডিউল ডাউনলোড বিকল্প বিভাগে, নিম্নলিখিতটি সম্পূর্ণ করুন:

    1. 50 অক্ষর পর্যন্ত ব্যবহার করে মডিউল শিরোনাম নির্দিষ্ট করুন। প্ল্যাটফর্মটি ব্যবহারকারীদের কাছে মডিউলটি সনাক্ত করতে এই শিরোনামটি ব্যবহার করে যখন, উদাহরণস্বরূপ, ব্যবহারকারী মডিউলটি ডাউনলোড করতে চান কিনা তা নিশ্চিত করে৷ এই কারণে, আপনার অ্যাপের বেস মডিউলে মডিউল শিরোনামটিকে একটি স্ট্রিং রিসোর্স হিসেবে অন্তর্ভুক্ত করতে হবে, যা আপনি অনুবাদ করতে পারেন। অ্যান্ড্রয়েড স্টুডিও ব্যবহার করে মডিউল তৈরি করার সময়, IDE আপনার জন্য বেস মডিউলে স্ট্রিং রিসোর্স যোগ করে এবং ফিচার মডিউলের ম্যানিফেস্টে নিম্নলিখিত এন্ট্রি ইনজেক্ট করে:

      <dist:module
          ...
          dist:title="@string/feature_title">
      </dist:module>
      
    2. ইনস্টল-টাইম অন্তর্ভুক্তির অধীনে ড্রপডাউন মেনুতে, ইনস্টল-টাইমে মডিউল অন্তর্ভুক্ত করবেন না নির্বাচন করুন। অ্যান্ড্রয়েড স্টুডিও আপনার পছন্দকে প্রতিফলিত করতে মডিউলের ম্যানিফেস্টে নিম্নলিখিতগুলি ইনজেক্ট করে:

      <dist:module ... >
        <dist:delivery>
            <dist:on-demand/>
        </dist:delivery>
      </dist:module>
      
    3. আপনি যদি চান যে এই মডিউলটি Android 4.4 (API লেভেল 20) এবং তার নিচের এবং মাল্টি-APK-তে অন্তর্ভুক্ত ডিভাইসগুলিতে উপলব্ধ হতে চান তাহলে Fusing- এর পাশের বাক্সটি চেক করুন৷ এর মানে হল আপনি এই মডিউলটির জন্য চাহিদার আচরণ সক্ষম করতে পারেন এবং বিভক্ত APK ডাউনলোড এবং ইনস্টল করা সমর্থন করে না এমন ডিভাইসগুলি থেকে এটি বাদ দিতে ফিউজিং অক্ষম করতে পারেন৷ অ্যান্ড্রয়েড স্টুডিও আপনার পছন্দকে প্রতিফলিত করতে মডিউলের ম্যানিফেস্টে নিম্নলিখিতগুলি ইনজেক্ট করে:

      <dist:module ...>
          <dist:fusing dist:include="true | false" />
      </dist:module>
      
  7. শেষ ক্লিক করুন.

অ্যান্ড্রয়েড স্টুডিও আপনার মডিউল তৈরি করা শেষ করার পরে, প্রকল্প ফলক থেকে নিজেই এর বিষয়বস্তু পরীক্ষা করুন (মেনু বার থেকে দেখুন > টুল উইন্ডোজ > প্রকল্প নির্বাচন করুন)। ডিফল্ট কোড, সংস্থান এবং সংস্থাটি মানক অ্যাপ মডিউলের মতো হওয়া উচিত।

এর পরে, আপনাকে প্লে ফিচার ডেলিভারি লাইব্রেরি ব্যবহার করে অন ডিমান্ড ইনস্টল কার্যকারিতা বাস্তবায়ন করতে হবে।

আপনার প্রজেক্টে প্লে ফিচার ডেলিভারি লাইব্রেরি অন্তর্ভুক্ত করুন

আপনি শুরু করার আগে, আপনাকে প্রথমে আপনার প্রোজেক্টে প্লে ফিচার ডেলিভারি লাইব্রেরি যোগ করতে হবে।

একটি চাহিদা মডিউল অনুরোধ করুন

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

উদাহরণ স্বরূপ, ডিভাইসের ক্যামেরা ব্যবহার করে ছবি বার্তা ক্যাপচার এবং পাঠানোর জন্য একটি অন ডিমান্ড মডিউল আছে এমন একটি অ্যাপ বিবেচনা করুন এবং এই অন ডিমান্ড মডিউলটি তার ম্যানিফেস্টে split="pictureMessages" উল্লেখ করে। নিচের নমুনা SplitInstallManager ব্যবহার করে pictureMessages মডিউলের জন্য অনুরোধ করে (কিছু প্রচারমূলক ফিল্টারের জন্য একটি অতিরিক্ত মডিউল সহ):

কোটলিন

// Creates an instance of SplitInstallManager.
val splitInstallManager = SplitInstallManagerFactory.create(context)

// Creates a request to install a module.
val request =
    SplitInstallRequest
        .newBuilder()
        // You can download multiple on demand modules per
        // request by invoking the following method for each
        // module you want to install.
        .addModule("pictureMessages")
        .addModule("promotionalFilters")
        .build()

splitInstallManager
    // Submits the request to install the module through the
    // asynchronous startInstall() task. Your app needs to be
    // in the foreground to submit the request.
    .startInstall(request)
    // You should also be able to gracefully handle
    // request state changes and errors. To learn more, go to
    // the section about how to Monitor the request state.
    .addOnSuccessListener { sessionId -> ... }
    .addOnFailureListener { exception ->  ... }

জাভা

// Creates an instance of SplitInstallManager.
SplitInstallManager splitInstallManager =
    SplitInstallManagerFactory.create(context);

// Creates a request to install a module.
SplitInstallRequest request =
    SplitInstallRequest
        .newBuilder()
        // You can download multiple on demand modules per
        // request by invoking the following method for each
        // module you want to install.
        .addModule("pictureMessages")
        .addModule("promotionalFilters")
        .build();

splitInstallManager
    // Submits the request to install the module through the
    // asynchronous startInstall() task. Your app needs to be
    // in the foreground to submit the request.
    .startInstall(request)
    // You should also be able to gracefully handle
    // request state changes and errors. To learn more, go to
    // the section about how to Monitor the request state.
    .addOnSuccessListener(sessionId -> { ... })
    .addOnFailureListener(exception -> { ... });

যখন আপনার অ্যাপ অন ডিমান্ড মডিউলের অনুরোধ করে, তখন প্লে ফিচার ডেলিভারি লাইব্রেরি একটি "ফায়ার-এন্ড-ফোরগেট" কৌশল নিযুক্ত করে। অর্থাৎ, এটি মডিউলটি প্ল্যাটফর্মে ডাউনলোড করার অনুরোধ পাঠায়, কিন্তু ইনস্টলেশন সফল হয়েছে কিনা তা নিরীক্ষণ করে না। ইনস্টলেশনের পরে ব্যবহারকারীর যাত্রাকে এগিয়ে নিয়ে যেতে বা ত্রুটিগুলি সুন্দরভাবে পরিচালনা করতে, আপনি অনুরোধের অবস্থা পর্যবেক্ষণ করছেন তা নিশ্চিত করুন।

দ্রষ্টব্য: ডিভাইসে ইতিমধ্যে ইনস্টল করা একটি বৈশিষ্ট্য মডিউল অনুরোধ করা ঠিক আছে৷ API তাৎক্ষণিকভাবে অনুরোধটিকে সম্পূর্ণ হিসাবে বিবেচনা করে যদি এটি সনাক্ত করে যে মডিউলটি ইতিমধ্যে ইনস্টল করা আছে। উপরন্তু, একটি মডিউল ইনস্টল করার পরে, Google Play এটি স্বয়ংক্রিয়ভাবে আপডেট রাখে। অর্থাৎ, আপনি যখন আপনার অ্যাপ বান্ডেলের একটি নতুন সংস্করণ আপলোড করেন, তখন প্ল্যাটফর্মটি আপনার অ্যাপের অন্তর্গত সমস্ত ইনস্টল করা APK আপডেট করে। আরও তথ্যের জন্য, অ্যাপ আপডেটগুলি পরিচালনা করুন পড়ুন।

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

চাহিদা মডিউল ইনস্টলেশন বিলম্বিত

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

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

কোটলিন

// Requests an on demand module to be downloaded when the app enters
// the background. You can specify more than one module at a time.
splitInstallManager.deferredInstall(listOf("promotionalFilters"))

জাভা

// Requests an on demand module to be downloaded when the app enters
// the background. You can specify more than one module at a time.
splitInstallManager.deferredInstall(Arrays.asList("promotionalFilters"));

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

অনুরোধ রাষ্ট্র নিরীক্ষণ

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

কোটলিন

// Initializes a variable to later track the session ID for a given request.
var mySessionId = 0

// Creates a listener for request status updates.
val listener = SplitInstallStateUpdatedListener { state ->
    if (state.sessionId() == mySessionId) {
      // Read the status of the request to handle the state update.
    }
}

// Registers the listener.
splitInstallManager.registerListener(listener)

...

splitInstallManager
    .startInstall(request)
    // When the platform accepts your request to download
    // an on demand module, it binds it to the following session ID.
    // You use this ID to track further status updates for the request.
    .addOnSuccessListener { sessionId -> mySessionId = sessionId }
    // You should also add the following listener to handle any errors
    // processing the request.
    .addOnFailureListener { exception ->
        // Handle request errors.
    }

// When your app no longer requires further updates, unregister the listener.
splitInstallManager.unregisterListener(listener)

জাভা

// Initializes a variable to later track the session ID for a given request.
int mySessionId = 0;

// Creates a listener for request status updates.
SplitInstallStateUpdatedListener listener = state -> {
    if (state.sessionId() == mySessionId) {
      // Read the status of the request to handle the state update.
    }
};

// Registers the listener.
splitInstallManager.registerListener(listener);

...

splitInstallManager
    .startInstall(request)
    // When the platform accepts your request to download
    // an on demand module, it binds it to the following session ID.
    // You use this ID to track further status updates for the request.
    .addOnSuccessListener(sessionId -> { mySessionId = sessionId; })
    // You should also add the following listener to handle any errors
    // processing the request.
    .addOnFailureListener(exception -> {
        // Handle request errors.
    });

// When your app no longer requires further updates, unregister the listener.
splitInstallManager.unregisterListener(listener);

অনুরোধের ত্রুটিগুলি পরিচালনা করুন

মনে রাখবেন যে চাহিদা অনুযায়ী বৈশিষ্ট্য মডিউলগুলির ইনস্টলেশন কখনও কখনও ব্যর্থ হতে পারে, ঠিক যেমন অ্যাপ ইনস্টলেশন সবসময় সফল হয় না। কম ডিভাইস স্টোরেজ, নেটওয়ার্ক কানেক্টিভিটি না থাকা বা ব্যবহারকারীর গুগল প্লে স্টোরে সাইন ইন না করার মতো সমস্যার কারণে ইনস্টল করতে ব্যর্থ হতে পারে। ব্যবহারকারীর দৃষ্টিকোণ থেকে কীভাবে এই পরিস্থিতিগুলিকে সুন্দরভাবে পরিচালনা করা যায় সে সম্পর্কে পরামর্শের জন্য, চাহিদার সরবরাহের জন্য আমাদের UX নির্দেশিকা দেখুন৷

কোড অনুসারে, আপনাকে addOnFailureListener() ব্যবহার করে একটি মডিউল ডাউনলোড বা ইনস্টল করার ব্যর্থতাগুলি পরিচালনা করা উচিত, যেমনটি নীচে দেখানো হয়েছে:

কোটলিন

splitInstallManager
    .startInstall(request)
    .addOnFailureListener { exception ->
        when ((exception as SplitInstallException).errorCode) {
            SplitInstallErrorCode.NETWORK_ERROR -> {
                // Display a message that requests the user to establish a
                // network connection.
            }
            SplitInstallErrorCode.ACTIVE_SESSIONS_LIMIT_EXCEEDED -> checkForActiveDownloads()
            ...
        }
    }

fun checkForActiveDownloads() {
    splitInstallManager
        // Returns a SplitInstallSessionState object for each active session as a List.
        .sessionStates
        .addOnCompleteListener { task ->
            if (task.isSuccessful) {
                // Check for active sessions.
                for (state in task.result) {
                    if (state.status() == SplitInstallSessionStatus.DOWNLOADING) {
                        // Cancel the request, or request a deferred installation.
                    }
                }
            }
        }
}

জাভা

splitInstallManager
    .startInstall(request)
    .addOnFailureListener(exception -> {
        switch (((SplitInstallException) exception).getErrorCode()) {
            case SplitInstallErrorCode.NETWORK_ERROR:
                // Display a message that requests the user to establish a
                // network connection.
                break;
            case SplitInstallErrorCode.ACTIVE_SESSIONS_LIMIT_EXCEEDED:
                checkForActiveDownloads();
            ...
    });

void checkForActiveDownloads() {
    splitInstallManager
        // Returns a SplitInstallSessionState object for each active session as a List.
        .getSessionStates()
        .addOnCompleteListener( task -> {
            if (task.isSuccessful()) {
                // Check for active sessions.
                for (SplitInstallSessionState state : task.getResult()) {
                    if (state.status() == SplitInstallSessionStatus.DOWNLOADING) {
                        // Cancel the request, or request a deferred installation.
                    }
                }
            }
        });
}

নীচের সারণীটি বর্ণনা করে যে ত্রুটিটি আপনার অ্যাপকে পরিচালনা করতে হতে পারে:

ভুল সংকেত বর্ণনা ব্যবস্থা নেওয়ার পরামর্শ দিয়েছেন
ACTIVE_SESSIONS_LIMIT_EXCEEDED অনুরোধটি প্রত্যাখ্যান করা হয়েছে কারণ অন্তত একটি বিদ্যমান অনুরোধ বর্তমানে ডাউনলোড হচ্ছে৷ উপরের নমুনায় দেখানো হয়েছে এমন কোনো অনুরোধ এখনও ডাউনলোড হচ্ছে কিনা তা পরীক্ষা করুন।
MODULE_UNAVAILABLE Google Play অ্যাপ, ডিভাইস এবং ব্যবহারকারীর Google Play অ্যাকাউন্টের বর্তমান ইনস্টল করা সংস্করণের উপর ভিত্তি করে অনুরোধ করা মডিউলটি খুঁজে পেতে অক্ষম৷ যদি ব্যবহারকারীর মডিউলে অ্যাক্সেস না থাকে তবে তাদের অবহিত করুন।
অনুরোধ অগ্রহণযোগ্য Google Play অনুরোধটি পেয়েছে, কিন্তু অনুরোধটি বৈধ নয়৷ যাচাই করুন যে অনুরোধে অন্তর্ভুক্ত তথ্য সম্পূর্ণ এবং সঠিক।
SESSION_NOT_FOUND প্রদত্ত সেশন আইডির জন্য একটি সেশন পাওয়া যায়নি। আপনি যদি সেশন আইডি দ্বারা অনুরোধের অবস্থা নিরীক্ষণ করার চেষ্টা করেন তবে নিশ্চিত করুন যে সেশন আইডিটি সঠিক।
API_NOT_AVAILABLE প্লে ফিচার ডেলিভারি লাইব্রেরি বর্তমান ডিভাইসে সমর্থিত নয়। অর্থাৎ ডিভাইসটি চাহিদা অনুযায়ী ফিচার ডাউনলোড ও ইনস্টল করতে সক্ষম নয়। Android 4.4 (API লেভেল 20) বা তার কম চলমান ডিভাইসগুলির জন্য, আপনি dist:fusing ম্যানিফেস্ট প্রপার্টি ব্যবহার করে ইনস্টল করার সময় বৈশিষ্ট্য মডিউলগুলি অন্তর্ভুক্ত করুন৷ আরও জানতে, বৈশিষ্ট্য মডিউল ম্যানিফেস্ট সম্পর্কে পড়ুন।
নেটওয়ার্ক ত্রুটি একটি নেটওয়ার্ক ত্রুটির কারণে অনুরোধটি ব্যর্থ হয়েছে৷ ব্যবহারকারীকে একটি নেটওয়ার্ক সংযোগ স্থাপন করতে বা একটি ভিন্ন নেটওয়ার্কে পরিবর্তন করতে অনুরোধ করুন৷
ACCESS_DENIED অ্যাপটি অপর্যাপ্ত অনুমতির কারণে অনুরোধটি নিবন্ধন করতে অক্ষম৷ অ্যাপটি ব্যাকগ্রাউন্ডে থাকলে এটি সাধারণত ঘটে। অ্যাপটি ফোরগ্রাউন্ডে ফিরে এলে অনুরোধ করার চেষ্টা করুন।
INCOMPATIBLE_WITH_EXISTING_SESSION অনুরোধটিতে এক বা একাধিক মডিউল রয়েছে যা ইতিমধ্যেই অনুরোধ করা হয়েছে কিন্তু এখনও ইনস্টল করা হয়নি। হয় একটি নতুন অনুরোধ তৈরি করুন যাতে আপনার অ্যাপ ইতিমধ্যেই অনুরোধ করা মডিউলগুলিকে অন্তর্ভুক্ত করে না, অথবা অনুরোধটি পুনরায় চেষ্টা করার আগে ইনস্টল করা শেষ করার জন্য বর্তমানে অনুরোধ করা সমস্ত মডিউলের জন্য অপেক্ষা করুন৷

মনে রাখবেন, ইতিমধ্যে ইন্সটল করা মডিউলের অনুরোধ করলে কোনো ত্রুটির সমাধান হয় না।

SERVICE_DIED অনুরোধ পরিচালনার জন্য দায়ী পরিষেবা মারা গেছে। অনুরোধ পুনরায় চেষ্টা করুন.

আপনার SplitInstallStateUpdatedListener এই ত্রুটি কোড, স্ট্যাটাস FAILED এবং সেশন আইডি -1 সহ একটি SplitInstallSessionState পেয়েছে।

অপর্যাপ্ত মজুত বৈশিষ্ট্য মডিউল ইনস্টল করার জন্য ডিভাইসে পর্যাপ্ত বিনামূল্যের সঞ্চয়স্থান নেই৷ ব্যবহারকারীকে জানান যে এই বৈশিষ্ট্যটি ইনস্টল করার জন্য তাদের কাছে পর্যাপ্ত স্টোরেজ নেই।
SPLITCOMPAT_VERIFICATION_ERROR, SPLITCOMPAT_EMULATION_ERROR, SPLITCOMPAT_COPY_ERROR SplitCompat বৈশিষ্ট্য মডিউল লোড করতে পারেনি. পরবর্তী অ্যাপ রিস্টার্ট হওয়ার পরে এই ত্রুটিগুলি স্বয়ংক্রিয়ভাবে সমাধান করা উচিত।
PLAY_STORE_NOT_FOUND প্লে স্টোর অ্যাপটি ডিভাইসে ইনস্টল করা নেই। ব্যবহারকারীকে জানিয়ে দিন যে এই বৈশিষ্ট্যটি ডাউনলোড করার জন্য প্লে স্টোর অ্যাপের প্রয়োজন।
APP_NOT_OWNED অ্যাপটি Google Play দ্বারা ইনস্টল করা হয়নি এবং বৈশিষ্ট্যটি ডাউনলোড করা যাবে না। এই ত্রুটি শুধুমাত্র বিলম্বিত ইনস্টলের জন্য ঘটতে পারে। আপনি যদি ব্যবহারকারীকে Google Play-তে অ্যাপটি অর্জন করতে চান, startInstall() ব্যবহার করুন যা প্রয়োজনীয় ব্যবহারকারীর নিশ্চয়তা পেতে পারে।
অভ্যন্তরীণ ত্রুটি প্লে স্টোরের মধ্যে একটি অভ্যন্তরীণ ত্রুটি ঘটেছে৷ অনুরোধ পুনরায় চেষ্টা করুন.

যদি একজন ব্যবহারকারী একটি অন ডিমান্ড মডিউল ডাউনলোড করার অনুরোধ করে এবং একটি ত্রুটি ঘটে, তাহলে একটি ডায়ালগ প্রদর্শন করার কথা বিবেচনা করুন যা ব্যবহারকারীর জন্য দুটি বিকল্প প্রদান করে: আবার চেষ্টা করুন (যা আবার অনুরোধের চেষ্টা করে) এবং বাতিল করুন (যা অনুরোধটি পরিত্যাগ করে)। অতিরিক্ত সহায়তার জন্য, আপনাকে সহায়তা লিঙ্কও প্রদান করা উচিত যা ব্যবহারকারীদের Google Play সহায়তা কেন্দ্রে নির্দেশ করে।

রাষ্ট্রীয় আপডেটগুলি পরিচালনা করুন

আপনি একজন শ্রোতা নিবন্ধন করার পরে এবং আপনার অনুরোধের জন্য সেশন আইডি রেকর্ড করার পরে, রাজ্যের পরিবর্তনগুলি পরিচালনা করতে StateUpdatedListener.onStateUpdate() ব্যবহার করুন, যেমন নীচে দেখানো হয়েছে।

কোটলিন

override fun onStateUpdate(state : SplitInstallSessionState) {
    if (state.status() == SplitInstallSessionStatus.FAILED
        && state.errorCode() == SplitInstallErrorCode.SERVICE_DIED) {
       // Retry the request.
       return
    }
    if (state.sessionId() == mySessionId) {
        when (state.status()) {
            SplitInstallSessionStatus.DOWNLOADING -> {
              val totalBytes = state.totalBytesToDownload()
              val progress = state.bytesDownloaded()
              // Update progress bar.
            }
            SplitInstallSessionStatus.INSTALLED -> {

              // After a module is installed, you can start accessing its content or
              // fire an intent to start an activity in the installed module.
              // For other use cases, see access code and resources from installed modules.

              // If the request is an on demand module for an Android Instant App
              // running on Android 8.0 (API level 26) or higher, you need to
              // update the app context using the SplitInstallHelper API.
            }
        }
    }
}

জাভা

@Override
public void onStateUpdate(SplitInstallSessionState state) {
    if (state.status() == SplitInstallSessionStatus.FAILED
        && state.errorCode() == SplitInstallErrorCode.SERVICE_DIES) {
       // Retry the request.
       return;
    }
    if (state.sessionId() == mySessionId) {
        switch (state.status()) {
            case SplitInstallSessionStatus.DOWNLOADING:
              int totalBytes = state.totalBytesToDownload();
              int progress = state.bytesDownloaded();
              // Update progress bar.
              break;

            case SplitInstallSessionStatus.INSTALLED:

              // After a module is installed, you can start accessing its content or
              // fire an intent to start an activity in the installed module.
              // For other use cases, see access code and resources from installed modules.

              // If the request is an on demand module for an Android Instant App
              // running on Android 8.0 (API level 26) or higher, you need to
              // update the app context using the SplitInstallHelper API.
        }
    }
}

আপনার ইনস্টলেশন অনুরোধের সম্ভাব্য অবস্থাগুলি নীচের টেবিলে বর্ণনা করা হয়েছে।

অনুরোধ রাষ্ট্র বর্ণনা ব্যবস্থা নেওয়ার পরামর্শ দিয়েছেন
বিচারাধীন অনুরোধ গৃহীত হয়েছে এবং ডাউনলোড শীঘ্রই শুরু করা উচিত। ডাউনলোডের বিষয়ে ব্যবহারকারীর প্রতিক্রিয়া প্রদান করতে UI উপাদানগুলি, যেমন একটি অগ্রগতি বার শুরু করুন৷
REQUIRES_USER_CONFIRMATION ডাউনলোড ব্যবহারকারী নিশ্চিতকরণ প্রয়োজন. অ্যাপটি Google Play-এর মাধ্যমে ইনস্টল করা না থাকলে সাধারণত এই অবস্থাটি ঘটে। Google Play এর মাধ্যমে বৈশিষ্ট্য ডাউনলোড নিশ্চিত করতে ব্যবহারকারীকে অনুরোধ করুন। আরও জানতে, কীভাবে ব্যবহারকারী নিশ্চিতকরণ পেতে হয় সে সম্পর্কে বিভাগে যান।
ডাউনলোড হচ্ছে ডাউনলোড চলছে। আপনি যদি ডাউনলোডের জন্য একটি অগ্রগতি বার প্রদান করেন, তাহলে UI আপডেট করতে SplitInstallSessionState.bytesDownloaded() এবং SplitInstallSessionState.totalBytesToDownload() পদ্ধতি ব্যবহার করুন (এই টেবিলের উপরে কোড নমুনা দেখুন)।
ডাউনলোড করা হয়েছে ডিভাইসটি মডিউলটি ডাউনলোড করেছে কিন্তু ইনস্টলেশন এখনও শুরু হয়নি। অ্যাপগুলিকে ডাউনলোড করা মডিউলগুলিতে অ্যাক্সেস পেতে SplitCompat সক্ষম করতে হবে এবং এই অবস্থাটি দেখা এড়াতে হবে। বৈশিষ্ট্য মডিউল এর কোড এবং সম্পদ অ্যাক্সেস করার জন্য এটি প্রয়োজন.
ইনস্টল করা হচ্ছে ডিভাইসটি বর্তমানে মডিউলটি ইনস্টল করছে। অগ্রগতি বার আপডেট করুন। এই রাষ্ট্র সাধারণত সংক্ষিপ্ত হয়.
ইনস্টল করা হয়েছে মডিউলটি ডিভাইসে ইনস্টল করা আছে। ব্যবহারকারীর যাত্রা চালিয়ে যেতে মডিউলে কোড এবং সংস্থান অ্যাক্সেস করুন

যদি মডিউলটি Android 8.0 (API লেভেল 26) বা উচ্চতর সংস্করণে চলমান একটি Android Instant অ্যাপের জন্য হয়, তাহলে নতুন মডিউলের সাথে অ্যাপের উপাদান আপডেট করতে আপনাকে splitInstallHelper ব্যবহার করতে হবে।

ব্যর্থ ডিভাইসে মডিউল ইনস্টল করার আগে অনুরোধটি ব্যর্থ হয়েছে৷ ব্যবহারকারীকে অনুরোধটি পুনরায় চেষ্টা করতে বা এটি বাতিল করতে অনুরোধ করুন৷
বাতিল করা হচ্ছে ডিভাইসটি অনুরোধ বাতিল করার প্রক্রিয়ায় রয়েছে। আরও জানতে, কিভাবে একটি ইনস্টল অনুরোধ বাতিল করতে হয় সে সম্পর্কে বিভাগে যান।
বাতিল করা হয়েছে অনুরোধ বাতিল করা হয়েছে.

ব্যবহারকারী নিশ্চিতকরণ প্রাপ্ত

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

কোটলিন

override fun onSessionStateUpdate(state: SplitInstallSessionState) {
    if (state.status() == SplitInstallSessionStatus.REQUIRES_USER_CONFIRMATION) {
        // Displays a confirmation for the user to confirm the request.
        splitInstallManager.startConfirmationDialogForResult(
          state,
          // an activity result launcher registered via registerForActivityResult
          activityResultLauncher)
    }
    ...
 }

জাভা

@Override void onSessionStateUpdate(SplitInstallSessionState state) {
    if (state.status() == SplitInstallSessionStatus.REQUIRES_USER_CONFIRMATION) {
        // Displays a confirmation for the user to confirm the request.
        splitInstallManager.startConfirmationDialogForResult(
          state,
          // an activity result launcher registered via registerForActivityResult
          activityResultLauncher);
    }
    ...
 }

আপনি বিল্টইন ActivityResultContracts.StartIntentSenderForResult চুক্তি ব্যবহার করে একটি কার্যকলাপ ফলাফল লঞ্চার নিবন্ধন করতে পারেন। কার্যকলাপ ফলাফল API দেখুন.

ব্যবহারকারীর প্রতিক্রিয়ার উপর নির্ভর করে অনুরোধের স্থিতি আপডেট করা হয়:

  • ব্যবহারকারী নিশ্চিতকরণ গ্রহণ করলে, অনুরোধের স্থিতি PENDING পরিবর্তিত হবে এবং ডাউনলোড এগিয়ে যাবে।
  • ব্যবহারকারী নিশ্চিতকরণ অস্বীকার করলে, অনুরোধের স্থিতি CANCELED হয়ে যায়।
  • ডায়ালগটি ধ্বংস হওয়ার আগে ব্যবহারকারী যদি একটি নির্বাচন না করে, তাহলে অনুরোধের স্থিতি REQUIRES_USER_CONFIRMATION হিসাবে থাকবে। আপনার অ্যাপ ব্যবহারকারীকে অনুরোধটি সম্পূর্ণ করার জন্য আবার অনুরোধ করতে পারে।

ব্যবহারকারীর প্রতিক্রিয়া সহ একটি কলব্যাক পেতে, আপনি নীচে দেখানো হিসাবে ActivityResultCallback ওভাররাইড করতে পারেন।

কোটলিন

registerForActivityResult(StartIntentSenderForResult()) { result: ActivityResult -> {
        // Handle the user's decision. For example, if the user selects "Cancel",
        // you may want to disable certain functionality that depends on the module.
    }
}

জাভা

registerForActivityResult(
    new ActivityResultContracts.StartIntentSenderForResult(),
    new ActivityResultCallback<ActivityResult>() {
        @Override
        public void onActivityResult(ActivityResult result) {
            // Handle the user's decision. For example, if the user selects "Cancel",
            // you may want to disable certain functionality that depends on the module.
        }
    });

একটি ইনস্টল অনুরোধ বাতিল করুন

যদি আপনার অ্যাপটি ইনস্টল করার আগে একটি অনুরোধ বাতিল করতে হয়, তাহলে এটি নীচে দেখানো হিসাবে অনুরোধের সেশন আইডি ব্যবহার করে cancelInstall() পদ্ধতি ব্যবহার করতে পারে।

কোটলিন

splitInstallManager
    // Cancels the request for the given session ID.
    .cancelInstall(mySessionId)

জাভা

splitInstallManager
    // Cancels the request for the given session ID.
    .cancelInstall(mySessionId);

অ্যাক্সেস মডিউল

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

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

  • প্ল্যাটফর্মটি মডিউল দ্বারা প্রবর্তিত কোনো নতুন ম্যানিফেস্ট এন্ট্রি প্রয়োগ করতে পারে না।
  • প্ল্যাটফর্মটি সিস্টেম UI উপাদানগুলির জন্য মডিউলের সংস্থানগুলি অ্যাক্সেস করতে পারে না, যেমন বিজ্ঞপ্তিগুলি৷ আপনার যদি অবিলম্বে এই জাতীয় সংস্থানগুলি ব্যবহার করার প্রয়োজন হয়, আপনার অ্যাপের বেস মডিউলে সেই সংস্থানগুলি অন্তর্ভুক্ত করার কথা বিবেচনা করুন৷

SplitCompat সক্ষম করুন

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

আপনি আপনার অ্যাপের জন্য SplitCompat সক্ষম করার পরে, আপনি আপনার অ্যাপের অ্যাক্সেস পেতে চান এমন বৈশিষ্ট্য মডিউলগুলির প্রতিটি কার্যকলাপের জন্য আপনাকে SplitCompat সক্ষম করতে হবে।

ম্যানিফেস্টে SplitCompatApplication ঘোষণা করুন

SplitCompat সক্ষম করার সহজতম উপায় হল SplitCompatApplication আপনার অ্যাপের ম্যানিফেস্টে Application সাবক্লাস হিসাবে ঘোষণা করা, যেমনটি নীচে দেখানো হয়েছে:

<application
    ...
    android:name="com.google.android.play.core.splitcompat.SplitCompatApplication">
</application>

অ্যাপটি একটি ডিভাইসে ইনস্টল করার পরে, আপনি স্বয়ংক্রিয়ভাবে ডাউনলোড করা বৈশিষ্ট্য মডিউলগুলি থেকে কোড এবং সংস্থানগুলি অ্যাক্সেস করতে পারেন৷

রানটাইমে SplitCompat আহ্বান করুন

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

আপনার যদি একটি কাস্টম অ্যাপ্লিকেশন ক্লাস থাকে, তাহলে নীচে দেখানো হিসাবে আপনার অ্যাপের জন্য SplitCompat সক্ষম করার জন্য এটির পরিবর্তে SplitCompatApplication প্রসারিত করুন:

কোটলিন

class MyApplication : SplitCompatApplication() {
    ...
}

জাভা

public class MyApplication extends SplitCompatApplication {
    ...
}

SplitCompat.install(Context applicationContext) অন্তর্ভুক্ত করতে SplitCompatApplication সহজভাবে ContextWrapper.attachBaseContext() ওভাররাইড করে। আপনি যদি আপনার Application ক্লাসটি SplitCompatApplication প্রসারিত করতে না চান, তাহলে আপনি attachBaseContext() পদ্ধতিটি ম্যানুয়ালি ওভাররাইড করতে পারেন, নিম্নরূপ:

কোটলিন

override fun attachBaseContext(base: Context) {
    super.attachBaseContext(base)
    // Emulates installation of future on demand modules using SplitCompat.
    SplitCompat.install(this)
}

জাভা

@Override
protected void attachBaseContext(Context base) {
    super.attachBaseContext(base);
    // Emulates installation of future on demand modules using SplitCompat.
    SplitCompat.install(this);
}

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

কোটলিন

override fun attachBaseContext(base: Context) {
    super.attachBaseContext(base)
    if (!InstantApps.isInstantApp(this)) {
        SplitCompat.install(this)
    }
}

জাভা

@Override
protected void attachBaseContext(Context base) {
    super.attachBaseContext(base);
    if (!InstantApps.isInstantApp(this)) {
        SplitCompat.install(this);
    }
}

মডিউল কার্যক্রমের জন্য SplitCompat সক্ষম করুন

আপনি আপনার বেস অ্যাপের জন্য SplitCompat সক্ষম করার পরে, আপনার অ্যাপটি একটি বৈশিষ্ট্য মডিউলে ডাউনলোড করে এমন প্রতিটি কার্যকলাপের জন্য আপনাকে SplitCompat সক্ষম করতে হবে। এটি করার জন্য, SplitCompat.installActivity() পদ্ধতিটি ব্যবহার করুন, নিম্নরূপ:

কোটলিন

override fun attachBaseContext(base: Context) {
    super.attachBaseContext(base)
    // Emulates installation of on demand modules using SplitCompat.
    SplitCompat.installActivity(this)
}

জাভা

@Override
protected void attachBaseContext(Context base) {
    super.attachBaseContext(base);
    // Emulates installation of on demand modules using SplitCompat.
    SplitCompat.installActivity(this);
}

বৈশিষ্ট্য মডিউল সংজ্ঞায়িত অ্যাক্সেস উপাদান

একটি বৈশিষ্ট্য মডিউল সংজ্ঞায়িত একটি কার্যকলাপ শুরু করুন

আপনি SplitCompat সক্ষম করার পরে startActivity() ব্যবহার করে বৈশিষ্ট্য মডিউলগুলিতে সংজ্ঞায়িত ক্রিয়াকলাপগুলি চালু করতে পারেন।

কোটলিন

startActivity(Intent()
  .setClassName("com.package", "com.package.module.MyActivity")
  .setFlags(...))

জাভা

startActivity(new Intent()
  .setClassName("com.package", "com.package.module.MyActivity")
  .setFlags(...));

setClassName প্রথম প্যারামিটারটি অ্যাপের প্যাকেজের নাম এবং দ্বিতীয় প্যারামিটারটি কার্যকলাপের পুরো ক্লাসের নাম।

যখন আপনার একটি ফিচার মডিউলে কোনো অ্যাক্টিভিটি থাকে যা আপনি অন-ডিমান্ড ডাউনলোড করেছেন, তখন আপনাকে অবশ্যই ক্রিয়াকলাপে SplitCompat সক্ষম করতে হবে

একটি বৈশিষ্ট্য মডিউলে সংজ্ঞায়িত একটি পরিষেবা শুরু করুন

আপনি স্প্লিটকম্প্যাট সক্ষম করার পরে startService() ব্যবহার করে বৈশিষ্ট্য মডিউলগুলিতে সংজ্ঞায়িত পরিষেবাগুলি চালু করতে পারেন।

কোটলিন

startService(Intent()
  .setClassName("com.package", "com.package.module.MyService")
  .setFlags(...))

জাভা

startService(new Intent()
  .setClassName("com.package", "com.package.module.MyService")
  .setFlags(...));

একটি বৈশিষ্ট্য মডিউলে সংজ্ঞায়িত একটি উপাদান রপ্তানি করুন

আপনার ঐচ্ছিক মডিউলের মধ্যে রপ্তানি করা Android উপাদান অন্তর্ভুক্ত করা উচিত নয়।

বিল্ড সিস্টেম বেস মডিউলে সমস্ত মডিউলের জন্য ম্যানিফেস্ট এন্ট্রিগুলিকে একত্রিত করে; যদি একটি ঐচ্ছিক মডিউলে একটি রপ্তানিকৃত উপাদান থাকে, তাহলে মডিউলটি ইনস্টল হওয়ার আগেই এটি অ্যাক্সেসযোগ্য হবে এবং অন্য অ্যাপ থেকে আহ্বান করার সময় অনুপস্থিত কোডের কারণে ক্র্যাশ হতে পারে।

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

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

ইনস্টল করা মডিউল থেকে কোড এবং সংস্থান অ্যাক্সেস করুন

আপনি যদি আপনার বেস অ্যাপ্লিকেশন প্রসঙ্গ এবং আপনার বৈশিষ্ট্য মডিউলের কার্যকলাপের জন্য SplitCompat সক্ষম করেন , তাহলে ঐচ্ছিক মডিউল ইনস্টল হয়ে গেলে আপনি একটি বৈশিষ্ট্য মডিউল থেকে কোড এবং সংস্থানগুলি ব্যবহার করতে পারেন যেন এটি বেস APK-এর একটি অংশ।

একটি ভিন্ন মডিউল থেকে অ্যাক্সেস কোড

একটি মডিউল থেকে বেস কোড অ্যাক্সেস করুন

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

অন্য মডিউল থেকে মডিউল কোড অ্যাক্সেস করুন

একটি মডিউলের অভ্যন্তরে একটি বস্তু বা শ্রেণী সরাসরি অন্য মডিউল থেকে স্ট্যাটিকভাবে অ্যাক্সেস করা যায় না, তবে এটি প্রতিফলন ব্যবহার করে পরোক্ষভাবে অ্যাক্সেস করা যেতে পারে।

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

ইন্সট্যান্টেশনের পরে বস্তুর সাথে মিথস্ক্রিয়া সহজ করার জন্য, বেস মডিউলে একটি ইন্টারফেস এবং বৈশিষ্ট্য মডিউলে এর বাস্তবায়নের সংজ্ঞায়িত করার সুপারিশ করা হয়। এই ক্ষেত্রে:

কোটলিন

// In the base module
interface MyInterface {
  fun hello(): String
}

// In the feature module
object MyInterfaceImpl : MyInterface {
  override fun hello() = "Hello"
}

// In the base module, where we want to access the feature module code
val stringFromModule = (Class.forName("com.package.module.MyInterfaceImpl")
    .kotlin.objectInstance as MyInterface).hello();

জাভা

// In the base module
public interface MyInterface {
  String hello();
}

// In the feature module
public class MyInterfaceImpl implements MyInterface {
  @Override
  public String hello() {
    return "Hello";
  }
}

// In the base module, where we want to access the feature module code
String stringFromModule =
   ((MyInterface) Class.forName("com.package.module.MyInterfaceImpl").getConstructor().newInstance()).hello();

একটি ভিন্ন মডিউল থেকে সম্পদ এবং সম্পদ অ্যাক্সেস করুন

একবার একটি মডিউল ইনস্টল হয়ে গেলে, আপনি দুটি সতর্কতা সহ স্ট্যান্ডার্ড উপায়ে মডিউলের মধ্যে সম্পদ এবং সম্পদ অ্যাক্সেস করতে পারেন:

  • আপনি যদি একটি ভিন্ন মডিউল থেকে একটি সংস্থান অ্যাক্সেস করেন, তবে মডিউলটির সংস্থান শনাক্তকারীর অ্যাক্সেস থাকবে না, যদিও সম্পদটি এখনও নাম দ্বারা অ্যাক্সেস করা যেতে পারে। মনে রাখবেন যে সংস্থানটি উল্লেখ করার জন্য যে প্যাকেজটি ব্যবহার করা হবে সেটি হল মডিউলের প্যাকেজ যেখানে সংস্থানটি সংজ্ঞায়িত করা হয়েছে।
  • আপনি যদি আপনার অ্যাপ্লিকেশানের একটি ভিন্ন ইনস্টল করা মডিউল থেকে একটি নতুন ইনস্টল করা মডিউলে বিদ্যমান সম্পদ বা সংস্থানগুলি অ্যাক্সেস করতে চান, তাহলে আপনাকে অবশ্যই অ্যাপ্লিকেশন প্রসঙ্গ ব্যবহার করে তা করতে হবে৷ সংস্থানগুলি অ্যাক্সেস করার চেষ্টা করছে এমন উপাদানটির প্রসঙ্গ এখনও আপডেট করা হবে না। বিকল্পভাবে, আপনি সেই উপাদানটি পুনরায় তৈরি করতে পারেন (উদাহরণস্বরূপ Activity.recreate() কলিং ) অথবা বৈশিষ্ট্য মডিউল ইনস্টলেশনের পরে এটিতে SplitCompat পুনরায় ইনস্টল করতে পারেন

অন-ডিমান্ড ডেলিভারি ব্যবহার করে একটি অ্যাপে নেটিভ কোড লোড করুন

আমরা ফিচার মডিউলের অন-ডিমান্ড ডেলিভারি ব্যবহার করার সময় আপনার সমস্ত নেটিভ লাইব্রেরি লোড করতে ReLinker ব্যবহার করার পরামর্শ দিই। ReLinker একটি বৈশিষ্ট্য মডিউল ইনস্টল করার পরে নেটিভ লাইব্রেরি লোড করার একটি সমস্যা সমাধান করে। আপনি Android JNI টিপসে ReLinker সম্পর্কে আরও জানতে পারবেন।

একটি ঐচ্ছিক মডিউল থেকে নেটিভ কোড লোড করুন

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

আপনি যদি আপনার নেটিভ কোড লোড করতে System.loadLibrary() ব্যবহার করেন এবং আপনার নেটিভ লাইব্রেরির মডিউলের অন্য লাইব্রেরির উপর নির্ভরশীলতা থাকে, তাহলে আপনাকে প্রথমে সেই অন্য লাইব্রেরিটি ম্যানুয়ালি লোড করতে হবে। আপনি যদি ReLinker ব্যবহার করেন, তাহলে সমতুল্য অপারেশন হল Relinker.recursively().loadLibrary()

আপনি যদি একটি ঐচ্ছিক মডিউলে সংজ্ঞায়িত একটি লাইব্রেরি লোড করার জন্য নেটিভ কোডে dlopen() ব্যবহার করেন তবে এটি আপেক্ষিক লাইব্রেরি পাথগুলির সাথে কাজ করবে না। সর্বোত্তম সমাধান হল ClassLoader.findLibrary() এর মাধ্যমে জাভা কোড থেকে লাইব্রেরির পরম পথটি পুনরুদ্ধার করা এবং তারপর এটি আপনার dlopen() কলে ব্যবহার করা। নেটিভ কোড প্রবেশ করার আগে এটি করুন বা জাভাতে আপনার নেটিভ কোড থেকে একটি JNI কল ব্যবহার করুন।

ইনস্টল করা Android ঝটপট অ্যাপ অ্যাক্সেস করুন

একটি অ্যান্ড্রয়েড ইনস্ট্যান্ট অ্যাপ মডিউল INSTALLED হিসাবে রিপোর্ট করার পরে, আপনি একটি রিফ্রেশ করা অ্যাপ প্রসঙ্গ ব্যবহার করে এর কোড এবং সংস্থানগুলি অ্যাক্সেস করতে পারেন৷ একটি মডিউল ইনস্টল করার আগে আপনার অ্যাপ তৈরি করে এমন একটি প্রসঙ্গ (উদাহরণস্বরূপ, যেটি ইতিমধ্যে একটি ভেরিয়েবলে সংরক্ষিত আছে) তাতে নতুন মডিউলের বিষয়বস্তু থাকে না। কিন্তু একটি নতুন প্রসঙ্গ আছে—এটি পাওয়া যেতে পারে, উদাহরণস্বরূপ, createPackageContext ব্যবহার করে।

কোটলিন

// Generate a new context as soon as a request for a new module
// reports as INSTALLED.
override fun onStateUpdate(state: SplitInstallSessionState ) {
    if (state.sessionId() == mySessionId) {
        when (state.status()) {
            ...
            SplitInstallSessionStatus.INSTALLED -> {
                val newContext = context.createPackageContext(context.packageName, 0)
                // If you use AssetManager to access your app’s raw asset files, you’ll need
                // to generate a new AssetManager instance from the updated context.
                val am = newContext.assets
            }
        }
    }
}

জাভা

// Generate a new context as soon as a request for a new module
// reports as INSTALLED.
@Override
public void onStateUpdate(SplitInstallSessionState state) {
    if (state.sessionId() == mySessionId) {
        switch (state.status()) {
            ...
            case SplitInstallSessionStatus.INSTALLED:
                Context newContext = context.createPackageContext(context.getPackageName(), 0);
                // If you use AssetManager to access your app’s raw asset files, you’ll need
                // to generate a new AssetManager instance from the updated context.
                AssetManager am = newContext.getAssets();
        }
    }
}

Android 8.0 এবং উচ্চতর সংস্করণে Android Instant Apps

Android 8.0 (API লেভেল 26) এবং উচ্চতর একটি Android Instant App-এর জন্য একটি অন ডিমান্ড মডিউলের অনুরোধ করার সময়, একটি ইন্সটল রিকোয়েস্ট INSTALLED হিসাবে রিপোর্ট করার পরে, আপনাকে SplitInstallHelper.updateAppInfo(Context context) তে একটি কলের মাধ্যমে নতুন মডিউলের প্রসঙ্গে অ্যাপটি আপডেট করতে হবে। SplitInstallHelper.updateAppInfo(Context context) । অন্যথায়, অ্যাপটি এখনও মডিউলের কোড এবং সংস্থান সম্পর্কে সচেতন নয়। অ্যাপের মেটাডেটা আপডেট করার পরে, আপনাকে পরবর্তী প্রধান থ্রেড ইভেন্টের সময় একটি নতুন Handler আহ্বান করে মডিউলের বিষয়বস্তু লোড করতে হবে, যেমনটি নীচে দেখানো হয়েছে:

কোটলিন

override fun onStateUpdate(state: SplitInstallSessionState ) {
    if (state.sessionId() == mySessionId) {
        when (state.status()) {
            ...
            SplitInstallSessionStatus.INSTALLED -> {
                // You need to perform the following only for Android Instant Apps
                // running on Android 8.0 (API level 26) and higher.
                if (BuildCompat.isAtLeastO()) {
                    // Updates the app’s context with the code and resources of the
                    // installed module.
                    SplitInstallHelper.updateAppInfo(context)
                    Handler().post {
                        // Loads contents from the module using AssetManager
                        val am = context.assets
                        ...
                    }
                }
            }
        }
    }
}

জাভা

@Override
public void onStateUpdate(SplitInstallSessionState state) {
    if (state.sessionId() == mySessionId) {
        switch (state.status()) {
            ...
            case SplitInstallSessionStatus.INSTALLED:
            // You need to perform the following only for Android Instant Apps
            // running on Android 8.0 (API level 26) and higher.
            if (BuildCompat.isAtLeastO()) {
                // Updates the app’s context with the code and resources of the
                // installed module.
                SplitInstallHelper.updateAppInfo(context);
                new Handler().post(new Runnable() {
                    @Override public void run() {
                        // Loads contents from the module using AssetManager
                        AssetManager am = context.getAssets();
                        ...
                    }
                });
            }
        }
    }
}

C/C++ লাইব্রেরি লোড করুন

আপনি যদি এমন একটি মডিউল থেকে C/C++ লাইব্রেরি লোড করতে চান যা ডিভাইসটি ইতিমধ্যেই একটি ঝটপট অ্যাপে ডাউনলোড করেছে, তাহলে নিচে দেখানো হিসাবে SplitInstallHelper.loadLibrary(Context context, String libName) ব্যবহার করুন:

কোটলিন

override fun onStateUpdate(state: SplitInstallSessionState) {
    if (state.sessionId() == mySessionId) {
        when (state.status()) {
            SplitInstallSessionStatus.INSTALLED -> {
                // Updates the app’s context as soon as a module is installed.
                val newContext = context.createPackageContext(context.packageName, 0)
                // To load C/C++ libraries from an installed module, use the following API
                // instead of System.load().
                SplitInstallHelper.loadLibrary(newContext, “my-cpp-lib”)
                ...
            }
        }
    }
}

জাভা

public void onStateUpdate(SplitInstallSessionState state) {
    if (state.sessionId() == mySessionId) {
        switch (state.status()) {
            case SplitInstallSessionStatus.INSTALLED:
                // Updates the app’s context as soon as a module is installed.
                Context newContext = context.createPackageContext(context.getPackageName(), 0);
                // To load C/C++ libraries from an installed module, use the following API
                // instead of System.load().
                SplitInstallHelper.loadLibrary(newContext, “my-cpp-lib”);
                ...
        }
    }
}

পরিচিত সীমাবদ্ধতা

  • একটি ঐচ্ছিক মডিউল থেকে সম্পদ বা সম্পদ অ্যাক্সেস করে এমন একটি কার্যকলাপে Android WebView ব্যবহার করা সম্ভব নয়। এটি অ্যান্ড্রয়েড এপিআই লেভেল 28 এবং তার নিচের ওয়েবভিউ এবং স্প্লিটকম্প্যাটের মধ্যে একটি অসামঞ্জস্যতার কারণে।
  • আপনি Android ApplicationInfo অবজেক্ট, তাদের বিষয়বস্তু বা আপনার অ্যাপের মধ্যে থাকা বস্তুগুলি ক্যাশে করতে পারবেন না। আপনি সবসময় একটি অ্যাপ্লিকেশন প্রসঙ্গ থেকে প্রয়োজন হিসাবে এই বস্তুগুলি আনয়ন করা উচিত. ফিচার মডিউল ইনস্টল করার সময় এই ধরনের অবজেক্ট ক্যাশ করার ফলে অ্যাপটি ক্র্যাশ হতে পারে।

ইনস্টল করা মডিউল পরিচালনা করুন

ডিভাইসে বর্তমানে কোন বৈশিষ্ট্য মডিউল ইনস্টল করা আছে তা পরীক্ষা করতে, আপনি SplitInstallManager.getInstalledModules() কল করতে পারেন, যা নীচে দেখানো মডিউলগুলির নামের একটি Set<String> প্রদান করে।

কোটলিন

val installedModules: Set<String> = splitInstallManager.installedModules

জাভা

Set<String> installedModules = splitInstallManager.getInstalledModules();

মডিউল আনইনস্টল করুন

আপনি নীচে দেখানো হিসাবে SplitInstallManager.deferredUninstall(List<String> moduleNames) ব্যবহার করে মডিউল আনইনস্টল করার জন্য ডিভাইসটিকে অনুরোধ করতে পারেন।

কোটলিন

// Specifies two feature modules for deferred uninstall.
splitInstallManager.deferredUninstall(listOf("pictureMessages", "promotionalFilters"))

জাভা

// Specifies two feature modules for deferred uninstall.
splitInstallManager.deferredUninstall(Arrays.asList("pictureMessages", "promotionalFilters"));

মডিউল আনইনস্টল অবিলম্বে ঘটবে না। অর্থাৎ, স্টোরেজ স্পেস বাঁচাতে ডিভাইসটি পটভূমিতে তাদের আনইনস্টল করে। আপনি নিশ্চিত করতে পারেন যে ডিভাইসটি SplitInstallManager.getInstalledModules() ব্যবহার করে এবং ফলাফল পরিদর্শন করে একটি মডিউল মুছে দিয়েছে, যেমনটি পূর্ববর্তী বিভাগে বর্ণিত হয়েছে।

অতিরিক্ত ভাষা সম্পদ ডাউনলোড করুন

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

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

কোটলিন

// Captures the user’s preferred language and persists it
// through the app’s SharedPreferences.
sharedPrefs.edit().putString(LANGUAGE_SELECTION, "fr").apply()
...

// Creates a request to download and install additional language resources.
val request = SplitInstallRequest.newBuilder()
        // Uses the addLanguage() method to include French language resources in the request.
        // Note that country codes are ignored. That is, if your app
        // includes resources for “fr-FR” and “fr-CA”, resources for both
        // country codes are downloaded when requesting resources for "fr".
        .addLanguage(Locale.forLanguageTag(sharedPrefs.getString(LANGUAGE_SELECTION)))
        .build()

// Submits the request to install the additional language resources.
splitInstallManager.startInstall(request)

জাভা

// Captures the user’s preferred language and persists it
// through the app’s SharedPreferences.
sharedPrefs.edit().putString(LANGUAGE_SELECTION, "fr").apply();
...

// Creates a request to download and install additional language resources.
SplitInstallRequest request =
    SplitInstallRequest.newBuilder()
        // Uses the addLanguage() method to include French language resources in the request.
        // Note that country codes are ignored. That is, if your app
        // includes resources for “fr-FR” and “fr-CA”, resources for both
        // country codes are downloaded when requesting resources for "fr".
        .addLanguage(Locale.forLanguageTag(sharedPrefs.getString(LANGUAGE_SELECTION)))
        .build();

// Submits the request to install the additional language resources.
splitInstallManager.startInstall(request);

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

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

কোটলিন

splitInstallManager.deferredLanguageInstall(
    Locale.forLanguageTag(sharedPrefs.getString(LANGUAGE_SELECTION)))

জাভা

splitInstallManager.deferredLanguageInstall(
    Locale.forLanguageTag(sharedPrefs.getString(LANGUAGE_SELECTION)));

ডাউনলোড করা ভাষা সম্পদ অ্যাক্সেস করুন

ডাউনলোড করা ভাষা সংস্থানগুলিতে অ্যাক্সেস পেতে, আপনার অ্যাপটিকে প্রতিটি ক্রিয়াকলাপের attachBaseContext() পদ্ধতির মধ্যে SplitCompat.installActivity() পদ্ধতিটি চালাতে হবে যার জন্য সেই সংস্থানগুলিতে অ্যাক্সেস প্রয়োজন, নীচে দেখানো হয়েছে৷

কোটলিন

override fun attachBaseContext(base: Context) {
  super.attachBaseContext(base)
  SplitCompat.installActivity(this)
}

জাভা

@Override
protected void attachBaseContext(Context base) {
  super.attachBaseContext(base);
  SplitCompat.installActivity(this);
}

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

কোটলিন

override fun attachBaseContext(base: Context) {
  val configuration = Configuration()
  configuration.setLocale(Locale.forLanguageTag(sharedPrefs.getString(LANGUAGE_SELECTION)))
  val context = base.createConfigurationContext(configuration)
  super.attachBaseContext(context)
  SplitCompat.install(this)
}

জাভা

@Override
protected void attachBaseContext(Context base) {
  Configuration configuration = new Configuration();
  configuration.setLocale(Locale.forLanguageTag(sharedPrefs.getString(LANGUAGE_SELECTION)));
  Context context = base.createConfigurationContext(configuration);
  super.attachBaseContext(context);
  SplitCompat.install(this);
}

এই পরিবর্তনগুলি কার্যকর করার জন্য, নতুন ভাষা ইনস্টল এবং ব্যবহারের জন্য প্রস্তুত হওয়ার পরে আপনাকে আপনার কার্যকলাপ পুনরায় তৈরি করতে হবে। আপনি Activity#recreate() পদ্ধতি ব্যবহার করতে পারেন।

কোটলিন

when (state.status()) {
  SplitInstallSessionStatus.INSTALLED -> {
      // Recreates the activity to load resources for the new language
      // preference.
      activity.recreate()
  }
  ...
}

জাভা

switch (state.status()) {
  case SplitInstallSessionStatus.INSTALLED:
      // Recreates the activity to load resources for the new language
      // preference.
      activity.recreate();
  ...
}

অতিরিক্ত ভাষা সংস্থান আনইনস্টল করুন

বৈশিষ্ট্য মডিউল অনুরূপ, আপনি যে কোনো সময় অতিরিক্ত সম্পদ আনইনস্টল করতে পারেন. একটি আনইনস্টল করার অনুরোধ করার আগে, আপনি প্রথমে নির্ধারণ করতে চাইতে পারেন যে কোন ভাষাগুলি বর্তমানে ইনস্টল করা আছে, নিম্নরূপ।

কোটলিন

val installedLanguages: Set<String> = splitInstallManager.installedLanguages

জাভা

Set<String> installedLanguages = splitInstallManager.getInstalledLanguages();

তারপর আপনি deferredLanguageUninstall() পদ্ধতি ব্যবহার করে কোন ভাষাগুলিকে আনইনস্টল করতে হবে তা নির্ধারণ করতে পারেন, যেমনটি নীচে দেখানো হয়েছে।

কোটলিন

splitInstallManager.deferredLanguageUninstall(
    Locale.forLanguageTag(sharedPrefs.getString(LANGUAGE_SELECTION)))

জাভা

splitInstallManager.deferredLanguageUninstall(
    Locale.forLanguageTag(sharedPrefs.getString(LANGUAGE_SELECTION)));

স্থানীয়ভাবে পরীক্ষা মডিউল ইনস্টল

প্লে ফিচার ডেলিভারি লাইব্রেরি আপনাকে প্লে স্টোরের সাথে সংযোগ না করেই আপনার অ্যাপের নিম্নলিখিত কাজগুলি করার ক্ষমতা স্থানীয়ভাবে পরীক্ষা করতে দেয়:

  • অনুরোধ এবং মডিউল ইনস্টল মনিটর.
  • ইনস্টলেশন ত্রুটিগুলি পরিচালনা করুন।
  • মডিউল অ্যাক্সেস করতে SplitCompat ব্যবহার করুন।

এই পৃষ্ঠাটি বর্ণনা করে যে কীভাবে আপনার পরীক্ষা ডিভাইসে আপনার অ্যাপের বিভক্ত APKগুলি স্থাপন করতে হয় যাতে প্লে বৈশিষ্ট্য ডেলিভারি স্বয়ংক্রিয়ভাবে সেই APKগুলিকে প্লে স্টোর থেকে মডিউলগুলিকে অনুরোধ, ডাউনলোড এবং ইনস্টল করার অনুকরণ করতে ব্যবহার করে৷

যদিও আপনাকে আপনার অ্যাপের যুক্তিতে কোনো পরিবর্তন করতে হবে না, আপনাকে নিম্নলিখিত প্রয়োজনীয়তাগুলি পূরণ করতে হবে:

  • bundletool এর সর্বশেষ সংস্করণটি ডাউনলোড এবং ইনস্টল করুন। আপনার অ্যাপের বান্ডেল থেকে ইনস্টলযোগ্য APKগুলির একটি নতুন সেট তৈরি করতে আপনার bundletool প্রয়োজন৷

APK-এর একটি সেট তৈরি করুন

আপনি যদি ইতিমধ্যে এটি না করে থাকেন তবে আপনার অ্যাপের বিভক্ত APK তৈরি করুন, নিম্নরূপ:

  1. নিম্নলিখিত পদ্ধতিগুলির মধ্যে একটি ব্যবহার করে আপনার অ্যাপের জন্য একটি অ্যাপ বান্ডিল তৈরি করুন:
  2. নিম্নলিখিত কমান্ড সহ সমস্ত ডিভাইস কনফিগারেশনের জন্য APKগুলির একটি সেট তৈরি করতে bundletool ব্যবহার করুন:

    bundletool build-apks --local-testing
      --bundle my_app.aab
      --output my_app.apks
    

--local-testing পতাকা আপনার APK-এর ম্যানিফেস্টে মেটা-ডেটা অন্তর্ভুক্ত করে যা Play বৈশিষ্ট্য ডেলিভারি লাইব্রেরীকে প্লে স্টোরের সাথে সংযোগ না করেই বৈশিষ্ট্য মডিউল ইনস্টল করার জন্য স্থানীয় স্প্লিট APK ব্যবহার করতে দেয়।

ডিভাইসে আপনার অ্যাপ স্থাপন করুন

আপনি --local-testing ফ্ল্যাগ ব্যবহার করে APK-এর একটি সেট তৈরি করার পরে, আপনার অ্যাপের বেস সংস্করণ ইনস্টল করতে bundletool ব্যবহার করুন এবং আপনার ডিভাইসের স্থানীয় স্টোরেজে অতিরিক্ত APK স্থানান্তর করুন। আপনি নিম্নলিখিত কমান্ডের সাথে উভয় ক্রিয়া সম্পাদন করতে পারেন:

bundletool install-apks --apks my_app.apks

এখন, যখন আপনি আপনার অ্যাপটি শুরু করেন এবং একটি বৈশিষ্ট্য মডিউল ডাউনলোড এবং ইনস্টল করার জন্য ব্যবহারকারীর প্রবাহ সম্পূর্ণ করেন, প্লে ফিচার ডেলিভারি লাইব্রেরি এমন APK ব্যবহার করে যা ডিভাইসের স্থানীয় স্টোরেজে bundletool হয়।

একটি নেটওয়ার্ক ত্রুটি অনুকরণ

প্লে স্টোর থেকে মডিউল ইনস্টল অনুকরণ করতে, প্লে ফিচার ডেলিভারি লাইব্রেরি SplitInstallManager এর একটি বিকল্প ব্যবহার করে, যাকে বলা হয় FakeSplitInstallManager , মডিউলটির অনুরোধ করতে। আপনি যখন --local-testing পতাকা সহ bundletool ব্যবহার করেন APK-এর একটি সেট তৈরি করতে এবং সেগুলিকে আপনার পরীক্ষা ডিভাইসে স্থাপন করতে, এতে মেটাডেটা অন্তর্ভুক্ত থাকে যা Play বৈশিষ্ট্য ডেলিভারি লাইব্রেরিকে স্বয়ংক্রিয়ভাবে আপনার অ্যাপের API কলগুলিকে SplitInstallManager এর পরিবর্তে, FakeSplitInstallManager চালু করতে নির্দেশ দেয়। .

FakeSplitInstallManager একটি বুলিয়ান ফ্ল্যাগ অন্তর্ভুক্ত করে যা আপনি পরের বার যখন আপনার অ্যাপ একটি মডিউল ইনস্টল করার অনুরোধ করে তখন একটি নেটওয়ার্ক ত্রুটি অনুকরণ করতে সক্ষম করতে পারেন৷ আপনার পরীক্ষায় FakeSplitInstallManager অ্যাক্সেস করতে, আপনি FakeSplitInstallManagerFactory ব্যবহার করে এটির একটি উদাহরণ পেতে পারেন, যেমনটি নীচে দেখানো হয়েছে:

কোটলিন

// Creates an instance of FakeSplitInstallManager with the app's context.
val fakeSplitInstallManager = FakeSplitInstallManagerFactory.create(context)
// Tells Play Feature Delivery Library to force the next module request to
// result in a network error.
fakeSplitInstallManager.setShouldNetworkError(true)

জাভা

// Creates an instance of FakeSplitInstallManager with the app's context.
FakeSplitInstallManager fakeSplitInstallManager =
    FakeSplitInstallManagerFactory.create(context);
// Tells Play Feature Delivery Library to force the next module request to
// result in a network error.
fakeSplitInstallManager.setShouldNetworkError(true);