অ্যাক্টিভিটি এমবেডিং

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

চিত্র 1. পাশাপাশি অ্যাক্টিভিটি সহ সেটিংস অ্যাপ।

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

অ্যাক্টিভিটি এম্বেডিংয়ের জন্য কোনো কোড রিফ্যাক্টরিংয়ের প্রয়োজন নেই। একটি XML কনফিগারেশন ফাইল তৈরি করে বা Jetpack WindowManager API কল করে আপনার অ্যাপ কীভাবে তার ক্রিয়াকলাপগুলি-পাশাপাশি বা স্তূপাকারভাবে প্রদর্শন করে তা আপনি নির্ধারণ করেন।

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

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

অ্যাক্টিভিটি এম্বেডিং অ্যান্ড্রয়েড 12L (API লেভেল 32) এবং উচ্চতর চলমান বেশিরভাগ বড় স্ক্রীন ডিভাইসে সমর্থিত।

স্প্লিট টাস্ক উইন্ডো

অ্যাক্টিভিটি এম্বেডিং অ্যাপ টাস্ক উইন্ডোটিকে দুটি পাত্রে বিভক্ত করে: প্রাথমিক এবং মাধ্যমিক৷ কন্টেইনারগুলি মূল ক্রিয়াকলাপ থেকে বা ইতিমধ্যে কন্টেইনারে থাকা অন্যান্য ক্রিয়াকলাপগুলি থেকে শুরু করা ক্রিয়াকলাপগুলিকে ধরে রাখে৷

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

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

চিত্র 2. পাশাপাশি দুটি ক্রিয়াকলাপ।

অথবা, একটি ক্রিয়াকলাপ যা পুরো টাস্ক উইন্ডোটি দখল করে আছে পাশাপাশি একটি নতুন কার্যকলাপ চালু করে একটি বিভক্ত তৈরি করতে পারে:

চিত্র 3. A কার্যকলাপ B পাশ থেকে শুরু করে।

যে ক্রিয়াকলাপগুলি ইতিমধ্যে একটি বিভক্ত অবস্থায় রয়েছে এবং একটি টাস্ক উইন্ডো ভাগ করে নেওয়া হয়েছে সেগুলি নিম্নলিখিত উপায়ে অন্যান্য ক্রিয়াকলাপ চালু করতে পারে:

  • অন্য কার্যকলাপের উপরে পাশে:

    চিত্র 4. A কার্যকলাপ C শুরু করে B কার্যকলাপের পাশ দিয়ে।
  • পাশের দিকে, এবং পূর্ববর্তী প্রাথমিক কার্যকলাপ গোপন করে, বিভক্তটি পাশে স্থানান্তর করুন:

    চিত্র 5. অ্যাক্টিভিটি B অ্যাক্টিভিটি C-কে পাশে শুরু করে এবং বিভক্তটিকে পাশে সরিয়ে দেয়।
  • উপরে জায়গায় একটি কার্যকলাপ চালু করুন; যে, একই কার্যকলাপ স্ট্যাকে:

    চিত্র 6. কার্যকলাপ B কোনো অতিরিক্ত অভিপ্রায় ফ্ল্যাগ ছাড়াই C কার্যকলাপ শুরু করে।
  • একই টাস্কে একটি অ্যাক্টিভিটি পূর্ণ উইন্ডো চালু করুন:

    চিত্র 7. কার্যকলাপ A বা কার্যকলাপ B কার্যকলাপ C শুরু করে যা টাস্ক উইন্ডোটি পূরণ করে।

পিছনে নেভিগেশন

ক্রিয়াকলাপগুলির মধ্যে নির্ভরতা বা ব্যবহারকারীরা কীভাবে ব্যাক ইভেন্টটি ট্রিগার করে তার উপর নির্ভর করে বিভিন্ন ধরণের অ্যাপ্লিকেশনগুলির একটি বিভক্ত টাস্ক উইন্ডো অবস্থায় বিভিন্ন ব্যাক নেভিগেশন নিয়ম থাকতে পারে, উদাহরণস্বরূপ:

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

বোতাম নেভিগেশন ব্যবহার করার সময় পিছনের ইভেন্টটি শেষ ফোকাস করা কার্যকলাপে পাঠানো হয়।

অঙ্গভঙ্গি-ভিত্তিক নেভিগেশনের জন্য:

  • অ্যান্ড্রয়েড 14 (এপিআই স্তর 34) এবং নীচের — পিছনের ইভেন্টটি সেই কার্যকলাপে পাঠানো হয় যেখানে অঙ্গভঙ্গিটি ঘটেছে। যখন ব্যবহারকারীরা স্ক্রিনের বাম দিক থেকে সোয়াইপ করেন, তখন পিছনের ইভেন্টটি স্প্লিট উইন্ডোর বাম দিকের ফলকে কার্যকলাপে পাঠানো হয়। যখন ব্যবহারকারীরা স্ক্রিনের ডান দিক থেকে সোয়াইপ করেন, তখন পিছনের ইভেন্টটি ডানদিকের ফলকে কার্যকলাপে পাঠানো হয়।

  • Android 15 (API স্তর 35) এবং উচ্চতর

    • একই অ্যাপ থেকে একাধিক ক্রিয়াকলাপ নিয়ে কাজ করার সময়, অঙ্গভঙ্গিটি সোয়াইপ দিক নির্বিশেষে শীর্ষ ক্রিয়াকলাপ শেষ করে, আরও একীভূত অভিজ্ঞতা প্রদান করে।

    • বিভিন্ন অ্যাপ্লিকেশান (ওভারলে) থেকে দুটি ক্রিয়াকলাপ জড়িত পরিস্থিতিতে, পিছনের ইভেন্টটি বোতাম নেভিগেশনের আচরণের সাথে সারিবদ্ধ করে ফোকাসের শেষ কার্যকলাপের দিকে পরিচালিত হয়।

মাল্টি-প্যান লেআউট

Jetpack WindowManager আপনাকে Android 12L (API লেভেল 32) বা উচ্চতর এবং পূর্ববর্তী প্ল্যাটফর্ম সংস্করণ সহ কিছু ডিভাইসে বড় স্ক্রীনের ডিভাইসে মাল্টি-পেন লেআউট এম্বেড করার একটি অ্যাক্টিভিটি তৈরি করতে সক্ষম করে। বিদ্যমান অ্যাপ্লিকেশানগুলি যেগুলি খণ্ড বা ভিউ-ভিত্তিক লেআউটগুলির পরিবর্তে একাধিক ক্রিয়াকলাপের উপর ভিত্তি করে যেমন SlidingPaneLayout সোর্স কোড রিফ্যাক্টরিং ছাড়াই একটি উন্নত বড় স্ক্রীন ব্যবহারকারীর অভিজ্ঞতা প্রদান করতে পারে৷

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

চিত্র 8. একটি মাল্টি-পেন লেআউটে দুটি কার্যক্রম একই সাথে শুরু হয়েছে।

বিভক্ত বৈশিষ্ট্য

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

একটি XML কনফিগারেশন ফাইলে সংজ্ঞায়িত নিয়মগুলির জন্য, নিম্নলিখিত বৈশিষ্ট্যগুলি সেট করুন:

  • splitRatio : ধারক অনুপাত সেট করে। মানটি খোলা ব্যবধানে একটি ফ্লোটিং পয়েন্ট সংখ্যা (0.0, 1.0)।
  • splitLayoutDirection : বিভক্ত পাত্রগুলি একে অপরের সাপেক্ষে কীভাবে সাজানো হয় তা নির্দিষ্ট করে। মান অন্তর্ভুক্ত:
    • ltr : বাম থেকে ডানে
    • rtl : ডান থেকে বাম
    • locale : ltr বা rtl হয় লোকেল সেটিং থেকে নির্ধারিত হয়

উদাহরণের জন্য XML কনফিগারেশন বিভাগটি দেখুন।

WindowManager API ব্যবহার করে তৈরি করা নিয়মগুলির জন্য, SplitAttributes.Builder দিয়ে একটি SplitAttributes অবজেক্ট তৈরি করুন এবং নিম্নলিখিত বিল্ডার পদ্ধতিগুলিকে কল করুন:

  • setSplitType() : বিভক্ত পাত্রের অনুপাত সেট করে। SplitAttributes.SplitType.ratio() পদ্ধতি সহ বৈধ আর্গুমেন্টের জন্য SplitAttributes.SplitType দেখুন।
  • setLayoutDirection() : কন্টেইনারগুলির বিন্যাস সেট করে। সম্ভাব্য মানগুলির জন্য SplitAttributes.LayoutDirection দেখুন।

উদাহরণের জন্য WindowManager API বিভাগটি দেখুন।

চিত্র 9. দুটি ক্রিয়াকলাপ বিভাজন বাম থেকে ডানে কিন্তু বিভিন্ন বিভক্ত অনুপাত সহ।

স্থানধারক

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

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

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

যাইহোক, SplitPlaceholderRule এর stickyPlaceholder বৈশিষ্ট্য বা SplitPlaceholder.Builder এর setSticky() পদ্ধতি ডিফল্ট আচরণকে ওভাররাইড করতে পারে। যখন অ্যাট্রিবিউট বা পদ্ধতি true একটি মান নির্দিষ্ট করে, তখন সিস্টেমটি টাস্ক উইন্ডোতে প্লেসহোল্ডারটিকে শীর্ষস্থানীয় কার্যকলাপ হিসাবে প্রদর্শন করে যখন ডিসপ্লেটিকে টু-পেন ডিসপ্লে থেকে একটি একক-প্যান ডিসপ্লেতে পুনরায় আকার দেওয়া হয় (একটি উদাহরণের জন্য স্প্লিট কনফিগারেশন দেখুন) .

চিত্র 11. ভাঁজযোগ্য ডিভাইস ভাঁজ এবং উন্মোচন। স্থানধারক কার্যকলাপ স্টিকি.

জানালার আকার পরিবর্তন

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

প্লেসহোল্ডার কার্যকলাপ শুধুমাত্র তখনই দেখানো হয় যখন একটি বিভাজনের জন্য যথেষ্ট প্রদর্শন প্রস্থ থাকে। ছোট পর্দায়, স্থানধারক স্বয়ংক্রিয়ভাবে বরখাস্ত হয়। যখন ডিসপ্লে এরিয়া আবার যথেষ্ট বড় হয়ে যায়, তখন প্লেসহোল্ডারটি পুনরায় তৈরি করা হয়। ( প্লেসহোল্ডার বিভাগ দেখুন।)

