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

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

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

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

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

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

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

নতুন ফিচার মডিউল তৈরি করার সবচেয়ে সহজ উপায় হল অ্যান্ড্রয়েড স্টুডিও ৩.৫ বা তার উচ্চতর সংস্করণ ব্যবহার করা। যেহেতু ফিচার মডিউলগুলির বেস অ্যাপ মডিউলের উপর একটি অন্তর্নিহিত নির্ভরতা থাকে, তাই আপনি সেগুলি শুধুমাত্র বিদ্যমান অ্যাপ প্রকল্পগুলিতে যুক্ত করতে পারেন।

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

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

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

      <dist:module
          ...
          dist:title="@string/feature_title">
      </dist:module>
      
    2. Install-time inclusion এর অধীনে ড্রপডাউন মেনুতে, Do not include module at install-time নির্বাচন করুন। Android Studio আপনার পছন্দ প্রতিফলিত করার জন্য মডিউলের ম্যানিফেস্টে নিম্নলিখিতগুলি ইনজেক্ট করে:

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

      <dist:module ...>
          <dist:fusing dist:include="true | false" />
      </dist:module>
      
  7. Finish এ ক্লিক করুন।

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

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

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

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

একটি অন-ডিমান্ড মডিউলের অনুরোধ করুন

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

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

কোটলিন

// 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() এর বিপরীতে, আপনার অ্যাপটিকে একটি deferred ইনস্টলেশনের জন্য অনুরোধ শুরু করার জন্য অগ্রভাগে থাকার প্রয়োজন নেই।

কোটলিন

// 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.
                    }
                }
            }
        });
}

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

ত্রুটি কোড বিবরণ প্রস্তাবিত পদক্ষেপ
সক্রিয়_সেশন_সীমা_পেরিয়ে গেছে অনুরোধটি প্রত্যাখ্যান করা হয়েছে কারণ কমপক্ষে একটি অনুরোধ বর্তমানে ডাউনলোড হচ্ছে। উপরের নমুনায় দেখানো কোনও অনুরোধ এখনও ডাউনলোড হচ্ছে কিনা তা পরীক্ষা করে দেখুন।
মডিউল_অনুপলব্ধ অ্যাপ, ডিভাইস এবং ব্যবহারকারীর গুগল প্লে অ্যাকাউন্টের বর্তমান ইনস্টল করা সংস্করণের উপর ভিত্তি করে গুগল প্লে অনুরোধকৃত মডিউলটি খুঁজে পাচ্ছে না। যদি ব্যবহারকারীর মডিউলটিতে অ্যাক্সেস না থাকে, তাহলে তাদের অবহিত করুন।
INVALID_অনুরোধ গুগল প্লে অনুরোধটি পেয়েছে, কিন্তু অনুরোধটি বৈধ নয়। অনুরোধে অন্তর্ভুক্ত তথ্য সম্পূর্ণ এবং নির্ভুল কিনা তা যাচাই করুন।
সেশন_পাওয়া_যায়নি প্রদত্ত একটি সেশন আইডির জন্য একটি সেশন পাওয়া যায়নি। যদি আপনি কোনও অনুরোধের অবস্থা তার সেশন আইডি দিয়ে পর্যবেক্ষণ করার চেষ্টা করেন, তাহলে নিশ্চিত করুন যে সেশন আইডিটি সঠিক।
API_অনুপস্থিত_ বর্তমান ডিভাইসে প্লে ফিচার ডেলিভারি লাইব্রেরি সমর্থিত নয়। অর্থাৎ, ডিভাইসটি চাহিদা অনুযায়ী ফিচার ডাউনলোড এবং ইনস্টল করতে সক্ষম নয়। অ্যান্ড্রয়েড ৪.৪ (এপিআই লেভেল ২০) বা তার নিচের ভার্সন চালিত ডিভাইসগুলির জন্য, ইনস্টলেশনের সময় dist:fusing ম্যানিফেস্ট প্রপার্টি ব্যবহার করে ফিচার মডিউলগুলি অন্তর্ভুক্ত করা উচিত। আরও জানতে, ফিচার মডিউল ম্যানিফেস্ট সম্পর্কে পড়ুন।
নেটওয়ার্ক_ত্রুটি নেটওয়ার্ক ত্রুটির কারণে অনুরোধটি ব্যর্থ হয়েছে। ব্যবহারকারীকে একটি নেটওয়ার্ক সংযোগ স্থাপন করতে অথবা অন্য একটি নেটওয়ার্কে পরিবর্তন করতে অনুরোধ করুন।
অ্যাক্সেস_অস্বীকৃত পর্যাপ্ত অনুমতি না থাকার কারণে অ্যাপটি অনুরোধটি নিবন্ধন করতে পারছে না। এটি সাধারণত তখন ঘটে যখন অ্যাপটি ব্যাকগ্রাউন্ডে থাকে। অ্যাপটি যখন ফোরগ্রাউন্ডে ফিরে আসে তখন অনুরোধটি করার চেষ্টা করুন।
বিদ্যমান_সেশনের সাথে_অসঙ্গতিপূর্ণ অনুরোধটিতে এক বা একাধিক মডিউল রয়েছে যা ইতিমধ্যেই অনুরোধ করা হয়েছে কিন্তু এখনও ইনস্টল করা হয়নি। হয় এমন একটি নতুন অনুরোধ তৈরি করুন যাতে আপনার অ্যাপ ইতিমধ্যেই অনুরোধ করেছে এমন মডিউল অন্তর্ভুক্ত না থাকে, অথবা অনুরোধটি পুনরায় চেষ্টা করার আগে বর্তমানে অনুরোধ করা সমস্ত মডিউল ইনস্টল করা শেষ না হওয়া পর্যন্ত অপেক্ষা করুন।

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

