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

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

চিত্র 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।

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

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

বিভক্ত রাষ্ট্র পরিবর্তন প্রতিক্রিয়া

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

চিত্র 23. কার্যত অভিন্ন UI উপাদান সহ বিভিন্ন কার্যকলাপ।

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

চিত্র 24. অ্যাক্টিভিটি স্প্লিটে ডুপ্লিকেট UI উপাদান।

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

কোটলিন

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. সোয়াইপ অঙ্গভঙ্গি ফিনিশিং কার্যকলাপ B.
চিত্র 26. সোয়াইপ অঙ্গভঙ্গি ফিনিশিং কার্যকলাপ A.

যদি ডিভাইসটি ইঙ্গিত নেভিগেশনের পরিবর্তে পিছনের বোতামটি ব্যবহার করার জন্য সেট আপ করা হয় তবে ইনপুটটি ফোকাস করা কার্যকলাপে পাঠানো হয় - যে কার্যকলাপটি শেষ স্পর্শ করা হয়েছিল বা চালু হয়েছিল৷

একটি পাত্রে সমস্ত ক্রিয়াকলাপ সমাপ্ত করার প্রভাব বিপরীত কন্টেইনারের উপর নির্ভর করে বিভক্ত কনফিগারেশনের উপর।

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

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

  • 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>

ক্রিয়াকলাপ A এবং B সমন্বিত বিভক্ত। A শেষ হয়েছে, B কে সম্পূর্ণ উইন্ডো দখল করতে ছেড়েছে।

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

একসাথে কার্যক্রম শেষ করুন

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

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

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

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

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

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

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

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

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

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

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

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

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

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

উদাহরণস্বরূপ, যদি দুটি ক্রিয়াকলাপ সেকেন্ডারি পাত্রে থাকে, B এর উপরে C:

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

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

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

শীর্ষ কার্যকলাপ সমাপ্তি বিভাজন বজায় রাখে।

প্রাথমিক কন্টেইনারে কার্যকলাপ A এবং মাধ্যমিকে B এবং C কার্যকলাপের সাথে বিভক্ত করুন, C B এর উপরে স্তুপীকৃত। C সমাপ্তি, A এবং B ক্রিয়াকলাপ বিভাজনে রেখে।

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

প্রাথমিক কন্টেইনারে কার্যকলাপ A এবং মাধ্যমিকে B এবং C কার্যকলাপের সাথে বিভক্ত করুন, C B এর উপরে স্তুপীকৃত। B সমাপ্তি, A এবং C ক্রিয়াকলাপ বিভাজনে রেখে।

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

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

প্রাথমিক পাত্রে কার্যকলাপ A এবং মাধ্যমিক পাত্রে B এবং C কার্যকলাপের সাথে বিভক্ত, B এর উপরে C স্তুপীকৃত। A শেষ করে, এছাড়াও B এবং C সমাপ্ত করে।

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

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

প্রাথমিক কন্টেইনারে কার্যকলাপ A এবং মাধ্যমিকে B এবং C কার্যকলাপের সাথে বিভক্ত করুন, C B এর উপরে স্তুপীকৃত। C সমাপ্তি, A এবং B ক্রিয়াকলাপ বিভাজনে রেখে।

প্রাথমিক কন্টেইনারে কার্যকলাপ A এবং মাধ্যমিকে B এবং C কার্যকলাপের সাথে বিভক্ত করুন, C B এর উপরে স্তুপীকৃত। B সমাপ্তি, A এবং C ক্রিয়াকলাপ বিভাজনে রেখে।

প্রাথমিক কন্টেইনারে কার্যকলাপ A এবং মাধ্যমিকে B এবং C কার্যকলাপের সাথে বিভক্ত, B এর উপরে C স্তুপীকৃত। A সমাপ্তি, এছাড়াও B এবং C শেষ করে।

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

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

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

গতিশীল বিভক্ত বৈশিষ্ট্য

অ্যান্ড্রয়েড 15 (এপিআই লেভেল 35) এবং জেটপ্যাক উইন্ডো ম্যানেজার 1.4 দ্বারা সমর্থিত এবং উচ্চতর গতিশীল বৈশিষ্ট্যগুলি অফার করে যা অ্যাক্টিভিটি এমবেডিং স্প্লিটগুলির কনফিগারযোগ্যতা সক্ষম করে, যার মধ্যে রয়েছে:

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

ফলক সম্প্রসারণ

ফলক সম্প্রসারণ ব্যবহারকারীদের একটি দ্বৈত-প্যান বিন্যাসে দুটি কার্যকলাপের জন্য বরাদ্দকৃত স্ক্রীন স্থানের পরিমাণ সামঞ্জস্য করতে সক্ষম করে৷

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

  1. DividerAttributes এর একটি উদাহরণ তৈরি করুন

  2. বিভাজক বৈশিষ্ট্য কাস্টমাইজ করুন:

    • color : টেনে নেওয়া যায় এমন প্যান বিভাজকের রঙ।

    • widthDp : টেনে নেওয়া যায় এমন প্যান বিভাজকের প্রস্থ। সিস্টেমকে বিভাজকের প্রস্থ নির্ধারণ করতে দিতে WIDTH_SYSTEM_DEFAULT এ সেট করুন৷

    • টেনে আনার পরিসর: স্ক্রীনের ন্যূনতম শতাংশ যে কোন একটি ফলক দখল করতে পারে। 0.33 থেকে 0.66 পর্যন্ত হতে পারে। সিস্টেমকে ড্র্যাগ পরিসর নির্ধারণ করতে দিতে DRAG_RANGE_SYSTEM_DEFAULT এ সেট করুন৷