অ্যাক্টিভিটি স্ট্যাকিং সম্ভব কারণ WindowManager z-অর্ডার করে সেকেন্ডারি প্যানে ক্রিয়াকলাপগুলি প্রাথমিক ফলকের উপরে কার্যকলাপগুলিকে।

সেকেন্ডারি প্যানে একাধিক কার্যক্রম

অ্যাক্টিভিটি B কোনো অতিরিক্ত উদ্দেশ্য ফ্ল্যাগ ছাড়াই C-এর জায়গায় কার্যকলাপ শুরু করে:

অ্যাক্টিভিটি স্প্লিট যাতে অ্যা, বি, এবং সি অ্যাক্টিভিটি থাকে এবং C এর সাথে B-এর উপরে স্তুপ করা হয়।

একই টাস্কে নিম্নলিখিত z-ক্রমের কার্যক্রমের ফলে:

সেকেন্ডারি অ্যাক্টিভিটি স্ট্যাক যার মধ্যে অ্যাক্টিভিটি C রয়েছে B-এর উপরে। সেকেন্ডারি স্ট্যাকটি প্রামারি অ্যাক্টিভিটি স্ট্যাকের উপরে স্ট্যাক করা হয় যেটিতে অ্যাক্টিভিটি থাকে।

সুতরাং, একটি ছোট টাস্ক উইন্ডোতে, অ্যাপ্লিকেশনটি স্ট্যাকের শীর্ষে C সহ একটি একক কার্যকলাপে সঙ্কুচিত হয়:

ছোট উইন্ডো শুধুমাত্র কার্যকলাপ দেখায় C.

ছোট উইন্ডোতে আবার নেভিগেট করা একে অপরের উপরে স্তুপীকৃত কার্যকলাপের মাধ্যমে নেভিগেট করে।

যদি টাস্ক উইন্ডো কনফিগারেশনটি একটি বৃহত্তর আকারে পুনরুদ্ধার করা হয় যা একাধিক ফলককে মিটমাট করতে পারে, কার্যকলাপগুলি আবার পাশাপাশি প্রদর্শিত হবে।

স্তুপীকৃত বিভাজন

অ্যাক্টিভিটি B অ্যাক্টিভিটি C-কে পাশে শুরু করে এবং বিভক্তটিকে পাশে সরিয়ে দেয়:

টাস্ক উইন্ডো A এবং B ক্রিয়াকলাপ দেখায়, তারপরে B এবং C ক্রিয়াকলাপগুলি দেখায়।

ফলাফল হল একই টাস্কের ক্রিয়াকলাপগুলির নিম্নলিখিত z-ক্রম:

অ্যাক্টিভিটিগুলি A, B, এবং C একটি একক স্ট্যাকে। ক্রিয়াকলাপগুলি উপরে থেকে নীচের ক্রমানুসারে স্ট্যাক করা হয়েছে: C, B, A।

একটি ছোট টাস্ক উইন্ডোতে, অ্যাপ্লিকেশনটি উপরে C সহ একটি একক কার্যকলাপে সঙ্কুচিত হয়:

ছোট উইন্ডো শুধুমাত্র কার্যকলাপ দেখায় C.

স্থির-প্রতিকৃতি অভিযোজন

android:screenOrientation ম্যানিফেস্ট সেটিং অ্যাপগুলিকে পোর্ট্রেট বা ল্যান্ডস্কেপ ওরিয়েন্টেশনে ক্রিয়াকলাপগুলিকে সীমাবদ্ধ করতে সক্ষম করে৷ ট্যাবলেট এবং ফোল্ডেবলের মতো বড় স্ক্রীন ডিভাইসগুলিতে ব্যবহারকারীর অভিজ্ঞতা উন্নত করতে, ডিভাইস নির্মাতারা (OEMs) স্ক্রীন ওরিয়েন্টেশন অনুরোধগুলিকে উপেক্ষা করতে পারে এবং ল্যান্ডস্কেপ ডিসপ্লেতে পোর্ট্রেট ওরিয়েন্টেশনে বা পোর্ট্রেট ডিসপ্লেতে ল্যান্ডস্কেপ ওরিয়েন্টেশনে অ্যাপটিকে লেটারবক্স করতে পারে।

চিত্র 12. লেটারবক্সযুক্ত কার্যক্রম: ল্যান্ডস্কেপ ডিভাইসে ফিক্সড-পোর্ট্রেট (বাম), পোর্ট্রেট ডিভাইসে ফিক্সড-ল্যান্ডস্কেপ (ডানদিকে)।

একইভাবে, যখন অ্যাক্টিভিটি এমবেডিং সক্ষম করা থাকে, তখন OEMগুলি বড় স্ক্রিনে (প্রস্থ ≥ 600dp) ল্যান্ডস্কেপ ওরিয়েন্টেশনে লেটারবক্স ফিক্সড-পোর্ট্রেট অ্যাক্টিভিটিগুলিতে ডিভাইসগুলি কাস্টমাইজ করতে পারে। যখন একটি ফিক্সড-পোর্ট্রেট অ্যাক্টিভিটি একটি দ্বিতীয় অ্যাক্টিভিটি চালু করে, তখন ডিভাইসটি দুটি ক্রিয়াকলাপ পাশাপাশি প্রদর্শন করতে পারে একটি টু-পেন ডিসপ্লেতে।

চিত্র 13. ফিক্সড-পোর্ট্রেট অ্যাক্টিভিটি A পাশ থেকে B কার্যকলাপ শুরু করে।

ডিভাইসগুলিকে জানাতে যে আপনার অ্যাপ অ্যাক্টিভিটি এম্বেডিং সমর্থন করে তা জানাতে আপনার অ্যাপ ম্যানিফেস্ট ফাইলে সর্বদা android.window.PROPERTY_ACTIVITY_EMBEDDING_SPLITS_ENABLED প্রপার্টি যোগ করুন ( বিভক্ত কনফিগারেশন বিভাগটি দেখুন)। OEM-কাস্টমাইজড ডিভাইসগুলি তারপর লেটারবক্স ফিক্সড-পোর্ট্রেট ক্রিয়াকলাপগুলি নির্ধারণ করতে পারে।

বিভক্ত কনফিগারেশন

বিভক্ত নিয়ম কার্যকলাপ বিভক্ত কনফিগার. আপনি একটি XML কনফিগারেশন ফাইলে বা Jetpack WindowManager API কল করে বিভক্ত নিয়মগুলি সংজ্ঞায়িত করেন।

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

নিম্নলিখিতগুলি করুন:

  1. আপনার অ্যাপের মডিউল-স্তরের build.gradle ফাইলে সর্বশেষ WindowManager লাইব্রেরি নির্ভরতা যোগ করুন, উদাহরণস্বরূপ:

    implementation 'androidx.window:window:1.1.0-beta02'

    WindowManager লাইব্রেরি অ্যাক্টিভিটি এমবেডিংয়ের জন্য প্রয়োজনীয় সমস্ত উপাদান সরবরাহ করে।

  2. সিস্টেমকে জানান যে আপনার অ্যাপ অ্যাক্টিভিটি এমবেডিং প্রয়োগ করেছে।

    অ্যাপ ম্যানিফেস্ট ফাইলের <application> উপাদানে android.window.PROPERTY_ACTIVITY_EMBEDDING_SPLITS_ENABLED প্রপার্টি যোগ করুন এবং মানটিকে সত্যে সেট করুন, উদাহরণস্বরূপ:

    <manifest xmlns:android="http://schemas.android.com/apk/res/android">
        <application>
            <property
                android:name="android.window.PROPERTY_ACTIVITY_EMBEDDING_SPLITS_ENABLED"
                android:value="true" />
        </application>
    </manifest>
    

    WindowManager রিলিজ 1.1.0-alpha06 এবং পরবর্তীতে, অ্যাক্টিভিটি এমবেডিং স্প্লিটগুলি নিষ্ক্রিয় করা হয় যদি না সম্পত্তিটি ম্যানিফেস্টে যোগ করা হয় এবং সত্যে সেট করা হয়।

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

XML কনফিগারেশন