সার্ভিস_ডাইড অনুরোধটি পরিচালনার জন্য দায়িত্বপ্রাপ্ত পরিষেবাটি মারা গেছে। অনুরোধটি আবার চেষ্টা করুন।

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

অপর্যাপ্ত_স্টোরেজ ফিচার মডিউলটি ইনস্টল করার জন্য ডিভাইসটিতে পর্যাপ্ত ফ্রি স্টোরেজ নেই। ব্যবহারকারীকে জানান যে এই বৈশিষ্ট্যটি ইনস্টল করার জন্য তাদের কাছে পর্যাপ্ত সঞ্চয়স্থান নেই।
SPLITCOMPAT_যাচাই_ত্রুটি, SPLITCOMPAT_EMULATION_ত্রুটি, SPLITCOMPAT_COPY_ত্রুটি SplitCompat ফিচার মডিউলটি লোড করতে পারেনি। পরবর্তী অ্যাপ রিস্টার্ট করার পরে এই ত্রুটিগুলি স্বয়ংক্রিয়ভাবে সমাধান হয়ে যাবে।
PLAY_STORE_NOT_FOUND সম্পর্কে ডিভাইসে প্লে স্টোর অ্যাপটি ইনস্টল করা নেই। ব্যবহারকারীকে জানাতে হবে যে এই বৈশিষ্ট্যটি ডাউনলোড করার জন্য প্লে স্টোর অ্যাপটি প্রয়োজন।
অ্যাপ_অন_মালিকানাধীন অ্যাপটি গুগল প্লে দ্বারা ইনস্টল করা হয়নি এবং বৈশিষ্ট্যটি ডাউনলোড করা যাচ্ছে না। এই ত্রুটিটি শুধুমাত্র বিলম্বিত ইনস্টলেশনের ক্ষেত্রেই ঘটতে পারে। যদি আপনি চান যে ব্যবহারকারী গুগল প্লে থেকে অ্যাপটি পান, 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 উপাদানগুলি, যেমন একটি অগ্রগতি বার, আরম্ভ করুন।
ব্যবহারকারীর_নিশ্চয়তা প্রয়োজন ডাউনলোডের জন্য ব্যবহারকারীর নিশ্চিতকরণ প্রয়োজন। সাধারণত এই অবস্থাটি তখন ঘটে যখন অ্যাপটি Google Play এর মাধ্যমে ইনস্টল করা না থাকে। ব্যবহারকারীকে Google Play এর মাধ্যমে বৈশিষ্ট্যটি ডাউনলোড নিশ্চিত করতে বলুন। আরও জানতে, ব্যবহারকারীর নিশ্চিতকরণ কীভাবে পাবেন সে সম্পর্কে বিভাগে যান।
ডাউনলোড হচ্ছে ডাউনলোড চলছে। যদি আপনি ডাউনলোডের জন্য একটি অগ্রগতি বার প্রদান করেন, তাহলে UI আপডেট করার জন্য SplitInstallSessionState.bytesDownloaded() এবং SplitInstallSessionState.totalBytesToDownload() পদ্ধতি ব্যবহার করুন (এই টেবিলের উপরে কোড নমুনা দেখুন)।
ডাউনলোড করা হয়েছে ডিভাইসটি মডিউলটি ডাউনলোড করেছে কিন্তু ইনস্টলেশন এখনও শুরু হয়নি। অ্যাপগুলির উচিত SplitCompat-কে ডাউনলোড করা মডিউলগুলিতে অ্যাক্সেস সক্ষম করা এবং এই অবস্থাটি দেখা এড়ানো। ফিচার মডিউলের কোড এবং রিসোর্সগুলি অ্যাক্সেস করার জন্য এটি প্রয়োজন।
ইনস্টল করা হচ্ছে ডিভাইসটি বর্তমানে মডিউলটি ইনস্টল করছে। অগ্রগতি বার আপডেট করুন। এই অবস্থা সাধারণত ছোট থাকে।
ইনস্টল করা হয়েছে মডিউলটি ডিভাইসে ইনস্টল করা আছে। ব্যবহারকারীর যাত্রা চালিয়ে যেতে মডিউলে কোড এবং রিসোর্স অ্যাক্সেস করুন

