অ্যাক্টিভিটি এম্বেডিং, দুটি অ্যাক্টিভিটি বা একই অ্যাক্টিভিটির দুটি ইনস্ট্যান্সের মধ্যে কোনও অ্যাপ্লিকেশনের টাস্ক উইন্ডোকে ভাগ করে বড় স্ক্রিন ডিভাইসে অ্যাপকে অপ্টিমাইজ করে।
আপনার অ্যাপে একাধিক অ্যাক্টিভিটি থাকলে, অ্যাক্টিভিটি এম্বেডিং আপনাকে ট্যাবলেট, ফোল্ডেবল ও ChromeOS ডিভাইসে উন্নত ব্যবহারকারীর অভিজ্ঞতা প্রদান করতে সাহায্য করে।
অ্যাক্টিভিটি এম্বেডিংয়ের জন্য কোড রিফ্যাক্টরিংয়ের প্রয়োজন হয় না। XML কনফিগারেশন ফাইল তৈরি করে অথবা Jetpack WindowManager API কল করে, আপনার অ্যাপ কীভাবে এর অ্যাক্টিভিটি দেখাবে—পাশাপাশি বা স্ট্যাক করা—তা আপনি নির্ধারণ করেন।
ছোট স্ক্রিনের জন্য সহায়তা অটোমেটিক বজায় রাখা হয়। আপনার অ্যাপ কোনও ছোট স্ক্রিনের ডিভাইসে থাকলে, অ্যাক্টিভিটিগুলি একটির উপরে একটি করে সাজানো থাকে। বড় স্ক্রিনে, অ্যাক্টিভিটি পাশাপাশি দেখানো হয়। আপনার তৈরি করা কনফিগারেশনের উপর ভিত্তি করে সিস্টেম প্রেজেন্টেশন নির্ধারণ করে—কোনও ব্রাঞ্চিং লজিক প্রয়োজন নেই।
ডিভাইসের ওরিয়েন্টেশন পরিবর্তন হলে অ্যাক্টিভিটি এম্বেডিং তা মানিয়ে নেয় এবং ফোল্ড করা যায় এমন ডিভাইসে নির্বিঘ্নে কাজ করে। ডিভাইস ফোল্ড ও আনফোল্ড করার সাথে সাথে অ্যাক্টিভিটি স্ট্যাক ও আনস্ট্যাক করে।
Android 12L (API লেভেল 32) ও এর পরবর্তী যেকোনও ভার্সনে চলে এমন বেশিরভাগ বড় স্ক্রিনের ডিভাইসে অ্যাক্টিভিটি এম্বেডিং কাজ করে।
টাস্ক উইন্ডো স্প্লিট করা
অ্যাক্টিভিটি এম্বেডিং অ্যাপ টাস্ক উইন্ডোকে দুটি কন্টেনারে ভাগ করে: প্রাথমিক ও সেকেন্ডারি। কন্টেনারগুলি মূল অ্যাক্টিভিটি থেকে বা কন্টেনারে আগে থেকেই থাকা অন্যান্য অ্যাক্টিভিটি থেকে লঞ্চ করা অ্যাক্টিভিটি ধরে রাখে।
অ্যাক্টিভিটি লঞ্চ করার সাথে সাথে সেকেন্ডারি কন্টেনারে সেগুলি স্ট্যাক করা হয় এবং ছোট স্ক্রিনে সেকেন্ডারি কন্টেনারটি প্রাইমারি কন্টেনারের উপরে স্ট্যাক করা হয়, তাই অ্যাক্টিভিটি স্ট্যাকিং ও ব্যাক নেভিগেশন আপনার অ্যাপে আগে থেকেই বিল্ট-ইন থাকা অ্যাক্টিভিটির ক্রমের সাথে সামঞ্জস্যপূর্ণ হয়।
অ্যাক্টিভিটি এম্বেডিং আপনাকে বিভিন্ন উপায়ে অ্যাক্টিভিটি দেখাতে সাহায্য করে। আপনার অ্যাপ, দুটি অ্যাক্টিভিটি একই সাথে পাশাপাশি বা একটির উপরে আরেকটি লঞ্চ করে টাস্ক উইন্ডো স্প্লিট করতে পারে:
সম্পূর্ণ টাস্ক উইন্ডো জুড়ে থাকা কোনও অ্যাক্টিভিটি, পাশাপাশি নতুন অ্যাক্টিভিটি লঞ্চ করে স্প্লিট তৈরি করতে পারে:
আগে থেকেই স্প্লিট করা এবং টাস্ক উইন্ডো শেয়ার করা অ্যাক্টিভিটিগুলি নিম্নলিখিত উপায়ে অন্যান্য অ্যাক্টিভিটি লঞ্চ করতে পারে:
অন্য অ্যাক্টিভিটির উপরে পাশে:
ছবি ৪. অ্যাক্টিভিটি A, অ্যাক্টিভিটি B-এর উপরে অ্যাক্টিভিটি C-কে সাইডে শুরু করে। একদিকে সরিয়ে এবং স্প্লিটকে পাশাপাশি শিফট করে, আগের প্রাথমিক অ্যাক্টিভিটি আড়াল করে:
ছবি ৫. অ্যাক্টিভিটি B, অ্যাক্টিভিটি C-কে পাশে শুরু করে এবং স্প্লিটকে পাশে সরায়। সবচেয়ে উপরে থাকা অ্যাক্টিভিটির জায়গায় কোনও অ্যাক্টিভিটি লঞ্চ করুন; অর্থাৎ, একই অ্যাক্টিভিটি স্ট্যাকে:
ছবি ৬. অ্যাক্টিভিটি 'খ' কোনও অতিরিক্ত ইনটেন্ট ফ্ল্যাগ ছাড়াই অ্যাক্টিভিটি 'গ' শুরু করে। একই টাস্কে একটি অ্যাক্টিভিটি ফুল উইন্ডো লঞ্চ করুন:
ছবি ৭. অ্যাক্টিভিটি A বা অ্যাক্টিভিটি B, অ্যাক্টিভিটি C শুরু করে যা টাস্ক উইন্ডো পূর্ণ করে।
ব্যাক নেভিগেশন
অ্যাক্টিভিটিগুলির মধ্যে পারস্পরিক নির্ভরতা বা কীভাবে ব্যবহারকারীরা ব্যাক ইভেন্ট ট্রিগার করেন তার উপর নির্ভর করে স্প্লিট টাস্ক উইন্ডো স্টেটে বিভিন্ন ধরনের অ্যাপ্লিকেশনের ব্যাক নেভিগেশন সংক্রান্ত আলাদা আলাদা নিয়ম থাকতে পারে, যেমন:
- একসাথে যাওয়া: অ্যাক্টিভিটিগুলি সম্পর্কিত হলে এবং একটিকে অন্যটি ছাড়া দেখানো না গেলে, ব্যাক নেভিগেশন কনফিগার করে দু'টিই শেষ করা যেতে পারে।
- আলাদা আলাদাভাবে কাজ করা: অ্যাক্টিভিটিগুলি সম্পূর্ণ স্বাধীন হলে, কোনও অ্যাক্টিভিটিতে ব্যাক নেভিগেশন করলে টাস্ক উইন্ডোতে অন্য অ্যাক্টিভিটির স্টেট প্রভাবিত হয় না।
বোতাম নেভিগেশন ব্যবহার করার সময়, শেষ ফোকাস করা অ্যাক্টিভিটিতে ব্যাক ইভেন্ট পাঠানো হয়।
জেসচার-ভিত্তিক নেভিগেশনের জন্য:
Android 14 (API লেভেল 34) ও এর আগের যেকোনও ভার্সন — ব্যাক ইভেন্টটি সেই অ্যাক্টিভিটিতে পাঠানো হয় যেখানে জেসচারটি করা হয়েছে। ব্যবহারকারী স্ক্রিনের বাঁদিক থেকে সোয়াইপ করলে, স্প্লিট উইন্ডোর বাঁদিকের প্যানেলে থাকা অ্যাক্টিভিটিতে 'ব্যাক' ইভেন্ট পাঠানো হয়। ব্যবহারকারী স্ক্রিনের ডানদিক থেকে সোয়াইপ করলে, ডানদিকের প্যানেলে অ্যাক্টিভিটিতে 'ফিরে যান' ইভেন্ট পাঠানো হয়।
Android 15 (API লেভেল 35) ও তার পরের যেকোনও ভার্সন
একই অ্যাপ থেকে একাধিক অ্যাক্টিভিটি ডিল করার সময়, সোয়াইপের দিকনির্দেশ নির্বিশেষে জেসচার সবচেয়ে উপরের অ্যাক্টিভিটি সম্পূর্ণ করে, যা আরও বেশি ইউনিফায়েড অভিজ্ঞতা প্রদান করে।
আলাদা আলাদা অ্যাপ থেকে দুটি অ্যাক্টিভিটি (ওভারলে) জড়িত আছে এমন পরিস্থিতিতে, ব্যাক ইভেন্টটি ফোকাসে থাকা শেষ অ্যাক্টিভিটিতে ডাইরেক্ট করা হয়, যা বোতাম নেভিগেশনের বিহেভিয়ারের সাথে সামঞ্জস্যপূর্ণ।
মাল্টি-প্যানেল লেআউট
Jetpack WindowManager আপনাকে Android 12L (API লেভেল 32) বা তার পরের যেকোনও ভার্সন সহ বড় স্ক্রিনের ডিভাইসে এবং
আগের প্ল্যাটফর্ম ভার্সন সহ কিছু ডিভাইসে অ্যাক্টিভিটি এম্বেডিং মাল্টি-প্যানেল
লেআউট তৈরি করতে সাহায্য করে। ফ্র্যাগমেন্ট বা ভিউ-ভিত্তিক লেআউটের পরিবর্তে একাধিক অ্যাক্টিভিটির উপর ভিত্তি করে তৈরি
বর্তমান অ্যাপ, যেমন
SlidingPaneLayout সোর্স কোড রিফ্যাক্টর না করেই উন্নত বড় স্ক্রিন ব্যবহারকারীর অভিজ্ঞতা
প্রদান করতে পারে।
একটি সাধারণ উদাহরণ হল তালিকা-বিবরণ স্প্লিট। উচ্চ-কোয়ালিটির প্রেজেন্টেশন নিশ্চিত করতে, সিস্টেম তালিকা অ্যাক্টিভিটি শুরু করে এবং তারপরে অ্যাপ্লিকেশন অবিলম্বে বিস্তারিত অ্যাক্টিভিটি শুরু করে। দুটি অ্যাক্টিভিটিই ড্র করা না হওয়া পর্যন্ত ট্রানজিশন সিস্টেম অপেক্ষা করে, তারপর সেগুলি একসাথে দেখায়। ব্যবহারকারীর কাছে, দুটি অ্যাক্টিভিটি একটি হিসেবে লঞ্চ হয়।
অ্যাট্রিবিউট ভাগ করা
আপনি স্প্লিট কন্টেনারগুলির মধ্যে টাস্ক উইন্ডো কীভাবে আনুপাতিকভাবে ভাগ করা হয় এবং কন্টেনারগুলি কীভাবে একে অপরের সাথে সম্পর্কিত তা নির্দিষ্ট করতে পারেন।
XML কনফিগারেশন ফাইলে সংজ্ঞায়িত নিয়মের জন্য, নিম্নলিখিত অ্যাট্রিবিউট সেট করুন:
splitRatio: কন্টেনারের অনুপাত সেট করে। মানটি হল একটি ফ্লোটিং পয়েন্ট ওপেন ইন্টারভ্যালে (০.০, ১.০) থাকা সংখ্যা।splitLayoutDirection: স্প্লিট কন্টেনারগুলি কীভাবে একে অপরের তুলনায় লেআউট করা হয় তা নির্দিষ্ট করে। ভ্যালুর মধ্যে এগুলি পড়ে:ltr: বাঁদিক থেকে ডানদিকেrtl: ডানদিক থেকে বাঁদিকেlocale: লোকেল সেটিং থেকেltrবাrtlনির্ধারণ করা হয়
উদাহরণ দেখতে XML কনফিগারেশন বিভাগ দেখুন।
WindowManager API ব্যবহার করে তৈরি করা নিয়মের জন্য, SplitAttributes.Builder সহ একটি SplitAttributes
অবজেক্ট তৈরি করুন এবং নিম্নলিখিত বিল্ডার
মেথড কল করুন:
setSplitType(): স্প্লিট কন্টেনারের অনুপাত সেট করে। বৈধ আর্গুমেন্ট, যার মধ্যেSplitAttributes.SplitType.ratio()পদ্ধতিও পড়ে, সেই সম্পর্কে জানতেSplitAttributes.SplitTypeদেখুন।setLayoutDirection(): কন্টেনারের লেআউট সেট করে। সম্ভাব্য ভ্যালু জানতেSplitAttributes.LayoutDirectionদেখুন।
উদাহরণ দেখতে WindowManager API বিভাগ দেখুন।
স্প্লিট ওরিয়েন্টেশন
ডিসপ্লের ডাইমেনশন ও অ্যাস্পেক্ট রেশিও অ্যাক্টিভিটি এম্বেডিং স্প্লিটে অ্যাক্টিভিটির পজিশনিং নির্ধারণ করে। বড় ল্যান্ডস্কেপ ডিসপ্লেতে, অ্যাক্টিভিটি পাশাপাশি দেখানো হয়; লম্বা পোর্ট্রেট ডিসপ্লে বা ফোল্ড করা যায় এমন ডিভাইসে টেবিলটপ পোসচারে একটির উপরে আরেকটি দেখানো হয়।
আপনি SplitController
SplitAttributes ক্যালকুলেটরের সাহায্যে স্প্লিট করার ওরিয়েন্টেশন নির্দিষ্ট করতে পারবেন। অ্যাক্টিভ SplitRule-এর জন্য
ক্যালকুলেটর SplitAttributes গণনা করে।
বিভিন্ন ডিভাইস স্টেটের জন্য বিভিন্ন দিকে প্যারেন্ট কন্টেনার স্প্লিট করতে ক্যালকুলেটর ব্যবহার করুন, যেমন:
Kotlin
if (WindowSdkExtensions.getInstance().extensionVersion >= 2) { SplitController.getInstance(this).setSplitAttributesCalculator { params -> val parentConfiguration = params.parentConfiguration val builder = SplitAttributes.Builder() return@setSplitAttributesCalculator if (parentConfiguration.screenWidthDp >= 840) { // Side-by-side dual-pane layout for wide displays. builder .setLayoutDirection(SplitAttributes.LayoutDirection.LOCALE) .build() } else if (parentConfiguration.screenHeightDp >= 600) { // Horizontal split for tall displays. builder .setLayoutDirection(SplitAttributes.LayoutDirection.BOTTOM_TO_TOP) .build() } else { // Fallback to expand the secondary container. builder .setSplitType(SPLIT_TYPE_EXPAND) .build() } } }
জাভা
if (WindowSdkExtensions.getInstance().getExtensionVersion() >= 2) { SplitController.getInstance(this).setSplitAttributesCalculator(params -> { Configuration parentConfiguration = params.getParentConfiguration(); SplitAttributes.Builder builder = new SplitAttributes.Builder(); if (parentConfiguration.screenWidthDp >= 840) { // Side-by-side dual-pane layout for wide displays. return builder .setLayoutDirection(SplitAttributes.LayoutDirection.LOCALE) .build(); } else if (parentConfiguration.screenHeightDp >= 600) { // Horizontal split for tall displays. return builder .setLayoutDirection(SplitAttributes.LayoutDirection.BOTTOM_TO_TOP) .build(); } else { // Fallback to expand the secondary container. return builder .setSplitType(SplitType.SPLIT_TYPE_EXPAND) .build(); } }); }
ফোল্ড করা যায় এমন ডিভাইসে, ডিভাইসটি ল্যান্ডস্কেপ মোডে থাকলে আপনি স্ক্রিনটি উল্লম্বভাবে স্প্লিট করতে পারবেন, ডিভাইসটি পোর্ট্রেট মোডে থাকলে একটি অ্যাক্টিভিটি ডিসপ্লে করতে পারবেন এবং ডিভাইসটি টেবিলটপ পোজে থাকলে স্ক্রিনটি অনুভূমিকভাবে স্প্লিট করতে পারবেন:
Kotlin
if (WindowSdkExtensions.getInstance().extensionVersion >= 2) { SplitController.getInstance(this).setSplitAttributesCalculator { params -> val tag = params.splitRuleTag val parentWindowMetrics = params.parentWindowMetrics val parentConfiguration = params.parentConfiguration val foldingFeatures = params.parentWindowLayoutInfo.displayFeatures.filterIsInstance<FoldingFeature>() val feature = if (foldingFeatures.size == 1) foldingFeatures[0] else null val builder = SplitAttributes.Builder() builder.setSplitType(SPLIT_TYPE_HINGE) return@setSplitAttributesCalculator if (feature?.isSeparating == true) { // Horizontal split for tabletop posture. builder .setSplitType(SPLIT_TYPE_HINGE) .setLayoutDirection( if (feature.orientation == FoldingFeature.Orientation.HORIZONTAL) { SplitAttributes.LayoutDirection.BOTTOM_TO_TOP } else { SplitAttributes.LayoutDirection.LOCALE } ) .build() } else if (parentConfiguration.screenWidthDp >= 840) { // Side-by-side dual-pane layout for wide displays. builder .setLayoutDirection(SplitAttributes.LayoutDirection.LOCALE) .build() } else { // No split for tall displays. builder .setSplitType(SPLIT_TYPE_EXPAND) .build() } } }
জাভা
if (WindowSdkExtensions.getInstance().getExtensionVersion() >= 2) { SplitController.getInstance(this).setSplitAttributesCalculator(params -> { String tag = params.getSplitRuleTag(); WindowMetrics parentWindowMetrics = params.getParentWindowMetrics(); Configuration parentConfiguration = params.getParentConfiguration(); List<FoldingFeature> foldingFeatures = params.getParentWindowLayoutInfo().getDisplayFeatures().stream().filter( item -> item instanceof FoldingFeature) .map(item -> (FoldingFeature) item) .collect(Collectors.toList()); FoldingFeature feature = foldingFeatures.size() == 1 ? foldingFeatures.get(0) : null; SplitAttributes.Builder builder = new SplitAttributes.Builder(); builder.setSplitType(SplitType.SPLIT_TYPE_HINGE); if (feature != null && feature.isSeparating()) { // Horizontal slit for tabletop posture. return builder .setSplitType(SplitType.SPLIT_TYPE_HINGE) .setLayoutDirection( feature.getOrientation() == FoldingFeature.Orientation.HORIZONTAL ? SplitAttributes.LayoutDirection.BOTTOM_TO_TOP : SplitAttributes.LayoutDirection.LOCALE) .build(); } else if (parentConfiguration.screenWidthDp >= 840) { // Side-by-side dual-pane layout for wide displays. return builder .setLayoutDirection(SplitAttributes.LayoutDirection.LOCALE) .build(); } else { // No split for tall displays. return builder .setSplitType(SplitType.SPLIT_TYPE_EXPAND) .build(); } }); }
প্লেসহোল্ডার
প্লেসহোল্ডার অ্যাক্টিভিটি হল খালি সেকেন্ডারি অ্যাক্টিভিটি যা অ্যাক্টিভিটি স্প্লিটের একটি অংশ দখল করে। সেগুলিকে শেষ পর্যন্ত কন্টেন্ট আছে এমন অন্য অ্যাক্টিভিটি দিয়ে পরিবর্তন করতে হবে। যেমন, কোনও তালিকা থেকে কোনও আইটেম বেছে না নেওয়া পর্যন্ত, কোনও প্লেসহোল্ডার অ্যাক্টিভিটি, তালিকা-বিবরণ লেআউটে অ্যাক্টিভিটি স্প্লিটের সেকেন্ডারি সাইড দখল করে রাখতে পারে। সেই আইটেম বেছে নেওয়ার পরে, বেছে নেওয়া তালিকা আইটেমের বিস্তারিত তথ্য থাকা অ্যাক্টিভিটি প্লেসহোল্ডারটিকে সরিয়ে দেয়।
ডিফল্ট হিসেবে, অ্যাক্টিভিটি স্প্লিটের জন্য যথেষ্ট জায়গা থাকলে তবেই সিস্টেম প্লেসহোল্ডার দেখায়। ডিসপ্লে সাইজ পরিবর্তিত হয়ে স্প্লিট দেখানোর জন্য প্রস্থ বা উচ্চতা খুব ছোট হয়ে গেলে প্লেসহোল্ডার অটোমেটিক শেষ হয়ে যায়। জায়গা থাকলে, সিস্টেম আবার নতুন করে শুরু করা অবস্থা সহ প্লেসহোল্ডারটি আবার লঞ্চ করে।
তবে, SplitPlaceholder.Builder-এর SplitPlaceholderRule বা
setSticky() পদ্ধতির stickyPlaceholder অ্যাট্রিবিউট
ডিফল্ট আচরণকে ওভাররাইড করতে পারে। অ্যাট্রিবিউট বা মেথড true ভ্যালু নির্দিষ্ট করলে,
ডিসপ্লেকে দুটি প্যানেল থেকে একটি প্যানেল ডিসপ্লেতে রিসাইজ করা হলে,
সিস্টেম টাস্ক উইন্ডোতে প্লেসহোল্ডারকে সবচেয়ে উপরের অ্যাক্টিভিটি হিসেবে দেখায়
(উদাহরণ হিসেবে স্প্লিট কনফিগারেশন দেখুন)।
উইন্ডোর সাইজ পরিবর্তন
ডিভাইস কনফিগারেশনে পরিবর্তন হলে, টাস্ক উইন্ডোর প্রস্থ কমে যায়, ফলে মাল্টি-পেন লেআউটের জন্য সেটি যথেষ্ট বড় থাকে না (যেমন, বড় স্ক্রিনের ফোল্ড করা যায় এমন ডিভাইস ট্যাবলেট সাইজ থেকে ফোন সাইজে ফোল্ড করা হলে অথবা মাল্টি-উইন্ডো মোডে অ্যাপ উইন্ডোর সাইজ পরিবর্তন করা হলে), টাস্ক উইন্ডোর সেকেন্ডারি প্যানে থাকা প্লেসহোল্ডার নয় এমন অ্যাক্টিভিটি প্রাইমারি প্যানে থাকা অ্যাক্টিভিটির উপরে স্ট্যাক করা হয়।
প্লেসহোল্ডার অ্যাক্টিভিটি তখনই দেখানো হয় যখন স্প্লিটের জন্য যথেষ্ট ডিসপ্লে উইডথ থাকে। ছোট স্ক্রিনে, প্লেসহোল্ডার অটোমেটিক বাতিল হয়ে যায়। ডিসপ্লে এরিয়া আবার যথেষ্ট বড় হয়ে গেলে, প্লেসহোল্ডারটি আবার তৈরি করা হয়। (প্লেসহোল্ডার বিভাগ দেখুন।)
অ্যাক্টিভিটি স্ট্যাকিং সম্ভব কারণ WindowManager সেকেন্ডারি প্যানেলে অ্যাক্টিভিটিগুলিকে প্রাইমারি প্যানেলে থাকা অ্যাক্টিভিটিগুলির উপরে z-অর্ডার করে।
সেকেন্ডারি প্যানেলে একাধিক অ্যাক্টিভিটি
অ্যাক্টিভিটি B, অ্যাক্টিভিটি C-কে কোনও অতিরিক্ত ইনটেন্ট ফ্ল্যাগ ছাড়াই চালু করে:

এর ফলে একই টাস্কে অ্যাক্টিভিটির নিম্নলিখিত z-অর্ডার তৈরি হয়:

তাই, ছোট টাস্ক উইন্ডোতে, অ্যাপ্লিকেশনটি একটি অ্যাক্টিভিটিতে ছোট হয়ে যায় এবং স্ট্যাকের উপরে C থাকে:

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

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

ছোট টাস্ক উইন্ডোতে, অ্যাপ্লিকেশনটি C on top সহ একটি অ্যাক্টিভিটিতে ছোট হয়ে যায়:

ফিক্সড-পোর্ট্রেট ওরিয়েন্টেশন
android:screenOrientation ম্যানিফেস্ট সেটিং, অ্যাপকে পোর্ট্রেট বা ল্যান্ডস্কেপ ওরিয়েন্টেশনে অ্যাক্টিভিটি সীমাবদ্ধ করতে দেয়। ট্যাবলেট ও ফোল্ড করা যায় এমন ডিভাইসের মতো বড় স্ক্রিনযুক্ত ডিভাইসে ব্যবহারকারীর অভিজ্ঞতা উন্নত করতে, ডিভাইস প্রস্তুতকারী (OEM) স্ক্রিন ওরিয়েন্টেশন সংক্রান্ত অনুরোধ উপেক্ষা করতে এবং ল্যান্ডস্কেপ ডিসপ্লেতে পোর্ট্রেট ওরিয়েন্টেশন বা পোর্ট্রেট ডিসপ্লেতে ল্যান্ডস্কেপ ওরিয়েন্টেশনে অ্যাপ লেটারবক্স করতে পারে।
একইভাবে, অ্যাক্টিভিটি এম্বেডিং চালু করা থাকলে, OEM-রা ডিভাইস কাস্টমাইজ করে বড় স্ক্রিনে ল্যান্ডস্কেপ ওরিয়েন্টেশনে ফিক্সড-পোর্ট্রেট অ্যাক্টিভিটি লেটারবক্স করতে পারে (প্রস্থ ≥ ৬০০dp)। ফিক্সড-পোর্ট্রেট অ্যাক্টিভিটি দ্বিতীয় অ্যাক্টিভিটি লঞ্চ করলে, ডিভাইসটি দু'টি অ্যাক্টিভিটি পাশাপাশি টু-পেন ডিসপ্লেতে দেখাতে পারে।
আপনার অ্যাপ যে অ্যাক্টিভিটি এম্বেডিং (স্প্লিট কনফিগারেশন
বিভাগ দেখুন) সাপোর্ট করে তা ডিভাইসকে জানাতে, আপনার অ্যাপ ম্যানিফেস্ট ফাইলে সবসময় android.window.PROPERTY_ACTIVITY_EMBEDDING_SPLITS_ENABLED
প্রপার্টি যোগ করুন। তারপরে OEM-কাস্টমাইজ করা ডিভাইস নির্ধারণ করতে পারে যে ফিক্সড-পোর্ট্রেট অ্যাক্টিভিটি লেটারবক্স
করতে হবে কিনা।
স্প্লিট কনফিগারেশন
স্প্লিট নিয়ম অ্যাক্টিভিটি স্প্লিট কনফিগার করে। আপনি XML কনফিগারেশন ফাইলে বা Jetpack WindowManager API কল করার মাধ্যমে স্প্লিট করার নিয়ম ডিফাইন করেন।
দুটি ক্ষেত্রেই, আপনার অ্যাপকে অবশ্যই WindowManager লাইব্রেরি অ্যাক্সেস করতে হবে এবং সিস্টেমকে জানাতে হবে যে অ্যাপটি অ্যাক্টিভিটি এম্বেডিং প্রয়োগ করেছে।
নিম্নলিখিত কাজগুলি করুন:
আপনার অ্যাপের মডিউল-লেভেলে
build.gradleলেটেস্ট WindowManager লাইব্রেরি নির্ভরতা যোগ করুন, যেমন:implementation 'androidx.window:window:1.1.0-beta02'WindowManager লাইব্রেরি অ্যাক্টিভিটি এম্বেডিংয়ের জন্য প্রয়োজনীয় সব কম্পোনেন্ট প্রদান করে।
সিস্টেমকে জানান যে আপনার অ্যাপ অ্যাক্টিভিটি এম্বেডিং প্রয়োগ করেছে।
অ্যাপ ম্যানিফেস্ট ফাইলের <application> এলিমেন্টে
android.window.PROPERTY_ACTIVITY_EMBEDDING_SPLITS_ENABLEDপ্রপার্টি যোগ করুন এবং ভ্যালু true হিসেবে সেট করুন, যেমন:<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-ভিত্তিক প্রয়োগ তৈরি করতে, নিম্নলিখিত ধাপগুলি সম্পূর্ণ করুন:
নিম্নলিখিত কাজগুলি করে এমন একটি 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>ইনিশিয়ালাইজার তৈরি করুন।
WindowManager
RuleControllerকম্পোনেন্ট XML কনফিগারেশন ফাইল পার্স করে এবং সিস্টেমের জন্য নিয়ম উপলভ্য করে তোলে। Jetpack Startup লাইব্রেরিInitializerঅ্যাপ চালু হওয়ার সময় XML ফাইলকেRuleControllerউপলভ্য করে তোলে, যাতে কোনও অ্যাক্টিভিটি শুরু হওয়ার সময় নিয়ম কার্যকর থাকে।ইনিশিয়ালাইজার তৈরি করতে, নিম্নলিখিত কাজগুলি করুন:
আপনার মডিউল-লেভেল
build.gradleফাইলে লেটেস্ট Jetpack Startup লাইব্রেরি ডিপেন্ডেন্সি যোগ করুন, যেমন:implementation 'androidx.startup:startup-runtime:1.1.1'Initializerইন্টারফেস প্রয়োগ করে এমন একটি ক্লাস তৈরি করুন।XML কনফিগারেশন ফাইলের (
main_split_config.xml) ID,RuleController.parseRules()মেথডে পাস করার মাধ্যমে, ইনিশিয়ালাইজারRuleController-এর জন্য স্প্লিট করার নিয়ম উপলভ্য করে তোলে।Kotlin
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(); } }
নিয়মের সংজ্ঞা দেওয়ার জন্য কন্টেন্ট প্রদানকারী তৈরি করুন।
আপনার অ্যাপ মেনিফেস্ট ফাইলে
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>অ্যাপের
onCreate()মেথড কল করার আগেInitializationProviderডিসকভার ও ইনিশিয়ালাইজSplitInitializerকরে। এর ফলে, অ্যাপের মূল অ্যাক্টিভিটি শুরু হলে স্প্লিট নিয়ম কার্যকর হয়।
WindowManager API
আপনি অল্প কয়েকটি API
কলের মাধ্যমে প্রোগ্র্যামাটিক উপায়ে অ্যাক্টিভিটি এম্বেডিং প্রয়োগ করতে পারবেন। যাতে কোনও অ্যাক্টিভিটি
লঞ্চ করার আগে নিয়ম কার্যকর থাকে তা নিশ্চিত করতে, onCreate()
Application-এর সাবক্লাসের মধ্যে কল করুন।
প্রোগ্র্যামাটিক উপায়ে অ্যাক্টিভিটি স্প্লিট তৈরি করতে, নিম্নলিখিত কাজগুলি করুন:
একটি স্প্লিট নিয়ম তৈরি করুন:
একটি
SplitPairFilterতৈরি করুন যা স্প্লিট শেয়ার করা অ্যাক্টিভিটি শনাক্ত করে:Kotlin
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 );
ফিল্টার সেটে ফিল্টার যোগ করুন:
```Kotlin
val filterSet = setOf(splitPairFilter)
জাভা
Set<SplitPairFilter> filterSet = new HashSet<>(); filterSet.add(splitPairFilter);
স্প্লিটের জন্য লেআউট অ্যাট্রিবিউট তৈরি করুন:
Kotlin
val splitAttributes: SplitAttributes = SplitAttributes.Builder() .setSplitType(SplitAttributes.SplitType.ratio(0.33f)) .setLayoutDirection(SplitAttributes.LayoutDirection.LEFT_TO_RIGHT) .build()
জাভা
SplitAttributes splitAttributes = new SplitAttributes.Builder() .setSplitType(SplitAttributes.SplitType.ratio(0.33f)) .setLayoutDirection(SplitAttributes.LayoutDirection.LEFT_TO_RIGHT) .build();
SplitAttributes.Builderলেআউট অ্যাট্রিবিউট সহ একটি অবজেক্ট তৈরি করে:setSplitType(): উপলভ্য ডিসপ্লে এরিয়া কীভাবে প্রতিটি অ্যাক্টিভিটি কন্টেনারে অ্যাসাইন করা হয় তা নির্ধারণ করে। অনুপাত স্প্লিট করার ধরনটি উপলভ্য ডিসপ্লে এরিয়ার সেই অংশকে নির্দিষ্ট করে যা প্রাইমারি কন্টেনারে বরাদ্দ করা হয়েছে; সেকেন্ডারি কন্টেনারটি উপলভ্য ডিসপ্লে এরিয়ার অবশিষ্ট অংশ দখল করে।setLayoutDirection(): অ্যাক্টিভিটি কন্টেনারগুলি একে অপরের সাথে কীভাবে সাজানো হয় তা নির্দিষ্ট করে, প্রথমে প্রাথমিক কন্টেনার।
SplitPairRuleতৈরি করুন:Kotlin
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(): ডিভাইসের ওরিয়েন্টেশন যাই হোক না কেন, স্প্লিট করার সুবিধা চালু করতে হলে, দুটি ডিসপ্লে ডাইমেনশনের মধ্যে ছোটটির ন্যূনতম ভ্যালু (ডিপি-তে) কত হতে হবে তা সেট করে।setMaxAspectRatioInPortrait(): পোর্ট্রেট ওরিয়েন্টেশনে সর্বাধিক ডিসপ্লে অ্যাস্পেক্ট রেশিও (উচ্চতা:প্রস্থ) সেট করে যার জন্য অ্যাক্টিভিটি স্প্লিট দেখানো হয়। কোনও পোর্ট্রেট ডিসপ্লের অ্যাস্পেক্ট রেশিও সর্বাধিক অ্যাস্পেক্ট রেশিওর থেকে বেশি হলে, ডিসপ্লের প্রস্থ যাই হোক না কেন, স্প্লিট করার সুবিধা বন্ধ করে দেওয়া হয়। মনে রাখবেন: ডিফল্ট ভ্যালু হল ১.৪, যার ফলে বেশিরভাগ ট্যাবলেটে পোর্ট্রেট ওরিয়েন্টেশনে অ্যাক্টিভিটি পুরো টাস্ক উইন্ডো জুড়ে থাকে। এছাড়াও দেখুনSPLIT_MAX_ASPECT_RATIO_PORTRAIT_DEFAULTএবংsetMaxAspectRatioInLandscape(). ল্যান্ডস্কেপের ডিফল্ট ভ্যালু হলALWAYS_ALLOW।setFinishPrimaryWithSecondary(): সেকেন্ডারি কন্টেনারে সব অ্যাক্টিভিটি সম্পূর্ণ করলে, প্রাইমারি কন্টেনারের অ্যাক্টিভিটি কীভাবে প্রভাবিত হয় তা সেট করে।NEVERথেকে বোঝা যায় যে সেকেন্ডারি কন্টেনারের সব অ্যাক্টিভিটি শেষ হয়ে গেলেও সিস্টেম যেন প্রাইমারি অ্যাক্টিভিটি শেষ না করে (অ্যাক্টিভিটি শেষ করা দেখুন)।setFinishSecondaryWithPrimary(): প্রাইমারি কন্টেনারের সব অ্যাক্টিভিটি সম্পূর্ণ হলে তা সেকেন্ডারি কন্টেনারের অ্যাক্টিভিটিকে কীভাবে প্রভাবিত করে তা সেট করে।ALWAYSথেকে বোঝা যায় যে প্রাইমারি কন্টেনারের সব অ্যাক্টিভিটি সম্পূর্ণ হয়ে গেলে সিস্টেমকে সবসময় সেকেন্ডারি কন্টেনারের অ্যাক্টিভিটি সম্পূর্ণ করতে হবে (দেখুন অ্যাক্টিভিটি সম্পূর্ণ করা)।setClearTop(): কন্টেনারে নতুন অ্যাক্টিভিটি লঞ্চ করার সময় সেকেন্ডারি কন্টেনারের সব অ্যাক্টিভিটি শেষ হয়ে গেছে কিনা তা নির্দিষ্ট করে।falseভ্যালু থেকে বোঝা যায় যে নতুন অ্যাক্টিভিটি সেকেন্ডারি কন্টেনারে আগে থেকেই থাকা অ্যাক্টিভিটির উপরে স্ট্যাক করা হয়।
WindowManager
RuleController-এর সিঙ্গলটন ইনস্ট্যান্স পান, এবং এই নিয়ম যোগ করুন:Kotlin
val ruleController = RuleController.getInstance(this) ruleController.addRule(splitPairRule)
জাভা
RuleController ruleController = RuleController.getInstance(this); ruleController.addRule(splitPairRule);
কন্টেন্ট উপলভ্য না থাকলে সেকেন্ডারি কন্টেনারের জন্য প্লেসহোল্ডার তৈরি করুন:
এমন একটি
ActivityFilterতৈরি করুন যা সেই অ্যাক্টিভিটি শনাক্ত করে যার সাথে প্লেসহোল্ডার একটি টাস্ক উইন্ডো স্প্লিট শেয়ার করে:Kotlin
val placeholderActivityFilter = ActivityFilter( ComponentName(this, ListActivity::class.java), null )
জাভা
ActivityFilter placeholderActivityFilter = new ActivityFilter( new ComponentName(this, ListActivity.class), null );
ফিল্টার সেটে ফিল্টার যোগ করুন:
Kotlin
val placeholderActivityFilterSet = setOf(placeholderActivityFilter)
জাভা
Set<ActivityFilter> placeholderActivityFilterSet = new HashSet<>(); placeholderActivityFilterSet.add(placeholderActivityFilter);
একটি
SplitPlaceholderRuleতৈরি করুন:Kotlin
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(this, 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(): দুটি ডিসপ্লে ডাইমেনশনের মধ্যে ছোটটির ন্যূনতম ভ্যালু (ডিপি-তে) সেট করে যা ডিভাইসের ওরিয়েন্টেশন নির্বিশেষে স্প্লিট করার অনুমতি দেওয়ার জন্য থাকতে হবে।setMaxAspectRatioInPortrait(): পোর্ট্রেট ওরিয়েন্টেশনে অ্যাক্টিভিটি স্প্লিট দেখানোর জন্য সর্বাধিক ডিসপ্লে অ্যাস্পেক্ট রেশিও (উচ্চতা:প্রস্থ) সেট করে। মনে রাখবেন: ডিফল্ট ভ্যালু হল ১.৪, যার ফলে বেশিরভাগ ট্যাবলেটে পোর্ট্রেট ওরিয়েন্টেশনে অ্যাক্টিভিটি টাস্ক উইন্ডো পূরণ করে। এছাড়াও দেখুনSPLIT_MAX_ASPECT_RATIO_PORTRAIT_DEFAULTএবংsetMaxAspectRatioInLandscape(). ল্যান্ডস্কেপের ডিফল্ট ভ্যালু হলALWAYS_ALLOW।setFinishPrimaryWithPlaceholder(): প্রাইমারি কন্টেনারে প্লেসহোল্ডার অ্যাক্টিভিটি শেষ করার ফলে অ্যাক্টিভিটি কীভাবে প্রভাবিত হয় তা সেট করে। ALWAYS নির্দেশ করে যে প্লেসহোল্ডার শেষ হয়ে গেলে সিস্টেমকে সবসময় প্রাইমারি কন্টেনারে অ্যাক্টিভিটি শেষ করতে হবে (অ্যাক্টিভিটি শেষ করা দেখুন)।setSticky(): প্লেসহোল্ডার অ্যাক্টিভিটি প্রথমে যথেষ্ট ন্যূনতম প্রস্থ সহ স্প্লিটে দেখা গেলে, ছোট ডিসপ্লেতে অ্যাক্টিভিটি স্ট্যাকের উপরে প্লেসহোল্ডার অ্যাক্টিভিটি দেখা যাবে কিনা তা নির্ধারণ করে।
WindowManager
RuleController-এ নিয়ম যোগ করুন:Kotlin
ruleController.addRule(splitPlaceholderRule)
জাভা
ruleController.addRule(splitPlaceholderRule);
স্প্লিট করা উচিত নয় এমন অ্যাক্টিভিটি উল্লেখ করুন:
এমন একটি
ActivityFilterতৈরি করুন যা এমন অ্যাক্টিভিটি শনাক্ত করে যা সবসময় সম্পূর্ণ টাস্ক ডিসপ্লে এরিয়া জুড়ে থাকবে:Kotlin
val expandedActivityFilter = ActivityFilter( ComponentName(this, ExpandedActivity::class.java), null )
জাভা
ActivityFilter expandedActivityFilter = new ActivityFilter( new ComponentName(this, ExpandedActivity.class), null );
ফিল্টার সেটে ফিল্টার যোগ করুন:
Kotlin
val expandedActivityFilterSet = setOf(expandedActivityFilter)
জাভা
Set<ActivityFilter> expandedActivityFilterSet = new HashSet<>(); expandedActivityFilterSet.add(expandedActivityFilter);
ActivityRuleতৈরি করুন:Kotlin
val activityRule = ActivityRule.Builder(expandedActivityFilterSet) .setAlwaysExpand(true) .build()
জাভা
ActivityRule activityRule = new ActivityRule.Builder( expandedActivityFilterSet ).setAlwaysExpand(true) .build();
ActivityRule.Builderনিয়ম তৈরি ও কনফিগার করে:expandedActivityFilterSet: এতে অ্যাক্টিভিটি ফিল্টার থাকে যা কখন নিয়ম প্রয়োগ করতে হবে তা নির্ধারণ করে। এটি সেইসব অ্যাক্টিভিটি শনাক্ত করে যেগুলি আপনি স্প্লিট থেকে বাদ দিতে চান।setAlwaysExpand(): অ্যাক্টিভিটি সম্পূর্ণ টাস্ক উইন্ডো পূর্ণ করবে কিনা তা নির্দিষ্ট করে।
WindowManager
RuleController-এ নিয়ম যোগ করুন:Kotlin
ruleController.addRule(activityRule)
জাভা
ruleController.addRule(activityRule);
ক্রস-অ্যাপ্লিকেশন এম্বেডিং
Android 13 (API লেভেল 33) ও এর পরের যেকোনও ভার্সনে, অ্যাপ অন্যান্য অ্যাপ থেকে অ্যাক্টিভিটি এম্বেড করতে পারে। ক্রস‑অ্যাপ্লিকেশন বা ক্রস‑UID, অ্যাক্টিভিটি এম্বেডিং একাধিক Android অ্যাপ্লিকেশন থেকে অ্যাক্টিভিটির ভিজ্যুয়াল ইন্টিগ্রেশন চালু করে। সিঙ্গেল-অ্যাপ অ্যাক্টিভিটি এম্বেডিংয়ের মতো, সিস্টেম স্ক্রিনে হোস্ট অ্যাপের অ্যাক্টিভিটি এবং অন্য অ্যাপ থেকে এম্বেড করা অ্যাক্টিভিটি পাশাপাশি বা উপরে ও নিচে দেখায়।
যেমন, Settings অ্যাপটি WallpaperPicker অ্যাপ থেকে ওয়ালপেপার বাছাইকারী অ্যাক্টিভিটি এম্বেড করতে পারে:
ট্রাস্ট মডেল
অন্যান্য অ্যাপ থেকে অ্যাক্টিভিটি এম্বেড করা হোস্ট প্রসেস, এম্বেড করা অ্যাক্টিভিটির প্রেজেন্টেশন নতুন করে সংজ্ঞায়িত করতে পারে, এর মধ্যে সাইজ, পজিশন, ক্রপিং ও ট্রান্সপারেন্সি অন্তর্ভুক্ত। ক্ষতিকারক হোস্ট এই ক্ষমতা ব্যবহার করে ব্যবহারকারীদের বিভ্রান্ত করতে এবং ক্লিকজ্যাকিং বা অন্যান্য UI-রিড্রেসিং অ্যাটাক তৈরি করতে পারে।
ক্রস-অ্যাপ অ্যাক্টিভিটি এম্বেডিংয়ের অপব্যবহার প্রতিরোধ করতে, Android-এর প্রয়োজন হল যে অ্যাপগুলি তাদের অ্যাক্টিভিটি এম্বেড করার অনুমতি দেওয়ার জন্য অপ্ট ইন করবে। অ্যাপ হোস্টকে বিশ্বস্ত বা অবিশ্বস্ত হিসেবে চিহ্নিত করতে পারে।
বিশ্বস্ত হোস্ট
আপনার অ্যাপ থেকে অ্যাক্টিভিটি এম্বেড ও সম্পূর্ণ কন্ট্রোল করার জন্য অন্যান্য অ্যাপ্লিকেশনকে অনুমতি দিতে, হোস্ট অ্যাপ্লিকেশনের SHA-256 সার্টিফিকেটটি আপনার অ্যাপের ম্যানিফেস্ট ফাইলের
<activity> বা <application> এলিমেন্টের android:knownActivityEmbeddingCerts অ্যাট্রিবিউটে উল্লেখ করুন।
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>
অ্যাপের মালিকরা Gradle
signingReport টাস্ক রান করিয়ে SHA সার্টিফিকেট ডাইজেস্ট পেতে পারেন। সার্টিফিকেট ডাইজেস্ট হল SHA-256 ফিঙ্গারপ্রিন্ট, যাতে আলাদা করার জন্য
কোলন থাকে না। আরও তথ্যের জন্য, সাইন-ইন রিপোর্ট রান করানো এবং
আপনার ক্লায়েন্টকে যাচাই করা দেখুন।
অবিশ্বস্ত হোস্ট
আপনার অ্যাপের অ্যাক্টিভিটি এম্বেড করতে এবং সেগুলির প্রেজেন্টেশন কন্ট্রোল করতে,
অ্যাপ ম্যানিফেস্টে <activity> বা <application> এলিমেন্টে android:allowUntrustedActivityEmbedding অ্যাট্রিবিউট উল্লেখ করুন, যেমন:
<activity
android:name=".MyEmbeddableActivity"
android:allowUntrustedActivityEmbedding="true"
... />
অ্যাট্রিবিউটের ডিফল্ট ভ্যালু হল false, যা ক্রস-অ্যাপ অ্যাক্টিভিটি এম্বেড করা আটকায়।
কাস্টম যাচাইকরণ
অবিশ্বস্ত অ্যাক্টিভিটি এম্বেড করার ঝুঁকি কমাতে, হোস্টের পরিচয় যাচাই করে এমন কাস্টম
যাচাইকরণ মেকানিজম তৈরি করুন। আপনি যদি হোস্ট
সার্টিফিকেট জানেন, তাহলে androidx.security.app.authenticator লাইব্রেরি ব্যবহার করে
প্রমাণ করুন। হোস্ট আপনার অ্যাক্টিভিটি এম্বেড করার পরে প্রমাণীকরণ করলে, আপনি
আসল কন্টেন্ট দেখাতে পারবেন। যদি না হয়, তাহলে আপনি ব্যবহারকারীকে জানাতে পারেন যে অ্যাকশনটি
অনুমোদিত নয় এবং কন্টেন্টটি ব্লক করতে পারেন।
কোনও হোস্ট আপনার
অ্যাক্টিভিটি এম্বেড করছে কিনা তা চেক করতে, Jetpack WindowManager লাইব্রেরি থেকে
ActivityEmbeddingController#isActivityEmbedded() পদ্ধতি ব্যবহার করুন, যেমন:
Kotlin
fun isActivityEmbedded(activity: Activity): Boolean { return ActivityEmbeddingController.getInstance(this).isActivityEmbedded(activity) }
জাভা
boolean isActivityEmbedded(Activity activity) { return ActivityEmbeddingController.getInstance(context).isActivityEmbedded(activity); }
ন্যূনতম সাইজ সংক্রান্ত বিধিনিষেধ
Android সিস্টেম, এম্বেড করা অ্যাক্টিভিটিতে অ্যাপের
মেনিফেস্ট <layout> এলিমেন্টে উল্লেখ করা ন্যূনতম উচ্চতা ও প্রস্থ প্রয়োগ করে। কোনও অ্যাপ্লিকেশন ন্যূনতম উচ্চতা ও প্রস্থ উল্লেখ না করলে, সিস্টেমের ডিফল্ট ভ্যালু প্রযোজ্য হয়
(sw220dp)।
হোস্ট যদি এম্বেড করা কন্টেনারকে ন্যূনতম সাইজের চেয়ে ছোট সাইজে রিসাইজ করার চেষ্টা করে, তাহলে এম্বেড করা কন্টেনারটি সম্পূর্ণ টাস্ক বাউন্ড জুড়ে প্রসারিত হয়।
<activity-alias>
বিশ্বস্ত বা অবিশ্বস্ত অ্যাক্টিভিটি এম্বেড করার জন্য
<activity-alias> এলিমেন্টের সাথে কাজ করতে, android:knownActivityEmbeddingCerts বা
android:allowUntrustedActivityEmbedding অবশ্যই অ্যালিয়াসের পরিবর্তে টার্গেট অ্যাক্টিভিটিতে
প্রয়োগ করতে হবে। সিস্টেম সার্ভারে নিরাপত্তা যাচাই করে এমন নীতি
অ্যালিয়াসের পরিবর্তে টার্গেটে সেট করা ফ্ল্যাগের উপর ভিত্তি করে তৈরি হয়।
হোস্ট অ্যাপ্লিকেশন
হোস্ট অ্যাপ্লিকেশনগুলি ক্রস-অ্যাপ অ্যাক্টিভিটি এম্বেডিং ঠিক সেইভাবে প্রয়োগ করে,
যেভাবে তারা সিঙ্গেল-অ্যাপ অ্যাক্টিভিটি এম্বেডিং প্রয়োগ করে। SplitPairRule এবং
SplitPairFilter অথবা ActivityRule ও ActivityFilter অবজেক্ট
এম্বেড করা অ্যাক্টিভিটি ও টাস্ক উইন্ডো স্প্লিট নির্দিষ্ট করে। স্প্লিট করার নিয়ম
XML-এ স্ট্যাটিক অথবা Jetpack
WindowManager API কল ব্যবহার করে রানটাইমে ডিফাইন করা হয়।
কোনও হোস্ট অ্যাপ্লিকেশন যদি এমন কোনও অ্যাক্টিভিটি এম্বেড করার চেষ্টা করে যা ক্রস-অ্যাপ এম্বেডিং অপ্ট-ইন করেনি, তাহলে অ্যাক্টিভিটিটি সম্পূর্ণ টাস্ক বাউন্ড দখল করে নেয়। এর ফলে, টার্গেট অ্যাক্টিভিটি ক্রস-অ্যাপ এম্বেডিংয়ের অনুমতি দেয় কিনা তা হোস্ট অ্যাপ্লিকেশনকে জানতে হবে।
কোনও এম্বেড করা অ্যাক্টিভিটি একই টাস্কে নতুন অ্যাক্টিভিটি শুরু করলে এবং নতুন অ্যাক্টিভিটি ক্রস-অ্যাপ এম্বেডিংয়ে অপ্ট-ইন না করলে, এম্বেড করা কন্টেনারে অ্যাক্টিভিটি ওভারলে করার পরিবর্তে অ্যাক্টিভিটি পুরো টাস্ক বাউন্ড দখল করে নেয়।
হোস্ট অ্যাপ্লিকেশন কোনও বিধিনিষেধ ছাড়াই নিজস্ব অ্যাক্টিভিটি এম্বেড করতে পারে, তবে অ্যাক্টিভিটি একই টাস্কে লঞ্চ করতে হবে।
স্প্লিট করার উদাহরণ
ফুল উইন্ডো থেকে স্প্লিট করা
কোনও রিফ্যাক্টরিংয়ের প্রয়োজন নেই। আপনি স্ট্যাটিক্যালি বা রানটাইমে স্প্লিটের
কনফিগারেশন ডিফাইন করতে পারবেন এবং তারপরে কোনও
অতিরিক্ত প্যারামিটার ছাড়াই Context#startActivity() কল করতে পারবেন।
<SplitPairRule>
<SplitPairFilter
window:primaryActivityName=".A"
window:secondaryActivityName=".B"/>
</SplitPairRule>
ডিফল্ট হিসেবে স্প্লিট করা
কোনও অ্যাপ্লিকেশনের ল্যান্ডিং পৃষ্ঠা বড় স্ক্রিনে দুটি কন্টেনারে ভাগ করার জন্য ডিজাইন করা হলে, দুটি অ্যাক্টিভিটিই একসাথে তৈরি ও দেখানো হলে ব্যবহারকারীর অভিজ্ঞতা সবচেয়ে ভালো হয়। তবে, ব্যবহারকারী প্রাইমারি কন্টেনারে থাকা অ্যাক্টিভিটির সাথে ইন্টার্যাক্ট না করা পর্যন্ত স্প্লিটের সেকেন্ডারি কন্টেনারে কন্টেন্ট উপলভ্য নাও থাকতে পারে (যেমন, ব্যবহারকারী নেভিগেশন মেনু থেকে কোনও আইটেম বেছে নেন)। কন্টেন্ট স্প্লিটের সেকেন্ডারি কন্টেনারে দেখানো না পর্যন্ত প্লেসহোল্ডার অ্যাক্টিভিটি ফাঁকা জায়গা পূরণ করতে পারে (প্লেসহোল্ডার বিভাগ দেখুন)।
প্লেসহোল্ডার সহ স্প্লিট তৈরি করতে, প্লেসহোল্ডার তৈরি করুন এবং এটিকে প্রাথমিক অ্যাক্টিভিটির সাথে যুক্ত করুন:
<SplitPlaceholderRule
window:placeholderActivityName=".PlaceholderActivity">
<ActivityFilter
window:activityName=".MainActivity"/>
</SplitPlaceholderRule>
ডিপ লিঙ্ক স্প্লিট
কোনও অ্যাপ ইনটেন্ট পেলে, টার্গেট অ্যাক্টিভিটি অ্যাক্টিভিটি স্প্লিটের সেকেন্ডারি পার্ট হিসেবে দেখানো যেতে পারে; যেমন, কোনও তালিকা থেকে কোনও আইটেমের তথ্য সহ একটি বিস্তারিত স্ক্রিন দেখানোর অনুরোধ। ছোট ডিসপ্লেতে, বিবরণ সম্পূর্ণ টাস্ক উইন্ডোতে দেখানো হয়; বড় ডিভাইসে, তালিকার পাশে দেখানো হয়।
লঞ্চ করার অনুরোধটি মূল অ্যাক্টিভিটিতে রুট করা উচিত এবং টার্গেট বিবরণ অ্যাক্টিভিটি স্প্লিটে লঞ্চ করা উচিত। উপলভ্য ডিসপ্লের প্রস্থের উপর ভিত্তি করে সিস্টেম অটোমেটিক সঠিক প্রেজেন্টেশন—স্ট্যাক করা বা পাশাপাশি—বেছে নেয়।
Kotlin
override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) RuleController.getInstance(this) .addRule(SplitPairRule.Builder(filterSet).build()) startActivity(Intent(this, DetailActivity::class.java)) }
জাভা
@Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(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>
কনফিগারেশন অ্যাট্রিবিউট বিভাগ দেখুন।
স্প্লিট কন্টেনারে একাধিক অ্যাক্টিভিটি
স্প্লিট কন্টেনারে একাধিক অ্যাক্টিভিটি স্ট্যাক করলে ব্যবহারকারীরা ডিপ কন্টেন্ট অ্যাক্সেস করতে পারেন। যেমন, লিস্ট-ডিটেল স্প্লিটের ক্ষেত্রে, ব্যবহারকারীকে হয়ত সাব-ডিটেল বিভাগে যেতে হবে, কিন্তু প্রাইমারি অ্যাক্টিভিটি একই জায়গায় রাখতে হবে:
Kotlin
class DetailActivity : AppCompatActivity() { fun onOpenSubdetail() { startActivity(Intent(this, SubdetailActivity::class.java)) } }
জাভা
public class DetailActivity extends AppCompatActivity { void onOpenSubdetail() { startActivity(new Intent(this, SubdetailActivity.class)); } }
সাব-ডিটেল অ্যাক্টিভিটি, ডিটেল অ্যাক্টিভিটির উপরে প্লেস করা হয়, ফলে সেটি দেখা যায় না:

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

আগে থেকে থাকা স্প্লিটের উপরে নতুন কন্টেনারে সাইডে লঞ্চ করার সময় ডিফল্ট আচরণ হল, নতুন সেকেন্ডারি কন্টেনারকে উপরে রাখা এবং পুরনো কন্টেনারকে
ব্যাক স্ট্যাকে রেখে দেওয়া। আপনি স্প্লিট কনফিগার করে clearTop-এর মাধ্যমে আগের
সেকেন্ডারি কন্টেনার মুছে দিতে এবং নতুন অ্যাক্টিভিটি সাধারণভাবে লঞ্চ করতে পারবেন।
<SplitPairRule
window:clearTop="true">
<SplitPairFilter
window:primaryActivityName=".Menu"
window:secondaryActivityName=".ScreenA"/>
<SplitPairFilter
window:primaryActivityName=".Menu"
window:secondaryActivityName=".ScreenB"/>
</SplitPairRule>
Kotlin
inner class MenuActivity : AppCompatActivity() { fun onMenuItemSelected(selectedMenuItem: Int) { startActivity(Intent(this, classForItem(selectedMenuItem))) } }
জাভা
public class MenuActivity extends AppCompatActivity{ void onMenuItemSelected(int selectedMenuItem) { startActivity(new Intent(this, classForItem(selectedMenuItem))); } }
অথবা, একই সেকেন্ডারি অ্যাক্টিভিটি ব্যবহার করুন এবং প্রাইমারি (মেনু) অ্যাক্টিভিটি থেকে নতুন ইনটেন্ট পাঠান যা একই ইনস্ট্যান্সের সাথে সমাধান করে কিন্তু সেকেন্ডারি কন্টেনারে একটি স্টেট বা UI আপডেট ট্রিগার করে।
একাধিক স্প্লিট
অ্যাপ, পাশে অতিরিক্ত অ্যাক্টিভিটি লঞ্চ করে মাল্টি-লেভেল ডিপ নেভিগেশন প্রদান করতে পারে ।
সেকেন্ডারি কন্টেনারে থাকা কোনও অ্যাক্টিভিটি পাশে নতুন অ্যাক্টিভিটি লঞ্চ করলে, আগে থেকে থাকা স্প্লিটের উপরে নতুন স্প্লিট তৈরি হয়।
ব্যাক স্ট্যাকে আগে খোলা সব অ্যাক্টিভিটি থাকে, তাই ব্যবহারকারীরা C শেষ করার পরে A/B স্প্লিটে নেভিগেট করতে পারবেন।

নতুন স্প্লিট তৈরি করতে, আগে থেকে থাকা সেকেন্ডারি কন্টেনার থেকে নতুন অ্যাক্টিভিটি পাশে লঞ্চ করুন। A/B ও B/C স্প্লিটের জন্য কনফিগারেশন ঘোষণা করুন এবং B থেকে অ্যাক্টিভিটি C স্বাভাবিকভাবে লঞ্চ করুন:
<SplitPairRule>
<SplitPairFilter
window:primaryActivityName=".A"
window:secondaryActivityName=".B"/>
<SplitPairFilter
window:primaryActivityName=".B"
window:secondaryActivityName=".C"/>
</SplitPairRule>
Kotlin
class B : AppCompatActivity() { fun onOpenC() { startActivity(Intent(this, C::class.java)) } }
জাভা
public class B extends AppCompatActivity{ void onOpenC() { startActivity(new Intent(this, C.class)); } }
স্প্লিট স্টেট পরিবর্তনের ব্যাপারে প্রতিক্রিয়া জানানো
কোনও অ্যাপের বিভিন্ন অ্যাক্টিভিটিতে UI এলিমেন্ট থাকতে পারে যা একই ফাংশন পারফর্ম করে; যেমন, একটি কন্ট্রোল যা অ্যাকাউন্ট সেটিং সহ একটি উইন্ডো খোলে।
দুটি অ্যাক্টিভিটির মধ্যে যদি কোনও UI এলিমেন্ট কমন থাকে এবং সেগুলি স্প্লিট করা হয়, তাহলে দুটি অ্যাক্টিভিটিতেই এলিমেন্টটি দেখানো অপ্রয়োজনীয় এবং বিভ্রান্তিকর হতে পারে।
অ্যাক্টিভিটি কখন স্প্লিট করা হয়েছে তা জানতে, SplitController.splitInfoList ফ্লো চেক করুন অথবা স্প্লিট স্টেটে পরিবর্তন হলে তা জানতে
SplitControllerCallbackAdapter-এর সাথে লিসনার রেজিস্টার করুন। তারপর,
সেই অনুযায়ী UI অ্যাডজাস্ট করুন:
Kotlin
val layout = layoutInflater.inflate(R.layout.activity_main, null) val view = layout.findViewById<View>(R.id.infoButton) lifecycleScope.launch { 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) { super.onCreate(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 স্টেটে লঞ্চ করা হয় (আরও তথ্যের জন্য লাইফসাইকেল-অ্যাওয়ার কম্পোনেন্টের সাথে
Kotlin কোরাউটিন ব্যবহার করুন দেখুন)।
অ্যাক্টিভিটি
বন্ধ হয়ে গেলেও, যেকোনও লাইফসাইকেল স্টেটে কলব্যাক করা যেতে পারে। শ্রোতাদের সাধারণত onStart()-এ রেজিস্টার করা এবং onStop()-এ আনরেজিস্টার করা উচিত।
সম্পূর্ণ-উইন্ডো মোডাল
কিছু অ্যাক্টিভিটি নির্দিষ্ট অ্যাকশন না নেওয়া পর্যন্ত ব্যবহারকারীদের অ্যাপ্লিকেশনটির সাথে ইন্টার্যাক্ট করতে বাধা দেয়; যেমন, লগ-ইন স্ক্রিন অ্যাক্টিভিটি, নীতি স্বীকৃতি স্ক্রিন বা এরর মেসেজ। মডেল অ্যাক্টিভিটি যাতে স্প্লিটে দেখা না যায় তা নিশ্চিত করতে হবে।
expand configuration ব্যবহার করে কোনও অ্যাক্টিভিটিকে সবসময় টাস্ক উইন্ডো পূরণ করতে বাধ্য করা যেতে পারে:
<ActivityRule
window:alwaysExpand="true">
<ActivityFilter
window:activityName=".FullWidthActivity"/>
</ActivityRule>
অ্যাক্টিভিটি সম্পূর্ণ করা
ডিসপ্লের প্রান্ত থেকে সোয়াইপ করে ব্যবহারকারীরা স্প্লিটের যেকোনও দিকে অ্যাক্টিভিটি সম্পূর্ণ করতে পারবেন:
ডিভাইসটি জেসচার নেভিগেশনের পরিবর্তে 'ফিরে যান' বোতাম ব্যবহার করার জন্য সেট-আপ করা থাকলে, ইনপুটটি ফোকাস করা অ্যাক্টিভিটিতে পাঠানো হয়—যে অ্যাক্টিভিটি স্পর্শ করা হয়েছে বা সর্বশেষ লঞ্চ করা হয়েছে।
কোনও কন্টেনারে সব অ্যাক্টিভিটি সম্পূর্ণ করার ফলে বিপরীত কন্টেনারের উপর যে প্রভাব পড়ে তা স্প্লিট কনফিগারেশনের উপর নির্ভর করে।
কনফিগারেশন অ্যাট্রিবিউট
আপনি স্প্লিট পেয়ার রুল অ্যাট্রিবিউট নির্দিষ্ট করতে পারেন, যাতে স্প্লিটের একদিকের সব অ্যাক্টিভিটি সম্পূর্ণ হলে তা স্প্লিটের অন্যদিকের অ্যাক্টিভিটিকে কীভাবে প্রভাবিত করে তা কনফিগার করা যায়। অ্যাট্রিবিউটগুলি হল:
window:finishPrimaryWithSecondary— How finishing all activities in the secondary container affects the activities in the primary containerwindow:finishSecondaryWithPrimary— প্রাইমারি কন্টেনারে সব অ্যাক্টিভিটি সম্পূর্ণ করলে সেকেন্ডারি কন্টেনারের অ্যাক্টিভিটির উপর কী প্রভাব পড়ে
অ্যাট্রিবিউটের সম্ভাব্য ভ্যালুর মধ্যে এগুলি অন্তর্ভুক্ত:
always— সবসময় সংশ্লিষ্ট কন্টেনারে অ্যাক্টিভিটি সম্পূর্ণ করুনnever— সংশ্লিষ্ট কন্টেনারে অ্যাক্টিভিটি কখনও শেষ করবেন নাadjacent— দুটি কন্টেনার একে অপরের পাশে দেখানো হলে, সংশ্লিষ্ট কন্টেনারে থাকা অ্যাক্টিভিটি সম্পূর্ণ করুন, কিন্তু দুটি কন্টেনার একে অপরের উপরে থাকলে নয়
যেমন:
<SplitPairRule
<!-- Do not finish primary container activities when all secondary container activities finish. -->
window:finishPrimaryWithSecondary="never"
<!-- Finish secondary container activities when all primary container activities finish. -->
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>


কন্টেনারে একাধিক অ্যাক্টিভিটি সম্পূর্ণ করা
স্প্লিট কন্টেনারে একাধিক অ্যাক্টিভিটি স্ট্যাক করা থাকলে, স্ট্যাকের সবচেয়ে নিচে থাকা অ্যাক্টিভিটি শেষ করলে, সবচেয়ে উপরে থাকা অ্যাক্টিভিটি অটোমেটিক শেষ হয়ে যায় না।
যেমন, দুটি অ্যাক্টিভিটি সেকেন্ডারি কন্টেনারে থাকলে, B-এর উপরে C:

এবং স্প্লিটের কনফিগারেশন, অ্যাক্টিভিটি ক ও খ-এর কনফিগারেশন দ্বারা নির্ধারিত হয়:
<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>



রানটাইমে স্প্লিট প্রপার্টি পরিবর্তন করা
অ্যাক্টিভ ও দৃশ্যমান স্প্লিটের প্রপার্টি পরিবর্তন করা যায় না। স্প্লিট করার নিয়ম পরিবর্তন করলে, অতিরিক্ত অ্যাক্টিভিটি লঞ্চ ও নতুন কন্টেনার প্রভাবিত হয়, তবে আগে থেকে থাকা ও অ্যাক্টিভ স্প্লিট প্রভাবিত হয় না।
অ্যাক্টিভ স্প্লিটের প্রপার্টি পরিবর্তন করতে, স্প্লিটের মধ্যে থাকা সাইড অ্যাক্টিভিটি বা অ্যাক্টিভিটি সম্পূর্ণ করুন এবং নতুন কনফিগারেশন সহ আবার সাইডে লঞ্চ করুন।
ডায়নামিক স্প্লিট প্রপার্টি
Jetpack WindowManager 1.4 ও এর পরের যেকোনও ভার্সনে কাজ করে এমন Android 15 (API লেভেল ৩৫) ও এর পরের যেকোনও ভার্সন ডায়নামিক ফিচার অফার করে যা অ্যাক্টিভিটি এমবেডিং স্প্লিটের কনফিগার করার সুবিধা দেয়, এর মধ্যে এগুলি অন্তর্ভুক্ত:
- প্যানেল বড় করা: একটি ইন্টার্যাক্টিভ, টেনে আনা যায় এমন ডিভাইডার ব্যবহারকারীদের স্প্লিট প্রেজেন্টেশনে প্যানেলের সাইজ পরিবর্তন করতে দেয়।
- অ্যাক্টিভিটি স্ট্যাক পিনিং: ব্যবহারকারীরা একটি কন্টেনারে কন্টেন্ট পিন করতে এবং অন্য কন্টেনারের নেভিগেশন থেকে কন্টেনারের নেভিগেশনকে আলাদা করতে পারবেন।
- ডায়ালগ ফুল-স্ক্রিন ডিম: ডায়ালগ দেখানোর সময়, অ্যাপ নির্দিষ্ট করতে পারে যে সম্পূর্ণ টাস্ক উইন্ডো ডিম করবে নাকি শুধু সেই কন্টেনারটি ডিম করবে যেটি ডায়ালগ খুলেছে।
প্যানেল বড় করা
প্যানেল বড় করার সুবিধা ব্যবহার করে, ডুয়াল‑প্যানেল লেআউটে থাকা দুটি অ্যাক্টিভিটির জন্য বরাদ্দ করা স্ক্রিন স্পেসের পরিমাণ ব্যবহারকারীরা অ্যাডজাস্ট করতে পারেন।
উইন্ডো ডিভাইডারের চেহারা কাস্টমাইজ করতে এবং ডিভাইডারের ড্র্যাগ করার রেঞ্জ সেট করতে, নিম্নলিখিত কাজগুলি করুন:
DividerAttributes-এর ইনস্ট্যান্স তৈরি করোডিভাইডার অ্যাট্রিবিউট কাস্টমাইজ করা:
color: ড্র্যাগ করা যায় এমন প্যানেল ডিভাইডারের রঙ।widthDp: ড্র্যাগ করা যায় এমন প্যানেল সেপারেটরের প্রস্থ। ডিভাইডারের প্রস্থ সিস্টেমকে নির্ধারণ করতে দিতে,WIDTH_SYSTEM_DEFAULT-এ সেট করুন।ড্র্যাগ রেঞ্জ: স্ক্রিনের সর্বনিম্ন শতাংশ যা যেকোনও প্যানে দখল করতে পারে। ০.৩৩ থেকে ০.৬৬ পর্যন্ত হতে পারে। সিস্টেমকে ড্র্যাগ রেঞ্জ নির্ধারণ করতে দিতে,
DRAG_RANGE_SYSTEM_DEFAULT-এ সেট করুন ।
Kotlin
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(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(this, R.color.divider_color)) .setWidthDp(4) .setDragRange(DividerAttributes.DragRange.DRAG_RANGE_SYSTEM_DEFAULT) .build() ); } SplitAttributes _splitAttributes = splitAttributesBuilder.build();
অ্যাক্টিভিটি স্ট্যাক পিনিং
অ্যাক্টিভিটি স্ট্যাক পিনিং ব্যবহারকারীদের স্প্লিট উইন্ডোগুলির মধ্যে একটি পিন করতে দেয় যাতে ব্যবহারকারীরা অন্য উইন্ডোতে নেভিগেট করার সময় অ্যাক্টিভিটি যেমন আছে তেমনই থাকে। অ্যাক্টিভিটি স্ট্যাক পিনিং আরও উন্নত মাল্টিটাস্কিং অভিজ্ঞতা প্রদান করে।
আপনার অ্যাপে অ্যাক্টিভিটি স্ট্যাক পিনিং চালু করতে, নিম্নলিখিত কাজগুলি করুন:
আপনি যে অ্যাক্টিভিটি পিন করতে চান, তার লেআউট ফাইলে একটি বোতাম যোগ করুন, যেমন, একটি লিস্ট‑ডিটেল লেআউটের বিবরণ অ্যাক্টিভিটি:
<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>অ্যাক্টিভিটির
onCreate()পদ্ধতিতে, বোতামে onclick লিসনার সেট করুন:Kotlin
val pinButton: Button = 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 ব্যবহার করুন।
স্প্লিট উইন্ডো থেকে ফুল উইন্ডোতে অ্যাক্টিভিটি এক্সট্র্যাক্ট করা
এমন একটি নতুন কনফিগারেশন তৈরি করুন যা সাইড অ্যাক্টিভিটি সম্পূর্ণ উইন্ডোতে দেখায় এবং তারপরে একই ইনস্ট্যান্সের সাথে সমাধান করা যায় এমন ইনটেন্ট সহ অ্যাক্টিভিটি আবার চালু করুন।
রানটাইমে স্প্লিট সাপোর্ট চেক করা
অ্যাক্টিভিটি এম্বেডিং Android 12L (API লেভেল 32) ও তার পরের যেকোনও ভার্সনে কাজ করে, তবে
আগের প্ল্যাটফর্ম ভার্সনে চলে এমন কিছু ডিভাইসেও উপলভ্য। ফিচারের উপলভ্যতা
রানটাইমে চেক করতে, SplitController.splitSupportStatus প্রপার্টি বা
SplitController.getSplitSupportStatus() মেথড ব্যবহার করুন:
Kotlin
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. }
স্প্লিট কাজ না করলে, অ্যাক্টিভিটি স্ট্যাকের উপরে অ্যাক্টিভিটি লঞ্চ করা হয় (নন-অ্যাক্টিভিটি এম্বেডিং মডেল অনুসরণ করে)।
সিস্টেম ওভাররাইড প্রতিরোধ করা
Android ডিভাইসের প্রস্তুতকারক (মূল সরঞ্জাম প্রস্তুতকারক বা OEM) ডিভাইস সিস্টেমের ফাংশন হিসেবে অ্যাক্টিভিটি এম্বেডিং প্রয়োগ করতে পারে। সিস্টেম মাল্টি-অ্যাক্টিভিটি অ্যাপের জন্য স্প্লিট করার নিয়ম নির্দিষ্ট করে, যা অ্যাপের উইন্ডো বিহেভিয়ারকে ওভাররাইড করে। সিস্টেম ওভাররাইড একাধিক অ্যাক্টিভিটি থাকা অ্যাপকে সিস্টেম-সংজ্ঞায়িত অ্যাক্টিভিটি এম্বেডিং মোডে বাধ্য করে।
সিস্টেম অ্যাক্টিভিটি এম্বেডিং, অ্যাপে কোনও পরিবর্তন না করেই, লিস্ট-ডিটেল-এর মতো মাল্টি-পেন লেআউটের মাধ্যমে অ্যাপের প্রেজেন্টেশন উন্নত করতে পারে। তবে, সিস্টেমের অ্যাক্টিভিটি এম্বেডিংয়ের কারণে অ্যাপের লেআউট ভুল হতে পারে, বাগ হতে পারে অথবা অ্যাপের প্রয়োগ করা অ্যাক্টিভিটি এম্বেডিংয়ের সাথে কনফ্লিক্ট হতে পারে।
আপনার অ্যাপ, অ্যাপ ম্যানিফেস্ট
ফাইলে
PROPERTY_ACTIVITY_EMBEDDING_ALLOW_SYSTEM_OVERRIDE সেট করার মাধ্যমে সিস্টেম অ্যাক্টিভিটি এম্বেড করা আটকাতে বা অনুমতি দিতে পারে, যেমন:
<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 লাইব্রেরি স্প্লিট তৈরি করে এবং স্প্লিট কন্টেনারের শেষ অ্যাক্টিভিটি শেষ হয়ে গেলে স্প্লিট ধ্বংস হয়ে যায়।
- কনফিগারেশনে পরিবর্তন হলে অ্যাক্টিভিটি আবার লঞ্চ করা যেতে পারে, তাই স্প্লিট তৈরি বা সরানো হলে এবং অ্যাক্টিভিটি বাউন্ড পরিবর্তন হলে, অ্যাক্টিভিটি আগের ইনস্ট্যান্স সম্পূর্ণভাবে মুছে দিয়ে নতুন ইনস্ট্যান্স তৈরি করতে পারে। এর ফলে, অ্যাপ ডেভেলপারদের নিম্নলিখিত বিষয়গুলি সম্পর্কে সতর্ক থাকতে হবে, যেমন লাইফসাইকেল কলব্যাক থেকে নতুন অ্যাক্টিভিটি লঞ্চ করা।
- অ্যাক্টিভিটি এম্বেডিং কাজ করার জন্য ডিভাইসে উইন্ডো এক্সটেনশন ইন্টারফেস থাকতে হবে। Android 12L (API লেভেল 32) বা তার পরের যেকোনও ভার্সনে চলে এমন প্রায় সব বড় স্ক্রিনের ডিভাইসে ইন্টারফেস অন্তর্ভুক্ত থাকে। তবে, কিছু বড় স্ক্রিনের ডিভাইস যা একাধিক অ্যাক্টিভিটি চালাতে পারে না, সেগুলিতে উইন্ডো এক্সটেনশন ইন্টারফেস থাকে না। কোনও বড় স্ক্রিন ডিভাইসে মাল্টি-উইন্ডো মোড কাজ না করলে, তাতে অ্যাক্টিভিটি এম্বেডিং কাজ নাও করতে পারে।
অতিরিক্ত রিসোর্স
- কোডল্যাব:
- লার্নিং পাথওয়ে — অ্যাক্টিভিটি এম্বেডিং
- Sample app — activity-embedding