অ্যাক্টিভিটি এম্বেডিংয়ের একটি XML-ভিত্তিক বাস্তবায়ন তৈরি করতে, নিম্নলিখিত ধাপগুলি সম্পূর্ণ করুন:

  1. একটি XML রিসোর্স ফাইল তৈরি করুন যা নিম্নলিখিতগুলি করে:

    • ক্রিয়াকলাপগুলিকে সংজ্ঞায়িত করে যা একটি বিভাজন ভাগ করে
    • বিভক্ত বিকল্পগুলি কনফিগার করে
    • বিষয়বস্তু উপলব্ধ না হলে বিভক্তের গৌণ ধারকের জন্য একটি স্থানধারক তৈরি করে
    • এমন ক্রিয়াকলাপগুলি নির্দিষ্ট করে যেগুলি কখনই বিভাজনের অংশ হওয়া উচিত নয়৷

    যেমন:

    <!-- main_split_config.xml -->
    
    <resources
        xmlns:window="http://schemas.android.com/apk/res-auto">
    
        <!-- Define a split for the named activities. -->
        <SplitPairRule
            window:splitRatio="0.33"
            window:splitLayoutDirection="locale"
            window:splitMinWidthDp="840"
            window:splitMaxAspectRatioInPortrait="alwaysAllow"
            window:finishPrimaryWithSecondary="never"
            window:finishSecondaryWithPrimary="always"
            window:clearTop="false">
            <SplitPairFilter
                window:primaryActivityName=".ListActivity"
                window:secondaryActivityName=".DetailActivity"/>
        </SplitPairRule>
    
        <!-- Specify a placeholder for the secondary container when content is
             not available. -->
        <SplitPlaceholderRule
            window:placeholderActivityName=".PlaceholderActivity"
            window:splitRatio="0.33"
            window:splitLayoutDirection="locale"
            window:splitMinWidthDp="840"
            window:splitMaxAspectRatioInPortrait="alwaysAllow"
            window:stickyPlaceholder="false">
            <ActivityFilter
                window:activityName=".ListActivity"/>
        </SplitPlaceholderRule>
    
        <!-- Define activities that should never be part of a split. Note: Takes
             precedence over other split rules for the activity named in the
             rule. -->
        <ActivityRule
            window:alwaysExpand="true">
            <ActivityFilter
                window:activityName=".ExpandedActivity"/>
        </ActivityRule>
    
    </resources>
    
  2. একটি ইনিশিয়ালাইজার তৈরি করুন।

    WindowManager RuleController উপাদান XML কনফিগারেশন ফাইল পার্স করে এবং নিয়মগুলি সিস্টেমে উপলব্ধ করে। একটি জেটপ্যাক স্টার্টআপ লাইব্রেরি Initializer অ্যাপ স্টার্টআপে XML ফাইলটি RuleController এর কাছে উপলব্ধ করে যাতে কোনও কার্যকলাপ শুরু হলে নিয়মগুলি কার্যকর হয়।

    একটি ইনিশিয়ালাইজার তৈরি করতে, নিম্নলিখিতগুলি করুন:

    1. আপনার মডিউল-স্তরের build.gradle ফাইলে সাম্প্রতিক জেটপ্যাক স্টার্টআপ লাইব্রেরি নির্ভরতা যোগ করুন, উদাহরণস্বরূপ:

      implementation 'androidx.startup:startup-runtime:1.1.1'

    2. একটি ক্লাস তৈরি করুন যা Initializer ইন্টারফেস প্রয়োগ করে।

      ইনিশিয়ালাইজার XML কনফিগারেশন ফাইলের ID ( main_split_config.xml ) RuleController.parseRules() পদ্ধতিতে পাস করে RuleController কাছে বিভক্ত নিয়মগুলি উপলব্ধ করে।

      কোটলিন

      class SplitInitializer : Initializer<RuleController> {
      
          override fun create(context: Context): RuleController {
              return RuleController.getInstance(context).apply {
                  setRules(RuleController.parseRules(context, R.xml.main_split_config))
              }
          }
      
          override fun dependencies(): List<Class<out Initializer<*>>> {
              return emptyList()
          }
      }

      জাভা

      public class SplitInitializer implements Initializer<RuleController> {
      
           @NonNull
           @Override
           public RuleController create(@NonNull Context context) {
               RuleController ruleController = RuleController.getInstance(context);
               ruleController.setRules(
                   RuleController.parseRules(context, R.xml.main_split_config)
               );
               return ruleController;
           }
      
           @NonNull
           @Override
           public List<Class<? extends Initializer<?>>> dependencies() {
               return Collections.emptyList();
           }
      }
  3. নিয়মের সংজ্ঞার জন্য একটি বিষয়বস্তু প্রদানকারী তৈরি করুন।

    আপনার অ্যাপ ম্যানিফেস্ট ফাইলে androidx.startup.InitializationProvider যোগ করুন <provider> হিসেবে। আপনার RuleController ইনিশিয়ালাইজার, SplitInitializer এর বাস্তবায়নের একটি রেফারেন্স অন্তর্ভুক্ত করুন:

    <!-- AndroidManifest.xml -->
    
    <provider android:name="androidx.startup.InitializationProvider"
        android:authorities="${applicationId}.androidx-startup"
        android:exported="false"
        tools:node="merge">
        <!-- Make SplitInitializer discoverable by InitializationProvider. -->
        <meta-data android:name="${applicationId}.SplitInitializer"
            android:value="androidx.startup" />
    </provider>
    

    InitializationProvider অ্যাপের onCreate() পদ্ধতি কল করার আগে SplitInitializer আবিষ্কার করে এবং আরম্ভ করে। ফলস্বরূপ, অ্যাপের প্রধান কার্যকলাপ শুরু হলে বিভক্ত নিয়মগুলি কার্যকর হয়৷

WindowManager API

আপনি মুষ্টিমেয় এপিআই কলের সাথে প্রোগ্রামে অ্যাক্টিভিটি এমবেডিং বাস্তবায়ন করতে পারেন। কোনো কার্যক্রম চালু হওয়ার আগে নিয়ম কার্যকর হয়েছে তা নিশ্চিত করতে Application একটি সাবক্লাসের onCreate() পদ্ধতিতে কল করুন।