যদি মডিউলটি অ্যান্ড্রয়েড ৮.০ (এপিআই লেভেল ২৬) বা তার বেশি চলমান অ্যান্ড্রয়েড ইনস্ট্যান্ট অ্যাপের জন্য হয়, তাহলে নতুন মডিউল দিয়ে অ্যাপের উপাদানগুলি আপডেট করার জন্য আপনাকে 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 {
    ...
}

SplitCompatApplication কেবল ContextWrapper.attachBaseContext() কে ওভাররাইড করে SplitCompat.install(Context applicationContext) অন্তর্ভুক্ত করে। যদি আপনি না চান যে আপনার 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 সক্ষম করতে হবে।

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

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

কোটলিন

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

জাভা

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

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

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

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

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

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

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

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

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

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

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

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

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

প্রতিফলনের কর্মক্ষমতা খরচের কারণে এটি কত ঘন ঘন ঘটে সে সম্পর্কে আপনার সতর্ক থাকা উচিত। জটিল ব্যবহারের ক্ষেত্রে, প্রতি অ্যাপ্লিকেশনের জীবনকাল প্রতি একক প্রতিফলন কলের নিশ্চয়তা দিতে Dagger 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 ইনস্ট্যান্ট অ্যাপ অ্যাক্সেস করুন

একটি Android Instant App মডিউল INSTALLED হিসেবে রিপোর্ট করার পর, আপনি একটি রিফ্রেশ করা অ্যাপ Context ব্যবহার করে এর কোড এবং রিসোর্স অ্যাক্সেস করতে পারবেন। আপনার অ্যাপটি একটি মডিউল ইনস্টল করার আগে যে কনটেক্সট তৈরি করে (উদাহরণস্বরূপ, যেটি ইতিমধ্যেই একটি ভেরিয়েবলে সংরক্ষিত আছে) তাতে নতুন মডিউলের কন্টেন্ট থাকে না। কিন্তু একটি নতুন কনটেক্সট থাকে - এটি পাওয়া যেতে পারে, উদাহরণস্বরূপ, 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) এ কল করে নতুন মডিউলের প্রসঙ্গ সহ অ্যাপটি আপডেট করতে হবে। অন্যথায়, অ্যাপটি এখনও মডিউলের কোড এবং রিসোর্স সম্পর্কে অবগত নয়। অ্যাপের মেটাডেটা আপডেট করার পরে, আপনার পরবর্তী প্রধান থ্রেড ইভেন্টের সময় একটি নতুন 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 ব্যবহার করা সম্ভব নয়। এটি Android API লেভেল 28 এবং তার নিচের সংস্করণে WebView এবং SplitCompat এর মধ্যে অসঙ্গতির কারণে।
  • আপনি 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 গুলিকে আপনার পরীক্ষামূলক ডিভাইসে স্থাপন করবেন যাতে Play Feature Delivery স্বয়ংক্রিয়ভাবে সেই APK গুলিকে Play Store থেকে মডিউল অনুরোধ, ডাউনলোড এবং ইনস্টল করার অনুকরণ করতে ব্যবহার করে।

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

  • 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 Feature Delivery Library-কে Play Store-এর সাথে সংযোগ না করেই স্থানীয় স্প্লিট APK ব্যবহার করে ফিচার মডিউল ইনস্টল করার পরীক্ষা করতে সাহায্য করে।

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

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

bundletool install-apks --apks my_app.apks

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

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

প্লে স্টোর থেকে মডিউল ইনস্টল সিমুলেট করার জন্য, প্লে ফিচার ডেলিভারি লাইব্রেরি SplitInstallManager এর বিকল্প ব্যবহার করে, যাকে FakeSplitInstallManager বলা হয়, মডিউলটি অনুরোধ করার জন্য। যখন আপনি --local-testing ফ্ল্যাগ সহ bundletool ব্যবহার করে APK গুলির একটি সেট তৈরি করেন এবং সেগুলিকে আপনার টেস্ট ডিভাইসে স্থাপন করেন, তখন এতে মেটাডেটা থাকে যা Play Feature Delivery Library কে নির্দেশ দেয় যে আপনার অ্যাপের 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);