কোটলিন

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

if (WindowSdkExtensions.getInstance().extensionVersion >= 6) {
    splitAttributesBuilder.setDividerAttributes(
      DividerAttributes.DraggableDividerAttributes.Builder()
        .setColor(getColor(context, R.color.divider_color))
        .setWidthDp(4)
        .setDragRange(DividerAttributes.DragRange.DRAG_RANGE_SYSTEM_DEFAULT)
        .build()
    )
}
val splitAttributes: SplitAttributes = splitAttributesBuilder.build()

জাভা

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

if (WindowSdkExtensions.getInstance().getExtensionVersion() >= 6) {
    splitAttributesBuilder.setDividerAttributes(
      new DividerAttributes.DraggableDividerAttributes.Builder()
        .setColor(ContextCompat.getColor(context, R.color.divider_color))
        .setWidthDp(4)
        .setDragRange(DividerAttributes.DragRange.DRAG_RANGE_SYSTEM_DEFAULT)
        .build()
    );
}
SplitAttributes splitAttributes = splitAttributesBuilder.build();

অ্যাক্টিভিটি পিন করা হচ্ছে

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

আপনার অ্যাপে অ্যাক্টিভিটি পিনিং সক্ষম করতে, নিম্নলিখিতগুলি করুন:

  1. আপনি যে কার্যকলাপটি পিন করতে চান তার লেআউট ফাইলে একটি বোতাম যোগ করুন, উদাহরণস্বরূপ, একটি তালিকা-বিশদ বিন্যাসের বিস্তারিত কার্যকলাপ:

    <androidx.constraintlayout.widget.ConstraintLayout
     xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:app="http://schemas.android.com/apk/res-auto"
     xmlns:tools="http://schemas.android.com/tools"
     android:id="@+id/detailActivity"
     android:layout_width="match_parent"
     android:layout_height="match_parent"
     android:background="@color/white"
     tools:context=".DetailActivity">
    
    <TextView
       android:id="@+id/textViewItemDetail"
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"
       android:textSize="36sp"
       android:textColor="@color/obsidian"
       app:layout_constraintBottom_toTopOf="@id/pinButton"
       app:layout_constraintEnd_toEndOf="parent"
       app:layout_constraintStart_toStartOf="parent"
       app:layout_constraintTop_toTopOf="parent" />
    
    <androidx.appcompat.widget.AppCompatButton
       android:id="@+id/pinButton"
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"
       android:text="@string/pin_this_activity"
       app:layout_constraintBottom_toBottomOf="parent"
       app:layout_constraintEnd_toEndOf="parent"
       app:layout_constraintStart_toStartOf="parent"
       app:layout_constraintTop_toBottomOf="@id/textViewItemDetail"/>
    
    </androidx.constraintlayout.widget.ConstraintLayout>
    
  2. কার্যকলাপের onCreate() পদ্ধতিতে, বোতামে একটি অনক্লিক শ্রোতা সেট করুন:

    কোটলিন

    pinButton = findViewById(R.id.pinButton)
    pinButton.setOnClickListener {
        val splitAttributes: SplitAttributes = SplitAttributes.Builder()
            .setSplitType(SplitAttributes.SplitType.ratio(0.66f))
            .setLayoutDirection(SplitAttributes.LayoutDirection.LEFT_TO_RIGHT)
            .build()
    
        val pinSplitRule = SplitPinRule.Builder()
            .setSticky(true)
            .setDefaultSplitAttributes(splitAttributes)
            .build()
    
        SplitController.getInstance(applicationContext).pinTopActivityStack(taskId, pinSplitRule)
    }

    জাভা

    Button pinButton = findViewById(R.id.pinButton);
    pinButton.setOnClickListener( (view) => {
        SplitAttributes splitAttributes = new SplitAttributes.Builder()
            .setSplitType(SplitAttributes.SplitType.ratio(0.66f))
            .setLayoutDirection(SplitAttributes.LayoutDirection.LEFT_TO_RIGHT)
            .build();
    
        SplitPinRule pinSplitRule = new SplitPinRule.Builder()
            .setSticky(true)
            .setDefaultSplitAttributes(splitAttributes)
            .build();
    
        SplitController.getInstance(getApplicationContext()).pinTopActivityStack(getTaskId(), pinSplitRule);
    });

পূর্ণ-স্ক্রীন আবছা

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

WindowManager 1.4 এবং উচ্চতরের সাথে, একটি ডায়ালগ খোলে পুরো অ্যাপ উইন্ডোটি ডিফল্টরূপে ম্লান হয়ে যায় ( EmbeddingConfiguration.DimAreaBehavior.ON_TASK দেখুন)।

ডায়ালগটি খোলার ক্রিয়াকলাপের ধারকটিকে শুধুমাত্র আবছা করতে, EmbeddingConfiguration.DimAreaBehavior.ON_ACTIVITY_STACK ব্যবহার করুন।

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

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

রানটাইমে বিভক্ত সমর্থন পরীক্ষা করুন

অ্যাক্টিভিটি এম্বেডিং অ্যান্ড্রয়েড 12L (API লেভেল 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.
}

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

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

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

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

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

<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>

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

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

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

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