প্রোগ্রাম্যাটিকভাবে একটি কার্যকলাপ বিভাজন তৈরি করতে, নিম্নলিখিতগুলি করুন:

  1. একটি বিভক্ত নিয়ম তৈরি করুন:

    1. একটি SplitPairFilter তৈরি করুন যা বিভাজন ভাগ করে এমন কার্যকলাপগুলি সনাক্ত করে:

      কোটলিন

      val splitPairFilter = SplitPairFilter(
         ComponentName(this, ListActivity::class.java),
         ComponentName(this, DetailActivity::class.java),
         null
      )

      জাভা

      SplitPairFilter splitPairFilter = new SplitPairFilter(
         new ComponentName(this, ListActivity.class),
         new ComponentName(this, DetailActivity.class),
         null
      );
    2. ফিল্টার সেটে ফিল্টার যোগ করুন:

      কোটলিন

      val filterSet = setOf(splitPairFilter)

      জাভা

      Set<SplitPairFilter> filterSet = new HashSet<>();
      filterSet.add(splitPairFilter);
    3. বিভাজনের জন্য লেআউট বৈশিষ্ট্য তৈরি করুন:

      কোটলিন

      val splitAttributes: SplitAttributes = SplitAttributes.Builder()
          .setSplitType(SplitAttributes.SplitType.ratio(0.33f))
          .setLayoutDirection(SplitAttributes.LayoutDirection.LEFT_TO_RIGHT)
          .build()

      জাভা

      final SplitAttributes splitAttributes = new SplitAttributes.Builder()
            .setSplitType(SplitAttributes.SplitType.ratio(0.33f))
            .setLayoutDirection(SplitAttributes.LayoutDirection.LEFT_TO_RIGHT)
            .build();

      SplitAttributes.Builder লেআউট বৈশিষ্ট্য ধারণকারী একটি বস্তু তৈরি করে:

      • setSplitType : প্রতিটি অ্যাক্টিভিটি কন্টেইনারে কিভাবে উপলব্ধ ডিসপ্লে এলাকা বরাদ্দ করা হয় তা নির্ধারণ করে। অনুপাত বিভক্ত প্রকার প্রাথমিক কন্টেইনারে বরাদ্দ উপলব্ধ প্রদর্শন এলাকার অনুপাত নির্দিষ্ট করে; মাধ্যমিক ধারকটি উপলব্ধ প্রদর্শন এলাকার অবশিষ্টাংশ দখল করে।
      • setLayoutDirection : কীভাবে অ্যাক্টিভিটি কন্টেইনারগুলি একে অপরের সাপেক্ষে, প্রাথমিক কন্টেইনার প্রথমে রাখা হয় তা নির্দিষ্ট করে।
    4. একটি SplitPairRule তৈরি করুন:

      কোটলিন

      val splitPairRule = SplitPairRule.Builder(filterSet)
          .setDefaultSplitAttributes(splitAttributes)
          .setMinWidthDp(840)
          .setMinSmallestWidthDp(600)
          .setMaxAspectRatioInPortrait(EmbeddingAspectRatio.ratio(1.5f))
          .setFinishPrimaryWithSecondary(SplitRule.FinishBehavior.NEVER)
          .setFinishSecondaryWithPrimary(SplitRule.FinishBehavior.ALWAYS)
          .setClearTop(false)
          .build()

      জাভা

      SplitPairRule splitPairRule = new SplitPairRule.Builder(filterSet)
          .setDefaultSplitAttributes(splitAttributes)
          .setMinWidthDp(840)
          .setMinSmallestWidthDp(600)
          .setMaxAspectRatioInPortrait(EmbeddingAspectRatio.ratio(1.5f))
          .setFinishPrimaryWithSecondary(SplitRule.FinishBehavior.NEVER)
          .setFinishSecondaryWithPrimary(SplitRule.FinishBehavior.ALWAYS)
          .setClearTop(false)
          .build();

      SplitPairRule.Builder নিয়মটি তৈরি করে এবং কনফিগার করে:

      • filterSet : বিভক্ত জোড়া ফিল্টার রয়েছে যা বিভাজন ভাগ করে এমন ক্রিয়াকলাপগুলি সনাক্ত করে নিয়মটি কখন প্রয়োগ করতে হবে তা নির্ধারণ করে।
      • setDefaultSplitAttributes : নিয়মে লেআউট বৈশিষ্ট্য প্রয়োগ করে।
      • setMinWidthDp : ন্যূনতম প্রদর্শন প্রস্থ সেট করে (ঘনত্ব-স্বাধীন পিক্সেলে, dp) যা একটি বিভাজন সক্ষম করে।
      • setMinSmallestWidthDp : ন্যূনতম মান সেট করে (dp-এ) যে দুটি ডিসপ্লে ডাইমেনশনের ছোট হলে ডিভাইসের অভিযোজন নির্বিশেষে একটি বিভাজন সক্ষম করতে হবে।
      • setMaxAspectRatioInPortrait : পোর্ট্রেট ওরিয়েন্টেশনে সর্বোচ্চ ডিসপ্লে অ্যাসপেক্ট রেশিও (উচ্চতা:প্রস্থ) সেট করে যার জন্য অ্যাক্টিভিটি স্প্লিট প্রদর্শিত হয়। যদি একটি প্রতিকৃতি প্রদর্শনের আকৃতির অনুপাত সর্বাধিক আকৃতির অনুপাতকে অতিক্রম করে, তবে প্রদর্শনের প্রস্থ নির্বিশেষে বিভক্তগুলি নিষ্ক্রিয় করা হয়৷ দ্রষ্টব্য: ডিফল্ট মান হল 1.4, যার ফলে বেশিরভাগ ট্যাবলেটে পোর্ট্রেট ওরিয়েন্টেশনে ক্রিয়াকলাপ পুরো টাস্ক উইন্ডো দখল করে। এছাড়াও SPLIT_MAX_ASPECT_RATIO_PORTRAIT_DEFAULT এবং setMaxAspectRatioInLandscape দেখুন। ল্যান্ডস্কেপের জন্য ডিফল্ট মান হল ALWAYS_ALLOW
      • setFinishPrimaryWithSecondary : সেকেন্ডারি কন্টেইনারে সমস্ত ক্রিয়াকলাপ শেষ করা প্রাথমিক কন্টেইনারের কার্যকলাপকে কীভাবে প্রভাবিত করে তা সেট করে। সেকেন্ডারি কন্টেইনারের সমস্ত ক্রিয়াকলাপ শেষ হয়ে গেলে সিস্টেমের প্রাথমিক ক্রিয়াকলাপগুলি শেষ করা উচিত নয় বলে NEVER নির্দেশ করে ( ফিনিশ কার্যক্রম দেখুন)।
      • setFinishSecondaryWithPrimary : প্রাথমিক কন্টেইনারে সমস্ত ক্রিয়াকলাপ শেষ করা সেকেন্ডারি কন্টেইনারের কার্যকলাপকে কীভাবে প্রভাবিত করে তা সেট করে। ALWAYS নির্দেশ করে যে সিস্টেমটি সর্বদা সেকেন্ডারি কন্টেইনারে ক্রিয়াকলাপগুলি শেষ করা উচিত যখন প্রাথমিক কন্টেইনারের সমস্ত ক্রিয়াকলাপ শেষ হয় ( ফিনিশ কার্যক্রম দেখুন)।
      • setClearTop : কন্টেইনারে একটি নতুন কার্যকলাপ চালু হলে সেকেন্ডারি কন্টেইনারের সমস্ত ক্রিয়াকলাপ শেষ হয় কিনা তা নির্দিষ্ট করে। False নির্দিষ্ট করে যে নতুন ক্রিয়াকলাপগুলি ইতিমধ্যেই সেকেন্ডারি কন্টেইনারে থাকা ক্রিয়াকলাপগুলির উপরে স্তুপীকৃত।
    5. WindowManager RuleController এর সিঙ্গলটন উদাহরণ পান এবং নিয়মটি যোগ করুন:

      কোটলিন

        val ruleController = RuleController.getInstance(this)
        ruleController.addRule(splitPairRule)
        

      জাভা

        RuleController ruleController = RuleController.getInstance(this);
        ruleController.addRule(splitPairRule);
        
  2. বিষয়বস্তু উপলব্ধ না হলে সেকেন্ডারি কন্টেইনারের জন্য একটি স্থানধারক তৈরি করুন:

    1. একটি ActivityFilter তৈরি করুন যা সেই অ্যাক্টিভিটি শনাক্ত করে যার সাথে প্লেসহোল্ডার একটি টাস্ক উইন্ডো স্প্লিট শেয়ার করে:

      কোটলিন

      val placeholderActivityFilter = ActivityFilter(
          ComponentName(this, ListActivity::class.java),
          null
      )

      জাভা

      ActivityFilter placeholderActivityFilter = new ActivityFilter(
          new ComponentName(this, ListActivity.class),
          null
      );
    2. ফিল্টার সেটে ফিল্টার যোগ করুন:

      কোটলিন

      val placeholderActivityFilterSet = setOf(placeholderActivityFilter)

      জাভা

      Set<ActivityFilter> placeholderActivityFilterSet = new HashSet<>();
      placeholderActivityFilterSet.add(placeholderActivityFilter);
    3. একটি SplitPlaceholderRule তৈরি করুন:

      কোটলিন

      val splitPlaceholderRule = SplitPlaceholderRule.Builder(
            placeholderActivityFilterSet,
            Intent(context, PlaceholderActivity::class.java)
          ).setDefaultSplitAttributes(splitAttributes)
           .setMinWidthDp(840)
           .setMinSmallestWidthDp(600)
           .setMaxAspectRatioInPortrait(EmbeddingAspectRatio.ratio(1.5f))
           .setFinishPrimaryWithPlaceholder(SplitRule.FinishBehavior.ALWAYS)
           .setSticky(false)
           .build()

      জাভা

      SplitPlaceholderRule splitPlaceholderRule = new SplitPlaceholderRule.Builder(
            placeholderActivityFilterSet,
            new Intent(context, PlaceholderActivity.class)
          ).setDefaultSplitAttributes(splitAttributes)
           .setMinWidthDp(840)
           .setMinSmallestWidthDp(600)
           .setMaxAspectRatioInPortrait(EmbeddingAspectRatio.ratio(1.5f))
           .setFinishPrimaryWithPlaceholder(SplitRule.FinishBehavior.ALWAYS)
           .setSticky(false)
           .build();

      SplitPlaceholderRule.Builder নিয়মটি তৈরি করে এবং কনফিগার করে:

      • placeholderActivityFilterSet : অ্যাক্টিভিটি ফিল্টার ধারণ করে যা নির্ধারণ করে যে কখন নিয়ম প্রয়োগ করতে হবে সেই ক্রিয়াকলাপগুলির সাথে স্থানধারক কার্যকলাপ জড়িত।
      • Intent : স্থানধারক কার্যকলাপের সূচনা নির্দিষ্ট করে।
      • setDefaultSplitAttributes : নিয়মে লেআউট বৈশিষ্ট্য প্রয়োগ করে।
      • setMinWidthDp : ন্যূনতম প্রদর্শন প্রস্থ (ঘনত্ব-স্বাধীন পিক্সেল, dp-এ) সেট করে যা একটি বিভাজনের অনুমতি দেয়।
      • setMinSmallestWidthDp : ন্যূনতম মান সেট করে (dp-এ) যে দুটি ডিসপ্লে ডাইমেনশনের মধ্যে ছোট হলে ডিভাইসের অভিযোজন নির্বিশেষে একটি বিভাজনের অনুমতি দিতে হবে।
      • setMaxAspectRatioInPortrait : পোর্ট্রেট ওরিয়েন্টেশনে সর্বোচ্চ ডিসপ্লে অ্যাসপেক্ট রেশিও (উচ্চতা:প্রস্থ) সেট করে যার জন্য অ্যাক্টিভিটি স্প্লিট প্রদর্শিত হয়। দ্রষ্টব্য: ডিফল্ট মান হল 1.4, যার ফলে বেশিরভাগ ট্যাবলেটে পোর্ট্রেট ওরিয়েন্টেশনে টাস্ক উইন্ডো পূরণ করা হয়৷ এছাড়াও SPLIT_MAX_ASPECT_RATIO_PORTRAIT_DEFAULT এবং setMaxAspectRatioInLandscape দেখুন। ল্যান্ডস্কেপের জন্য ডিফল্ট মান হল ALWAYS_ALLOW
      • setFinishPrimaryWithPlaceholder : প্লেসহোল্ডার অ্যাক্টিভিটি কিভাবে শেষ করা প্রাথমিক কন্টেইনারের কার্যকলাপকে প্রভাবিত করে তা সেট করে। সর্বদা নির্দেশ করে যে স্থানধারক শেষ হলে সিস্টেমটি সর্বদা প্রাথমিক কন্টেইনারে ক্রিয়াকলাপগুলি শেষ করবে ( ফিনিশ কার্যক্রম দেখুন)।
      • setSticky : প্লেসহোল্ডার প্রথমবার পর্যাপ্ত ন্যূনতম প্রস্থের সাথে একটি বিভাজনে প্রদর্শিত হলে ছোট ডিসপ্লেতে অ্যাক্টিভিটি স্ট্যাকের উপরে স্থানধারক কার্যকলাপ প্রদর্শিত হবে কিনা তা নির্ধারণ করে।
    4. WindowManager RuleController এ নিয়ম যোগ করুন:

      কোটলিন

      ruleController.addRule(splitPlaceholderRule)

      জাভা

      ruleController.addRule(splitPlaceholderRule);
  3. এমন ক্রিয়াকলাপগুলি নির্দিষ্ট করুন যা কখনই বিভাজনের অংশ হওয়া উচিত নয়:

    1. একটি ActivityFilter তৈরি করুন যা এমন একটি ক্রিয়াকলাপকে চিহ্নিত করে যা সর্বদা পুরো টাস্ক ডিসপ্লে এরিয়া দখল করবে:

      কোটলিন

      val expandedActivityFilter = ActivityFilter(
        ComponentName(this, ExpandedActivity::class.java),
        null
      )

      জাভা

      ActivityFilter expandedActivityFilter = new ActivityFilter(
        new ComponentName(this, ExpandedActivity.class),
        null
      );
    2. ফিল্টার সেটে ফিল্টার যোগ করুন:

      কোটলিন

      val expandedActivityFilterSet = setOf(expandedActivityFilter)

      জাভা

      Set<ActivityFilter> expandedActivityFilterSet = new HashSet<>();
      expandedActivityFilterSet.add(expandedActivityFilter);
    3. একটি ActivityRule তৈরি করুন:

      কোটলিন

      val activityRule = ActivityRule.Builder(expandedActivityFilterSet)
          .setAlwaysExpand(true)
          .build()

      জাভা

      ActivityRule activityRule = new ActivityRule.Builder(
          expandedActivityFilterSet
      ).setAlwaysExpand(true)
       .build();

      ActivityRule.Builder নিয়ম তৈরি করে এবং কনফিগার করে:

      • expandedActivityFilterSet : কার্যকলাপ ফিল্টার রয়েছে যা নির্ধারণ করে কখন নিয়ম প্রয়োগ করতে হবে এমন কার্যকলাপগুলি চিহ্নিত করে যা আপনি বিভক্ত থেকে বাদ দিতে চান।
      • setAlwaysExpand : কার্যকলাপটি সম্পূর্ণ টাস্ক উইন্ডোটি পূরণ করবে কিনা তা নির্দিষ্ট করে।
    4. WindowManager RuleController এ নিয়ম যোগ করুন:

      কোটলিন

      ruleController.addRule(activityRule)

      জাভা

      ruleController.addRule(activityRule);

ক্রস-অ্যাপ্লিকেশন এমবেডিং

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

উদাহরণস্বরূপ, সেটিংস অ্যাপ WallpaperPicker অ্যাপ থেকে ওয়ালপেপার নির্বাচক কার্যকলাপ এম্বেড করতে পারে:

চিত্র 14. এম্বেড করা কার্যকলাপ (ডানদিকে) হিসাবে ওয়ালপেপার নির্বাচক সহ সেটিংস অ্যাপ (বামে মেনু)।

ট্রাস্ট মডেল

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

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

বিশ্বস্ত হোস্ট

অন্যান্য অ্যাপ্লিকেশানগুলিকে আপনার অ্যাপ্লিকেশান থেকে অ্যাক্টিভিটিগুলির উপস্থাপনাকে এম্বেড করতে এবং সম্পূর্ণরূপে নিয়ন্ত্রণ করার অনুমতি দিতে, আপনার অ্যাপের ম্যানিফেস্ট ফাইলের <activity> বা <application> উপাদানগুলির android:knownActivityEmbeddingCerts অ্যাট্রিবিউটে হোস্ট অ্যাপ্লিকেশনের SHA-256 শংসাপত্র নির্দিষ্ট করুন।

একটি স্ট্রিং হিসাবে android:knownActivityEmbeddingCerts এর মান সেট করুন:

<activity
    android:name=".MyEmbeddableActivity"
    android:knownActivityEmbeddingCerts="@string/known_host_certificate_digest"
    ... />

অথবা, একাধিক শংসাপত্র নির্দিষ্ট করতে, স্ট্রিংয়ের একটি অ্যারে:

<activity
    android:name=".MyEmbeddableActivity"
    android:knownActivityEmbeddingCerts="@array/known_host_certificate_digests"
    ... />

যা নিম্নলিখিত মত একটি সম্পদ উল্লেখ করে:

<resources>
    <string-array name="known_host_certificate_digests">
      <item>cert1</item>
      <item>cert2</item>
      ...
    </string-array>
</resources>

App মালিকরা Gradle signingReport টাস্ক চালিয়ে SHA সার্টিফিকেট ডাইজেস্ট পেতে পারেন। সার্টিফিকেট ডাইজেস্ট হল SHA-256 আঙ্গুলের ছাপ বিচ্ছিন্ন কোলন ছাড়া। আরও তথ্যের জন্য, একটি স্বাক্ষর প্রতিবেদন চালান এবং আপনার ক্লায়েন্ট প্রমাণীকরণ দেখুন।

অবিশ্বস্ত হোস্ট

যেকোনো অ্যাপকে আপনার অ্যাপের ক্রিয়াকলাপ এম্বেড করতে এবং তাদের উপস্থাপনা নিয়ন্ত্রণ করার অনুমতি দিতে, অ্যাপ ম্যানিফেস্টে <activity> বা <application> উপাদানগুলিতে android:allowUntrustedActivityEmbedding বৈশিষ্ট্যটি নির্দিষ্ট করুন, উদাহরণস্বরূপ:

<activity
    android:name=".MyEmbeddableActivity"
    android:allowUntrustedActivityEmbedding="true"
    ... />

অ্যাট্রিবিউটের ডিফল্ট মান মিথ্যা, যা ক্রস-অ্যাপ কার্যকলাপ এম্বেডিং প্রতিরোধ করে।

কাস্টম প্রমাণীকরণ

অবিশ্বস্ত কার্যকলাপ এম্বেডিংয়ের ঝুঁকি কমাতে, একটি কাস্টম প্রমাণীকরণ প্রক্রিয়া তৈরি করুন যা হোস্টের পরিচয় যাচাই করে। আপনি যদি হোস্ট শংসাপত্রগুলি জানেন তবে প্রমাণীকরণের জন্য androidx.security.app.authenticator লাইব্রেরি ব্যবহার করুন৷ যদি হোস্ট আপনার কার্যকলাপ এম্বেড করার পরে প্রমাণীকরণ করে, আপনি প্রকৃত বিষয়বস্তু প্রদর্শন করতে পারেন। যদি তা না হয়, আপনি ব্যবহারকারীকে জানাতে পারেন যে ক্রিয়াটি অনুমোদিত নয় এবং সামগ্রীটি ব্লক করুন৷

একটি হোস্ট আপনার কার্যকলাপ এম্বেড করছে কিনা তা পরীক্ষা করতে Jetpack WindowManager লাইব্রেরি থেকে ActivityEmbeddingController#isActivityEmbedded() পদ্ধতি ব্যবহার করুন, উদাহরণস্বরূপ:

কোটলিন

fun isActivityEmbedded(activity: Activity): Boolean {
    return ActivityEmbeddingController.getInstance(this).isActivityEmbedded(activity)
}

জাভা

boolean isActivityEmbedded(Activity activity) {
    return ActivityEmbeddingController.getInstance(this).isActivityEmbedded(activity);
}

ন্যূনতম আকারের সীমাবদ্ধতা

অ্যান্ড্রয়েড সিস্টেম এমবেড করা ক্রিয়াকলাপগুলিতে অ্যাপ ম্যানিফেস্ট <layout> উপাদানে নির্দিষ্ট ন্যূনতম উচ্চতা এবং প্রস্থ প্রয়োগ করে। যদি একটি অ্যাপ্লিকেশন ন্যূনতম উচ্চতা এবং প্রস্থ নির্দিষ্ট না করে, তবে সিস্টেমের ডিফল্ট মান প্রযোজ্য হবে ( sw220dp )।

যদি হোস্ট এমবেডেড কন্টেইনারটিকে ন্যূনতম থেকে ছোট আকারে আকার পরিবর্তন করার চেষ্টা করে, এমবেডেড ধারকটি সম্পূর্ণ টাস্ক বাউন্ড দখল করতে প্রসারিত হয়।

<ক্রিয়াকলাপ-উনাম>

<activity-alias> উপাদানের সাথে কাজ করার জন্য বিশ্বস্ত বা অবিশ্বস্ত কার্যকলাপ এম্বেডিংয়ের জন্য, android:knownActivityEmbeddingCerts বা android:allowUntrustedActivityEmbedding উপনামের পরিবর্তে লক্ষ্য কার্যকলাপে প্রয়োগ করতে হবে। যে নীতি সিস্টেম সার্ভারে নিরাপত্তা যাচাই করে তা লক্ষ্যের উপর সেট করা পতাকার উপর ভিত্তি করে, উপনাম নয়।

হোস্ট অ্যাপ্লিকেশন

হোস্ট অ্যাপ্লিকেশনগুলি ক্রস-অ্যাপ অ্যাক্টিভিটি এমবেডিং প্রয়োগ করে যেভাবে তারা একক-অ্যাপ অ্যাক্টিভিটি এমবেডিং প্রয়োগ করে। SplitPairRule এবং SplitPairFilter বা ActivityRule এবং ActivityFilter অবজেক্ট এমবেড করা কার্যকলাপ এবং টাস্ক উইন্ডো বিভাজন নির্দিষ্ট করে। জেটপ্যাক উইন্ডো ম্যানেজার API কল ব্যবহার করে XML-এ বা রানটাইমে স্প্লিট নিয়মগুলি স্থিরভাবে সংজ্ঞায়িত করা হয়।

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

যদি কোনো এমবেডেড অ্যাক্টিভিটি একই টাস্কে একটি নতুন অ্যাক্টিভিটি শুরু করে এবং নতুন অ্যাক্টিভিটি ক্রস-অ্যাপ এম্বেডিং বেছে না নেয়, তাহলে অ্যাক্টিভিটিটি এমবেডেড কন্টেইনারে অ্যাক্টিভিটি ওভারলে করার পরিবর্তে পুরো টাস্ক বাউন্ড দখল করে।

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

বিভক্ত উদাহরণ

সম্পূর্ণ উইন্ডো থেকে বিভক্ত

চিত্র 15. কার্যকলাপ A পাশ থেকে B কার্যকলাপ শুরু করে।

কোন রিফ্যাক্টরিং এর প্রয়োজন নেই। আপনি স্থিরভাবে বা রানটাইমে স্প্লিটের জন্য কনফিগারেশন সংজ্ঞায়িত করতে পারেন এবং তারপরে কোনো অতিরিক্ত প্যারামিটার ছাড়াই Context#startActivity() কল করতে পারেন।

<SplitPairRule>
    <SplitPairFilter
        window:primaryActivityName=".A"
        window:secondaryActivityName=".B"/>
</SplitPairRule>

ডিফল্টরূপে বিভক্ত

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

চিত্র 16. একই সাথে দুটি ক্রিয়াকলাপ খোলার মাধ্যমে বিভক্ত করা হয়েছে। একটি কার্যকলাপ একটি স্থানধারক.

একটি স্থানধারকের সাথে একটি বিভাজন তৈরি করতে, একটি স্থানধারক তৈরি করুন এবং এটিকে প্রাথমিক কার্যকলাপের সাথে সংযুক্ত করুন:

<SplitPlaceholderRule
    window:placeholderActivityName=".PlaceholderActivity">
    <ActivityFilter
        window:activityName=".MainActivity"/>
</SplitPlaceholderRule>

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

চিত্র 17. গভীর লিঙ্ক বিস্তারিত কার্যকলাপ একটি ছোট পর্দায় একা দেখানো হয়েছে, কিন্তু একটি বড় পর্দায় একটি তালিকা কার্যকলাপ সহ।

লঞ্চের অনুরোধটি মূল ক্রিয়াকলাপে রুট করা উচিত এবং লক্ষ্য বিস্তারিত ক্রিয়াকলাপটি একটি বিভাজনে চালু করা উচিত। সিস্টেম স্বয়ংক্রিয়ভাবে উপলব্ধ প্রদর্শন প্রস্থের উপর ভিত্তি করে সঠিক উপস্থাপনা - স্তুপীকৃত বা পাশাপাশি - নির্বাচন করে।

কোটলিন

override fun onCreate(savedInstanceState Bundle?) {
    . . .
    RuleController.getInstance(this)
        .addRule(SplitPairRule.Builder(filterSet).build())
    startActivity(Intent(this, DetailActivity::class.java))
}

জাভা

@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
    . . .
    RuleController.getInstance(this)
        .addRule(new SplitPairRule.Builder(filterSet).build());
    startActivity(new Intent(this, DetailActivity.class));
}

ডিপ লিঙ্ক গন্তব্য হতে পারে একমাত্র কার্যকলাপ যা ব্যবহারকারীর কাছে ব্যাক নেভিগেশন স্ট্যাকে উপলব্ধ হওয়া উচিত, এবং আপনি বিস্তারিত ক্রিয়াকলাপ খারিজ করা এবং শুধুমাত্র প্রধান ক্রিয়াকলাপ ত্যাগ করা এড়াতে চাইতে পারেন:

তালিকা কার্যকলাপ এবং বিস্তারিত কার্যকলাপ পাশাপাশি বড় প্রদর্শন.           পিছনে নেভিগেশন বিস্তারিত কার্যকলাপ খারিজ এবং পর্দায় তালিকা কার্যকলাপ ছেড়ে দিতে অক্ষম.

শুধুমাত্র বিস্তারিত কার্যকলাপ সহ ছোট প্রদর্শন. পিছনে নেভিগেশন বিস্তারিত কার্যকলাপ খারিজ এবং তালিকা কার্যকলাপ প্রকাশ করতে অক্ষম.

পরিবর্তে, আপনি finishPrimaryWithSecondary বৈশিষ্ট্য ব্যবহার করে একই সময়ে উভয় কার্যক্রম শেষ করতে পারেন:

<SplitPairRule
    window:finishPrimaryWithSecondary="always">
    <SplitPairFilter
        window:primaryActivityName=".ListActivity"
        window:secondaryActivityName=".DetailActivity"/>
</SplitPairRule>

কনফিগারেশন বৈশিষ্ট্য বিভাগ দেখুন।

বিভক্ত পাত্রে একাধিক কার্যক্রম

একটি বিভক্ত পাত্রে একাধিক ক্রিয়াকলাপ স্ট্যাক করা ব্যবহারকারীদের গভীর সামগ্রী অ্যাক্সেস করতে সক্ষম করে। উদাহরণস্বরূপ, একটি তালিকা-বিশদ বিভাজনের সাথে, ব্যবহারকারীকে একটি সাব-বিশদ বিভাগে যেতে হতে পারে তবে প্রাথমিক কার্যকলাপটি জায়গায় রাখতে হবে:

চিত্র 18. টাস্ক উইন্ডোর সেকেন্ডারি প্যানে জায়গায় ক্রিয়াকলাপ খোলা হয়েছে।

কোটলিন

class DetailActivity {
    . . .
    fun onOpenSubDetail() {
      startActivity(Intent(this, SubDetailActivity::class.java))
    }
}

জাভা

public class DetailActivity {
    . . .
    void onOpenSubDetail() {
        startActivity(new Intent(this, SubDetailActivity.class));
    }
}

উপ-বিস্তারিত কার্যকলাপ বিস্তারিত কার্যকলাপের উপরে স্থাপন করা হয়, এটি গোপন করে:

ব্যবহারকারী স্ট্যাকের মাধ্যমে ফিরে নেভিগেট করে পূর্ববর্তী বিশদ স্তরে ফিরে যেতে পারেন:

চিত্র 19. স্ট্যাকের শীর্ষ থেকে কার্যকলাপ সরানো হয়েছে৷

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

একটি নতুন কাজে কার্যকলাপ

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

চিত্র 20. B কার্যকলাপ থেকে একটি নতুন টাস্কে কার্যকলাপ C শুরু করুন।

কার্যকলাপ প্রতিস্থাপন

ক্রিয়াকলাপগুলি সেকেন্ডারি কন্টেইনার স্ট্যাকের মধ্যে প্রতিস্থাপিত করা যেতে পারে; উদাহরণস্বরূপ, যখন প্রাথমিক ক্রিয়াকলাপটি উচ্চ-স্তরের নেভিগেশনের জন্য ব্যবহৃত হয় এবং দ্বিতীয় ক্রিয়াকলাপটি একটি নির্বাচিত গন্তব্য। শীর্ষ-স্তরের নেভিগেশন থেকে প্রতিটি নির্বাচনকে সেকেন্ডারি কন্টেইনারে একটি নতুন কার্যকলাপ শুরু করা উচিত এবং পূর্বে সেখানে থাকা কার্যকলাপ বা কার্যকলাপগুলিকে সরিয়ে দেওয়া উচিত।

চিত্র 21. প্রাথমিক প্যানে শীর্ষ-স্তরের নেভিগেশন কার্যকলাপ গৌণ ফলকে গন্তব্য কার্যকলাপ প্রতিস্থাপন করে।

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

এই ধরনের ক্ষেত্রে স্ক্রীন A অবশ্যই ব্যাক স্ট্যাক থেকে সরিয়ে ফেলতে হবে।

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

<SplitPairRule
    window:clearTop="true">
    <SplitPairFilter
        window:primaryActivityName=".Menu"
        window:secondaryActivityName=".ScreenA"/>
    <SplitPairFilter
        window:primaryActivityName=".Menu"
        window:secondaryActivityName=".ScreenB"/>
</SplitPairRule>

কোটলিন

class MenuActivity {
    . . .
    fun onMenuItemSelected(selectedMenuItem: Int) {
        startActivity(Intent(this, classForItem(selectedMenuItem)))
    }
}

জাভা

public class MenuActivity {
    . . .
    void onMenuItemSelected(int selectedMenuItem) {
        startActivity(new Intent(this, classForItem(selectedMenuItem)));
    }
}

বিকল্পভাবে, একই সেকেন্ডারি অ্যাক্টিভিটি ব্যবহার করুন এবং প্রাথমিক (মেনু) অ্যাক্টিভিটি থেকে নতুন ইন্টেন্ট পাঠান যা একই উদাহরণে সমাধান করে কিন্তু সেকেন্ডারি কন্টেইনারে একটি স্টেট বা UI আপডেট ট্রিগার করে।

একাধিক বিভাজন

অ্যাপ্লিকেশানগুলি পাশে অতিরিক্ত কার্যকলাপ চালু করে বহু-স্তরের গভীর নেভিগেশন প্রদান করতে পারে।

যখন একটি মাধ্যমিক পাত্রে একটি কার্যকলাপ পাশে একটি নতুন কার্যকলাপ চালু করে, তখন বিদ্যমান বিভাজনের উপরে একটি নতুন স্প্লিট তৈরি হয়।

চিত্র 22. কার্যকলাপ B পাশ থেকে C কার্যকলাপ শুরু করে।

ব্যাক স্ট্যাকটিতে পূর্বে খোলা সমস্ত ক্রিয়াকলাপ রয়েছে, যাতে ব্যবহারকারীরা C শেষ করার পরে A/B বিভাজনে নেভিগেট করতে পারে।

একটি স্ট্যাকে A, B, এবং C কার্যক্রম। ক্রিয়াকলাপগুলি উপরে থেকে নীচের ক্রমানুসারে স্ট্যাক করা হয়েছে: C, B, A।

একটি নতুন বিভাজন তৈরি করতে, বিদ্যমান সেকেন্ডারি কন্টেইনার থেকে পাশের দিকে নতুন কার্যকলাপ চালু করুন। এ/বি এবং বি/সি উভয়ের জন্য কনফিগারেশনগুলি ঘোষণা করুন এবং বি থেকে সাধারণত ক্রিয়াকলাপ সি চালু করুন:

<SplitPairRule>
    <SplitPairFilter
        window:primaryActivityName=".A"
        window:secondaryActivityName=".B"/>
    <SplitPairFilter
        window:primaryActivityName=".B"
        window:secondaryActivityName=".C"/>
</SplitPairRule>

কোটলিন

class B {
    . . .
    fun onOpenC() {
        startActivity(Intent(this, C::class.java))
    }
}

জাভা

public class B {
    . . .
    void onOpenC() {
        startActivity(new Intent(this, C.class));
    }
}

বিভক্ত রাষ্ট্রের পরিবর্তনগুলিতে প্রতিক্রিয়া জানান

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

চিত্র 23। কার্যত অভিন্ন ইউআই উপাদানগুলির সাথে বিভিন্ন ক্রিয়াকলাপ।

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

চিত্র 24। ক্রিয়াকলাপ বিভক্তিতে সদৃশ ইউআই উপাদানগুলি।

ক্রিয়াকলাপগুলি যখন বিভক্ত হয় তখন তা জানতে, SplitController.splitInfoList পরীক্ষা করে দেখুন splitynflist প্রবাহ বা বিভক্ত অবস্থার পরিবর্তনের জন্য SplitControllerCallbackAdapter সাথে শ্রোতাদের নিবন্ধ করুন। তারপরে, সেই অনুযায়ী ইউআই সামঞ্জস্য করুন:

কোটলিন

val layout = layoutInflater.inflate(R.layout.activity_main, null)
val view = layout.findViewById<View>(R.id.infoButton)
lifecycleScope.launch {
    lifecycle.repeatOnLifecycle(Lifecycle.State.STARTED) {
        splitController.splitInfoList(this@SplitDeviceActivity) // The activity instance.
            .collect { list ->
                view.visibility = if (list.isEmpty()) View.VISIBLE else View.GONE
            }
    }
}

জাভা

@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
    . . .
    new SplitControllerCallbackAdapter(SplitController.getInstance(this))
        .addSplitListener(
            this,
            Runnable::run,
            splitInfoList -> {
                View layout = getLayoutInflater().inflate(R.layout.activity_main, null);
                layout.findViewById(R.id.infoButton).setVisibility(
                    splitInfoList.isEmpty() ? View.VISIBLE : View.GONE);
            });
}

করুটাইনগুলি যে কোনও লাইফসাইকেল অবস্থায় চালু করা যেতে পারে, তবে সাধারণত সংস্থান সংরক্ষণের জন্য STARTED চালু করা হয় (আরও তথ্যের জন্য লাইফসাইকেল-সচেতন উপাদানগুলির সাথে কোটলিন করুটাইনগুলি ব্যবহার করুন ) দেখুন।

কোনও ক্রিয়াকলাপ বন্ধ হয়ে গেলে যে কোনও লাইফসাইকেল অবস্থায় কলব্যাকগুলি করা যেতে পারে। শ্রোতাদের সাধারণত onStart() এ নিবন্ধিত হওয়া উচিত এবং onStop() এ নিবন্ধভুক্ত করা উচিত।

ফুল-উইন্ডো মডেল

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

একটি ক্রিয়াকলাপটি এক্সপেন্ড কনফিগারেশনটি ব্যবহার করে সর্বদা টাস্ক উইন্ডোটি পূরণ করতে বাধ্য করা যেতে পারে:

<ActivityRule
    window:alwaysExpand="true">
    <ActivityFilter
        window:activityName=".FullWidthActivity"/>
</ActivityRule>

ক্রিয়াকলাপ শেষ

ব্যবহারকারীরা ডিসপ্লেটির প্রান্ত থেকে সোয়াইপ করে বিভাজনের উভয় পাশে ক্রিয়াকলাপ শেষ করতে পারেন:

চিত্র 25. সোয়াইপ অঙ্গভঙ্গি সমাপ্তি ক্রিয়াকলাপ বি।
চিত্র 26. সোয়াইপ অঙ্গভঙ্গি সমাপ্তি ক্রিয়াকলাপ এ।

যদি ডিভাইস নেভিগেশনের পরিবর্তে পিছনের বোতামটি ব্যবহার করতে ডিভাইসটি সেট আপ করা হয় তবে ইনপুটটি ফোকাসযুক্ত ক্রিয়াকলাপে প্রেরণ করা হয় - এমন ক্রিয়াকলাপ যা ছোঁয়া বা সর্বশেষ চালু করা হয়েছিল।

কোনও ধারকটিতে সমস্ত ক্রিয়াকলাপ সমাপ্ত করার প্রভাবটি বিরোধী পাত্রে রয়েছে তা বিভক্ত কনফিগারেশনের উপর নির্ভর করে।

কনফিগারেশন বৈশিষ্ট্য

বিভক্তির একপাশে সমস্ত ক্রিয়াকলাপ কীভাবে শেষ করা বিভাজনের অন্য পাশের ক্রিয়াকলাপগুলিকে প্রভাবিত করে তা কনফিগার করতে আপনি বিভক্ত জোড় নিয়মের বৈশিষ্ট্যগুলি নির্দিষ্ট করতে পারেন। গুণাবলী হল:

  • window:finishPrimaryWithSecondary - মাধ্যমিক ধারকটিতে সমস্ত ক্রিয়াকলাপ কীভাবে শেষ করা প্রাথমিক ধারকটির ক্রিয়াকলাপগুলিকে প্রভাবিত করে
  • window:finishSecondaryWithPrimary - প্রাথমিক ধারকটিতে সমস্ত ক্রিয়াকলাপ কীভাবে শেষ করা গৌণ ধারকটির ক্রিয়াকলাপগুলিকে প্রভাবিত করে

বৈশিষ্ট্যগুলির সম্ভাব্য মানগুলির মধ্যে রয়েছে:

  • always - সর্বদা সম্পর্কিত পাত্রে ক্রিয়াকলাপগুলি শেষ করুন
  • never - সম্পর্কিত পাত্রে ক্রিয়াকলাপ শেষ করবেন না
  • adjacent - দুটি পাত্রে একে অপরের সংলগ্ন প্রদর্শিত হলে সম্পর্কিত পাত্রে ক্রিয়াকলাপগুলি শেষ করুন, তবে দুটি পাত্রে স্ট্যাক করা থাকলে নয়

যেমন:

<SplitPairRule
    &lt;!-- Do not finish primary container activities when all secondary container activities finish. --&gt;
    window:finishPrimaryWithSecondary="never"
    &lt;!-- Finish secondary container activities when all primary container activities finish. --&gt;
    window:finishSecondaryWithPrimary="always">
    <SplitPairFilter
        window:primaryActivityName=".A"
        window:secondaryActivityName=".B"/>
</SplitPairRule>

ডিফল্ট কনফিগারেশন

যখন বিভক্ত সমাপ্তির এক পাত্রে সমস্ত ক্রিয়াকলাপ হয়, তখন বাকী ধারকটি পুরো উইন্ডোটি দখল করে:

<SplitPairRule>
    <SplitPairFilter
        window:primaryActivityName=".A"
        window:secondaryActivityName=".B"/>
</SplitPairRule>

ক্রিয়াকলাপ এ এবং বি এ রয়েছে এমন বিভাজন সমাপ্ত হয়েছে, পুরো উইন্ডোটি দখল করতে বি ছেড়ে।

ক্রিয়াকলাপ এ এবং বি বি সমন্বিত স্প্লিট সমাপ্ত হয়েছে, পুরো উইন্ডোটি দখল করতে একটি রেখে।

একসাথে ক্রিয়াকলাপ শেষ করুন

গৌণ ধারক সমাপ্তির সমস্ত ক্রিয়াকলাপ স্বয়ংক্রিয়ভাবে প্রাথমিক ধারকটিতে ক্রিয়াকলাপগুলি শেষ করুন:

<SplitPairRule
    window:finishPrimaryWithSecondary="always">
    <SplitPairFilter
        window:primaryActivityName=".A"
        window:secondaryActivityName=".B"/>
</SplitPairRule>

ক্রিয়াকলাপ এ এবং বি বি সমন্বিত বিভক্ত হয়ে গেছে, যা টাস্ক উইন্ডোটি খালি রেখে এও শেষ করে।

ক্রিয়াকলাপ এ এবং বি এ সহ বিভক্ত বিভক্ত হয়ে গেছে, টাস্ক উইন্ডোতে বি একা রেখে।

প্রাথমিক ধারক সমাপ্তির সমস্ত ক্রিয়াকলাপ যখন স্বয়ংক্রিয়ভাবে মাধ্যমিক ধারকটিতে ক্রিয়াকলাপগুলি শেষ করুন:

<SplitPairRule
    window:finishSecondaryWithPrimary="always">
    <SplitPairFilter
        window:primaryActivityName=".A"
        window:secondaryActivityName=".B"/>
</SplitPairRule>

ক্রিয়াকলাপ এ এবং বি এ রয়েছে এমন বিভাজন সমাপ্ত, যা টাস্ক উইন্ডোটি খালি রেখে বিও শেষ করে।

ক্রিয়াকলাপ এ এবং বি বি সমন্বিত স্প্লিট সমাপ্ত, টাস্ক উইন্ডোতে একা রেখে।

প্রাথমিক বা গৌণ ধারক সমাপ্তিতে সমস্ত ক্রিয়াকলাপ শেষ হলে একসাথে ক্রিয়াকলাপ শেষ করুন:

<SplitPairRule
    window:finishPrimaryWithSecondary="always"
    window:finishSecondaryWithPrimary="always">
    <SplitPairFilter
        window:primaryActivityName=".A"
        window:secondaryActivityName=".B"/>
</SplitPairRule>

ক্রিয়াকলাপ এ এবং বি এ রয়েছে এমন বিভাজন সমাপ্ত, যা টাস্ক উইন্ডোটি খালি রেখে বিও শেষ করে।

ক্রিয়াকলাপ এ এবং বি বি সমন্বিত বিভক্ত হয়ে গেছে, যা টাস্ক উইন্ডোটি খালি রেখে এও শেষ করে।

পাত্রে একাধিক ক্রিয়াকলাপ শেষ করুন

যদি একাধিক ক্রিয়াকলাপ একটি বিভক্ত পাত্রে স্ট্যাক করা হয় তবে স্ট্যাকের নীচে কোনও ক্রিয়াকলাপ শেষ করা স্বয়ংক্রিয়ভাবে শীর্ষে ক্রিয়াকলাপগুলি শেষ করে না।

উদাহরণস্বরূপ, যদি দুটি ক্রিয়াকলাপ মাধ্যমিক পাত্রে থাকে তবে বি এর শীর্ষে সি:

ক্রিয়াকলাপযুক্ত ক্রিয়াকলাপ স্ট্যাক সি এর শীর্ষে স্ট্যাক করা ক্রিয়াকলাপ স্ট্যাকের শীর্ষে স্ট্যাক করা হয়েছে ক্রিয়াকলাপ এ।

এবং বিভক্তির কনফিগারেশনটি A এবং B এর ক্রিয়াকলাপের কনফিগারেশন দ্বারা সংজ্ঞায়িত করা হয়:

<SplitPairRule>
    <SplitPairFilter
        window:primaryActivityName=".A"
        window:secondaryActivityName=".B"/>
</SplitPairRule>

শীর্ষ কার্যকলাপ শেষ করা বিভাজনকে ধরে রাখে।

ক্রিয়াকলাপের সাথে বিভক্ত এবং প্রাথমিক ধারক এ বি এবং সি গৌণ, সি, সি এর শীর্ষে স্ট্যাক করা হয়েছে, ক্রিয়াকলাপ বিভক্তিতে এ এবং বি রেখে।

মাধ্যমিক ধারকটির নীচের (মূল) ক্রিয়াকলাপ শেষ করা এর শীর্ষে ক্রিয়াকলাপগুলি সরিয়ে দেয় না; এবং তাই, বিভাজনও ধরে রাখে।

ক্রিয়াকলাপের সাথে বিভক্ত এবং প্রাথমিক ধারক এ বি এবং সি গৌণ, সি, সি বি এর শীর্ষে সজ্জিত, ক্রিয়াকলাপ বিভক্তিতে এ এবং সি রেখে।

একসাথে ক্রিয়াকলাপ শেষ করার জন্য যে কোনও অতিরিক্ত নিয়ম যেমন প্রাথমিকের সাথে মাধ্যমিক ক্রিয়াকলাপ শেষ করাও কার্যকর করা হয়:

<SplitPairRule
    window:finishSecondaryWithPrimary="always">
    <SplitPairFilter
        window:primaryActivityName=".A"
        window:secondaryActivityName=".B"/>
</SplitPairRule>

প্রাথমিক ধারক এবং ক্রিয়াকলাপে ক্রিয়াকলাপের সাথে বিভক্ত করুন এবং গৌণ ধারকটিতে বি এবং সি, সি বি এর উপরে স্ট্যাক করা হয়েছে, বি এবং সি সমাপ্তি

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

<SplitPairRule
    window:finishPrimaryWithSecondary="always"
    window:finishSecondaryWithPrimary="always">
    <SplitPairFilter
        window:primaryActivityName=".A"
        window:secondaryActivityName=".B"/>
</SplitPairRule>

ক্রিয়াকলাপের সাথে বিভক্ত করুন এবং প্রাথমিক ধারক এ বি এবং সি গৌণ, সি, সি এর শীর্ষে স্ট্যাক করা হয়েছে, ক্রিয়াকলাপ বিভক্তিতে এ এবং বি রেখে।

ক্রিয়াকলাপের সাথে বিভক্ত এবং প্রাথমিক ধারক এ বি এবং সি গৌণ, সি, সি বি এর শীর্ষে সজ্জিত, ক্রিয়াকলাপ বিভক্তিতে এ এবং সি রেখে।

প্রাথমিক ধারক এবং ক্রিয়াকলাপে ক্রিয়াকলাপের সাথে বিভক্ত করুন এবং বি এবং সি মাধ্যমিক, সি বি এর শীর্ষে সজ্জিত একটি সমাপ্তি, বি এবং সি সমাপ্তি

রানটাইমে বিভক্ত বৈশিষ্ট্য পরিবর্তন করুন

একটি সক্রিয় এবং দৃশ্যমান বিভক্তির বৈশিষ্ট্যগুলি পরিবর্তন করা যায় না। বিভক্ত নিয়মগুলি পরিবর্তন করা অতিরিক্ত ক্রিয়াকলাপ লঞ্চ এবং নতুন পাত্রে প্রভাবিত করে তবে বিদ্যমান এবং সক্রিয় বিভাজন নয়।

সক্রিয় বিভাজনের বৈশিষ্ট্যগুলি পরিবর্তন করতে, বিভক্তিতে পার্শ্ব ক্রিয়াকলাপ বা ক্রিয়াকলাপগুলি শেষ করুন এবং একটি নতুন কনফিগারেশন সহ আবার পাশে চালু করুন।

একটি বিভক্ত থেকে সম্পূর্ণ উইন্ডোতে একটি ক্রিয়াকলাপ বের করুন

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

রানটাইমে স্প্লিট সাপোর্টের জন্য পরীক্ষা করুন

ক্রিয়াকলাপ এম্বেডিং অ্যান্ড্রয়েড 12 এল (এপিআই স্তর 32) এবং উচ্চতরগুলিতে সমর্থিত, তবে এটি পূর্ববর্তী প্ল্যাটফর্ম সংস্করণগুলি চলমান কিছু ডিভাইসেও উপলব্ধ। বৈশিষ্ট্যটির প্রাপ্যতার জন্য রানটাইম চেক করতে, SplitController.splitSupportStatus প্রপার্টি বা SplitController.getSplitSupportStatus() পদ্ধতি ব্যবহার করুন:

কোটলিন

if (SplitController.getInstance(this).splitSupportStatus ==
     SplitController.SplitSupportStatus.SPLIT_AVAILABLE) {
     // Device supports split activity features.
}

জাভা

if (SplitController.getInstance(this).getSplitSupportStatus() ==
     SplitController.SplitSupportStatus.SPLIT_AVAILABLE) {
     // Device supports split activity features.
}

যদি বিভাজনগুলি সমর্থন না করা হয় তবে ক্রিয়াকলাপ স্ট্যাকের শীর্ষে ক্রিয়াকলাপগুলি চালু করা হয় (অ-অ্যাক্টিভিটি এম্বেডিং মডেল অনুসরণ করে)।

সিস্টেম ওভাররাইড প্রতিরোধ করুন

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

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

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

<manifest xmlns:android="http://schemas.android.com/apk/res/android">
    <application>
        <property
            android:name="android.window.PROPERTY_ACTIVITY_EMBEDDING_ALLOW_SYSTEM_OVERRIDE"
            android:value="true|false" />
    </application>
</manifest>

সম্পত্তির নামটি জেটপ্যাক উইন্ডো ম্যানেজার উইন্ডোপ্রোপার্টি অবজেক্টে সংজ্ঞায়িত করা হয়েছে। যদি আপনার অ্যাপ্লিকেশন ক্রিয়াকলাপ এম্বেডিং প্রয়োগ করে বা আপনি যদি অন্যথায় সিস্টেমটিকে আপনার অ্যাপ্লিকেশনটিতে এম্বেডিং বিধি প্রয়োগ করতে বাধা দিতে চান তবে তা false মান সেট করুন। আপনার অ্যাপ্লিকেশনটিতে সিস্টেম-সংজ্ঞায়িত ক্রিয়াকলাপ এম্বেডিং প্রয়োগ করার জন্য সিস্টেমকে অনুমতি দেওয়ার জন্য true মানটি সেট করুন।

সীমাবদ্ধতা, বিধিনিষেধ এবং সতর্কতা

  • টাস্কের মূল ক্রিয়াকলাপের মালিক হিসাবে চিহ্নিত কেবলমাত্র টাস্কের হোস্ট অ্যাপ্লিকেশনটি টাস্কে অন্যান্য ক্রিয়াকলাপগুলি সংগঠিত করতে এবং এম্বেড করতে পারে। এম্বেডিং এবং বিভাজনকে সমর্থন করে এমন ক্রিয়াকলাপগুলি যদি কোনও ভিন্ন অ্যাপ্লিকেশন সম্পর্কিত কোনও কার্যক্রমে চালিত হয়, তবে এম্বেডিং এবং বিভাজনগুলি সেই ক্রিয়াকলাপগুলির জন্য কাজ করবে না।
  • ক্রিয়াকলাপগুলি কেবল একটি একক কাজের মধ্যে সংগঠিত করা যেতে পারে। একটি নতুন টাস্কে কোনও ক্রিয়াকলাপ চালু করা সর্বদা এটি কোনও বিদ্যমান বিভাজনের বাইরে একটি নতুন প্রসারিত উইন্ডোতে রাখে।
  • কেবলমাত্র একই প্রক্রিয়াতে ক্রিয়াকলাপগুলি সংগঠিত করা যায় এবং একটি বিভক্তিতে রাখা যেতে পারে। SplitInfo কলব্যাক কেবলমাত্র একই প্রক্রিয়া সম্পর্কিত ক্রিয়াকলাপগুলি রিপোর্ট করে, যেহেতু বিভিন্ন প্রক্রিয়াতে ক্রিয়াকলাপ সম্পর্কে জানার কোনও উপায় নেই।
  • প্রতিটি জোড়া বা একক ক্রিয়াকলাপ নিয়ম কেবল নিয়ম নিবন্ধিত হওয়ার পরে ঘটে এমন ক্রিয়াকলাপ চালু করার ক্ষেত্রে প্রযোজ্য। বর্তমানে বিদ্যমান বিভাজন বা তাদের ভিজ্যুয়াল বৈশিষ্ট্যগুলি আপডেট করার কোনও উপায় নেই।
  • স্প্লিট জোড় ফিল্টার কনফিগারেশন অবশ্যই ক্রিয়াকলাপগুলি সম্পূর্ণরূপে চালু করার সময় ব্যবহৃত অভিপ্রায়গুলির সাথে মেলে। অ্যাপ্লিকেশন প্রক্রিয়া থেকে যখন একটি নতুন ক্রিয়াকলাপ শুরু হয় তখন ম্যাচিংটি ঘটে থাকে, তাই এটি অন্তর্নিহিত উদ্দেশ্যগুলি ব্যবহার করার সময় সিস্টেম প্রক্রিয়াতে পরে সমাধান করা উপাদানগুলির নামগুলি সম্পর্কে নাও জানতে পারে। যদি কোনও উপাদানটির নাম প্রবর্তনের সময় জানা না যায় তবে পরিবর্তে একটি ওয়াইল্ডকার্ড ব্যবহার করা যেতে পারে ("*/*") এবং ফিল্টারিং অভিপ্রায় ক্রিয়াকলাপের ভিত্তিতে সম্পাদন করা যেতে পারে।
  • পাত্রে বা বিভক্ত হওয়ার পরে এবং তাদের তৈরি হওয়ার পরে বিভাজনের বাইরে ক্রিয়াকলাপগুলি সরিয়ে নেওয়ার কোনও উপায় নেই। স্প্লিটগুলি কেবল উইন্ডো ম্যানেজার লাইব্রেরি দ্বারা তৈরি করা হয় যখন ম্যাচিং বিধিগুলির সাথে নতুন ক্রিয়াকলাপ চালু করা হয় এবং বিভক্ত ধারকটিতে শেষ ক্রিয়াকলাপ শেষ হয়ে গেলে বিভাজনগুলি ধ্বংস হয়ে যায়।
  • কনফিগারেশনটি পরিবর্তিত হলে ক্রিয়াকলাপগুলি পুনরায় চালু করা যেতে পারে, সুতরাং যখন কোনও বিভাজন তৈরি করা হয় বা অপসারণ করা হয় এবং ক্রিয়াকলাপের সীমা পরিবর্তন হয়, তখন ক্রিয়াকলাপটি পূর্ববর্তী উদাহরণটির সম্পূর্ণ ধ্বংস এবং নতুনটির সৃষ্টির মধ্য দিয়ে যেতে পারে। ফলস্বরূপ, অ্যাপ্লিকেশন বিকাশকারীদের লাইফসাইকেল কলব্যাকগুলি থেকে নতুন ক্রিয়াকলাপ চালু করার মতো বিষয়গুলির সাথে সতর্ক হওয়া উচিত।
  • ক্রিয়াকলাপ এম্বেডিং সমর্থন করার জন্য ডিভাইসগুলিকে অবশ্যই উইন্ডো এক্সটেনশন ইন্টারফেস অন্তর্ভুক্ত করতে হবে। অ্যান্ড্রয়েড 12 এল (এপিআই স্তর 32) বা উচ্চতর চলমান প্রায় সমস্ত বড় স্ক্রিন ডিভাইস ইন্টারফেস অন্তর্ভুক্ত। তবে, একাধিক ক্রিয়াকলাপ চালাতে সক্ষম নয় এমন কিছু বড় স্ক্রিন ডিভাইসগুলি উইন্ডো এক্সটেনশন ইন্টারফেস অন্তর্ভুক্ত করে না। যদি কোনও বৃহত স্ক্রিন ডিভাইস মাল্টি-উইন্ডো মোড সমর্থন না করে তবে এটি ক্রিয়াকলাপ এম্বেডিং সমর্থন করতে পারে না।

অতিরিক্ত সম্পদ

{% শব্দার্থে %} {% endverbatim %} {% শব্দার্থে %} {% endverbatim %}