তথ্য আর্কিটেকচার

অ্যান্ড্রয়েড ৮.০ সেটিংস অ্যাপের জন্য একটি নতুন ইনফরমেশন আর্কিটেকচার চালু করে, যা সেটিংসের বিন্যাসকে সরল করে এবং ব্যবহারকারীদের জন্য তাদের অ্যান্ড্রয়েড ডিভাইস কাস্টমাইজ করার সেটিংস দ্রুত খুঁজে পাওয়া সহজ করে তোলে। অ্যান্ড্রয়েড ৯ আরও বেশি সেটিংস কার্যকারিতা এবং সহজতর বাস্তবায়নের জন্য কিছু উন্নতি সাধন করে।

উদাহরণ এবং উৎস

সেটিংস-এর বেশিরভাগ পৃষ্ঠা বর্তমানে নতুন ফ্রেমওয়ার্ক ব্যবহার করে তৈরি করা হয়েছে। এর একটি ভালো উদাহরণ হলো ডিসপ্লেসেটিংস: packages/apps/Settings/src/com/android/settings/DisplaySettings.java

গুরুত্বপূর্ণ উপাদানগুলোর ফাইল পাথ নিচে দেওয়া হলো:

  • CategoryKey : packages/SettingsLib/src/com/android/settingslib/drawer/CategoryKey.java
  • ড্যাশবোর্ডফ্র্যাগমেন্টরেজিস্ট্রি : packages/apps/Settings/src/com/android/settings/dashboard/DashboardFragmentRegistry.java
  • ড্যাশবোর্ডফ্র্যাগমেন্ট : packages/apps/Settings/src/com/android/settings/dashboard/DashboardFragment.java
  • AbstractPreferenceController : frameworks/base/packages/SettingsLib/src/com/android/settingslib/core/AbstractPreferenceController.java
  • BasePreferenceController (অ্যান্ড্রয়েড ৯-এ প্রবর্তিত): packages/apps/Settings/src/com/android/settings/core/BasePreferenceController.java

বাস্তবায়ন

ডিভাইস প্রস্তুতকারকদের বিদ্যমান সেটিংস তথ্য কাঠামোকে অভিযোজিত করতে এবং অংশীদার-নির্দিষ্ট বৈশিষ্ট্যগুলির জন্য প্রয়োজন অনুযায়ী অতিরিক্ত সেটিংস পৃষ্ঠা যুক্ত করতে উৎসাহিত করা হচ্ছে। পুরোনো পৃষ্ঠা ( SettingsPreferencePage হিসেবে বাস্তবায়িত) থেকে একটি নতুন পৃষ্ঠায় ( DashboardFragment ব্যবহার করে বাস্তবায়িত) প্রেফারেন্স স্থানান্তর করা জটিল হতে পারে। পুরোনো পৃষ্ঠার প্রেফারেন্সটি সম্ভবত PreferenceController দিয়ে বাস্তবায়িত নয়।

সুতরাং, একটি পুরোনো পৃষ্ঠা থেকে নতুন পৃষ্ঠায় কোনো প্রেফারেন্স সরানোর সময়, নতুন DashboardFragment এ ইনস্ট্যানশিয়েট করার আগে আপনাকে একটি PreferenceController তৈরি করতে হবে এবং কোডটি সেই কন্ট্রোলারের মধ্যে নিয়ে যেতে হবে। PreferenceController জন্য প্রয়োজনীয় API-গুলো এর নামেই বর্ণিত আছে এবং Javadoc-এ নথিভুক্ত করা আছে।

প্রতিটি PreferenceController জন্য একটি ইউনিট টেস্ট যোগ করার জন্য জোরালোভাবে সুপারিশ করা হচ্ছে। যদি পরিবর্তনটি AOSP-তে জমা দেওয়া হয়, তাহলে একটি ইউনিট টেস্ট আবশ্যক। Robolectric ভিত্তিক টেস্ট কীভাবে লিখতে হয় সে সম্পর্কে আরও তথ্য পেতে, packages/apps/Settings/tests/robotests/README.md এই রিডমি ফাইলটি দেখুন।

প্লাগইন-স্টাইল তথ্য স্থাপত্য

প্রতিটি সেটিংস আইটেম একটি প্রেফারেন্স হিসেবে প্রয়োগ করা হয়। একটি প্রেফারেন্স সহজেই এক পৃষ্ঠা থেকে অন্য পৃষ্ঠায় সরানো যায়।

একাধিক সেটিংস সহজে স্থানান্তর করার জন্য, অ্যান্ড্রয়েড ৮.০-তে একটি প্লাগইন-স্টাইলের হোস্ট ফ্র্যাগমেন্ট চালু করা হয়েছে, যার মধ্যে সেটিংস আইটেমগুলো থাকে। সেটিংস আইটেমগুলোকে প্লাগইন-স্টাইলের কন্ট্রোলার হিসেবে মডেল করা হয়। ফলে, একটি সেটিংস পেজ একটিমাত্র হোস্ট ফ্র্যাগমেন্ট এবং একাধিক সেটিংস কন্ট্রোলার দ্বারা গঠিত হয়।

ড্যাশবোর্ডফ্র্যাগমেন্ট

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

স্থির পছন্দ

XML-এ <Preference> ট্যাগ ব্যবহার করে একটি স্ট্যাটিক প্রেফারেন্স তালিকা সংজ্ঞায়িত করা হয়। কোন XML ফাইলে প্রদর্শনের জন্য স্ট্যাটিক প্রেফারেন্স তালিকাটি রয়েছে, তা নির্ধারণ করতে একটি DashboardFragment ইমপ্লিমেন্টেশন getPreferenceScreenResId() মেথডটি ব্যবহার করে।

গতিশীল পছন্দ

একটি ডাইনামিক আইটেম হলো ইন্টেন্টসহ একটি টাইল, যা একটি বাহ্যিক বা অভ্যন্তরীণ অ্যাক্টিভিটিতে নিয়ে যায়। সাধারণত, এই ইন্টেন্টটি একটি ভিন্ন সেটিং পেজে নিয়ে যায়। উদাহরণস্বরূপ, সেটিংস হোমপেজের "Google" সেটিং আইটেমটি একটি ডাইনামিক আইটেম। ডাইনামিক আইটেমগুলো AndroidManifest এ (যা নিচে আলোচনা করা হয়েছে) সংজ্ঞায়িত করা হয় এবং একটি FeatureProvider (যা DashboardFeatureProvider হিসেবে সংজ্ঞায়িত) মাধ্যমে লোড করা হয়।

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

  • এই সেটিংটি সেটিংস অ্যাপে সরাসরি প্রয়োগ করা হয় না (যেমন OEM/ক্যারিয়ার অ্যাপ দ্বারা প্রয়োগ করা কোনো সেটিং অন্তর্ভুক্ত করা)।
  • সেটিংটি সেটিংস হোমপেজে দেখা যাবে।
  • আপনার সেটিংটির জন্য ইতিমধ্যেই একটি অ্যাক্টিভিটি রয়েছে এবং আপনি অতিরিক্ত স্ট্যাটিক কনফিগারেশনটি প্রয়োগ করতে চান না।

একটি অ্যাক্টিভিটিকে ডাইনামিক সেটিং হিসেবে কনফিগার করতে, নিম্নলিখিতগুলি করুন:

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

এখানে সেটিংস অ্যাপের DisplaySettings থেকে নেওয়া একটি উদাহরণ দেওয়া হলো।

<activity android:name="Settings$DisplaySettingsActivity"
                   android:label="@string/display_settings"
                   android:icon="@drawable/ic_settings_display">
             <!-- Mark the activity as a dynamic setting -->
              <intent-filter>
                     <action android:name="com.android.settings.action.IA_SETTINGS" />
              </intent-filter>
             <!-- Tell Settings app which category it belongs to -->
              <meta-data android:name="com.android.settings.category"
                     android:value="com.android.settings.category.ia.homepage" />
             <!-- Add a summary text when the setting is displayed -->
              <meta-data android:name="com.android.settings.summary"
                     android:resource="@string/display_dashboard_summary"/>
             </activity>

রেন্ডার করার সময়, ফ্র্যাগমেন্টটি স্ট্যাটিক XML এবং AndroidManifest এ সংজ্ঞায়িত ডাইনামিক সেটিংস উভয় থেকেই প্রেফারেন্সের একটি তালিকা চাইবে। PreferenceController গুলো জাভা কোডে বা XML-এ সংজ্ঞায়িত হোক না কেন, DashboardFragment প্রতিটি সেটিং-এর হ্যান্ডলিং লজিক PreferenceController মাধ্যমে পরিচালনা করে (যা নিচে আলোচনা করা হয়েছে)। এরপর সেগুলো UI-তে একটি মিশ্র তালিকা হিসেবে প্রদর্শিত হয়।

প্রেফারেন্স কন্ট্রোলার

এই বিভাগে যেমন বর্ণনা করা হয়েছে, অ্যান্ড্রয়েড ৯ এবং অ্যান্ড্রয়েড ৮.x-এ PreferenceController বাস্তবায়নের মধ্যে পার্থক্য রয়েছে।

অ্যান্ড্রয়েড ৯ রিলিজে PreferenceController

একটি PreferenceController প্রেফারেন্সের সাথে ইন্টারঅ্যাক্ট করার সমস্ত লজিক থাকে, যার মধ্যে প্রদর্শন, আপডেট, সার্চ ইন্ডেক্সিং ইত্যাদি অন্তর্ভুক্ত।

PreferenceController এর ইন্টারফেসটি BasePreferenceController হিসেবে সংজ্ঞায়িত করা হয়েছে। উদাহরণস্বরূপ, packages/apps/Settings/src/com/android/settings/core/ BasePreferenceController.java তে থাকা কোডটি দেখুন।

BasePreferenceController এর বেশ কয়েকটি সাবক্লাস রয়েছে, যার প্রতিটি সেটিংস অ্যাপের ডিফল্টভাবে সমর্থিত একটি নির্দিষ্ট UI স্টাইলের সাথে ম্যাপ করা থাকে। উদাহরণস্বরূপ, TogglePreferenceController একটি API আছে যা সরাসরি নির্দেশ করে যে একজন ব্যবহারকারী একটি টগল-ভিত্তিক প্রেফারেন্স UI-এর সাথে কীভাবে ইন্টারঅ্যাক্ট করবে।

BasePreferenceController getAvailabilityStatus() , displayPreference() , handlePreferenceTreeClicked(), ইত্যাদির মতো API রয়েছে। প্রতিটি API-এর বিস্তারিত ডকুমেন্টেশন ইন্টারফেস ক্লাসে দেওয়া আছে।

BasePreferenceController (এবং এর সাবক্লাস যেমন TogglePreferenceController ) ইমপ্লিমেন্ট করার ক্ষেত্রে একটি সীমাবদ্ধতা হলো যে, কনস্ট্রাক্টরের সিগনেচার অবশ্যই নিম্নলিখিতগুলির যেকোনো একটির সাথে মিলতে হবে:

  • public MyController(Context context, String key) {}
  • public MyController(Context context) {}

ফ্র্যাগমেন্টে কোনো প্রেফারেন্স ইনস্টল করার সময়, ড্যাশবোর্ড প্রদর্শনের পূর্বে একটি PreferenceController সংযুক্ত করার একটি পদ্ধতি প্রদান করে। ইনস্টলের সময়েই কন্ট্রোলারটিকে ফ্র্যাগমেন্টের সাথে সংযুক্ত করে দেওয়া হয়, ফলে ভবিষ্যতের সমস্ত প্রাসঙ্গিক ইভেন্ট কন্ট্রোলারে পাঠানো হয়।

DashboardFragment স্ক্রিনে PreferenceController একটি তালিকা রাখে। ফ্র্যাগমেন্টের onCreate() ইভেন্টে, সমস্ত কন্ট্রোলারের getAvailabilityStatus() মেথড কল করা হয়, এবং যদি এটি true রিটার্ন করে, তাহলে ডিসপ্লে লজিক প্রসেস করার জন্য displayPreference() কল করা হয়। সার্চ করার সময় কোন আইটেমগুলো উপলব্ধ আছে, তা সেটিংস ফ্রেমওয়ার্ককে জানানোর জন্যও getAvailabilityStatus() গুরুত্বপূর্ণ।

অ্যান্ড্রয়েড 8.x রিলিজগুলিতে PreferenceController

একটি PreferenceController প্রেফারেন্সের সাথে ইন্টারঅ্যাক্ট করার সমস্ত লজিক থাকে, যার মধ্যে প্রদর্শন, আপডেট, সার্চ ইন্ডেক্সিং ইত্যাদি অন্তর্ভুক্ত।

প্রেফারেন্স ইন্টারঅ্যাকশনগুলোর সাথে সঙ্গতি রেখে, PreferenceController এর ইন্টারফেসে isAvailable() , displayPreference() , handlePreferenceTreeClicked() ইত্যাদি API রয়েছে। প্রতিটি API-এর বিস্তারিত ডকুমেন্টেশন ইন্টারফেস ক্লাসে পাওয়া যাবে।

ফ্র্যাগমেন্টে কোনো প্রেফারেন্স ইনস্টল করার সময়, ড্যাশবোর্ড প্রদর্শনের পূর্বে একটি PreferenceController সংযুক্ত করার একটি পদ্ধতি প্রদান করে। ইনস্টলের সময়েই কন্ট্রোলারটিকে ফ্র্যাগমেন্টের সাথে সংযুক্ত করে দেওয়া হয়, ফলে ভবিষ্যতের সমস্ত প্রাসঙ্গিক ইভেন্ট কন্ট্রোলারে পাঠানো হয়।

DashboardFragment স্ক্রিনে PreferenceControllers একটি তালিকা রাখে। ফ্র্যাগমেন্টটির onCreate() ইভেন্টে, সমস্ত কন্ট্রোলারের isAvailable() মেথড কল করা হয়, এবং যদি এটি true রিটার্ন করে, তাহলে ডিসপ্লে লজিক প্রসেস করার জন্য displayPreference() মেথডটি কল করা হয়।

ড্যাশবোর্ডফ্র্যাগমেন্ট ব্যবহার করুন

পৃষ্ঠা A থেকে B-তে একটি পছন্দ স্থানান্তর করুন

যদি প্রেফারেন্সটি মূল পেজের প্রেফারেন্স XML ফাইলে স্থিরভাবে তালিকাভুক্ত থাকে, তাহলে নিচে আপনার অ্যান্ড্রয়েড রিলিজের জন্য দেওয়া স্ট্যাটিক মুভ পদ্ধতি অনুসরণ করুন। অন্যথায়, আপনার অ্যান্ড্রয়েড রিলিজের জন্য দেওয়া ডাইনামিক মুভ পদ্ধতি অনুসরণ করুন।

অ্যান্ড্রয়েড ৯-এ স্ট্যাটিক মুভ

  1. মূল পৃষ্ঠা এবং গন্তব্য পৃষ্ঠার জন্য প্রেফারেন্স XML ফাইলগুলো খুঁজুন। আপনি পৃষ্ঠার getPreferenceScreenResId() মেথড থেকে এই তথ্যটি পেতে পারেন।
  2. মূল পৃষ্ঠার XML থেকে প্রেফারেন্সটি সরিয়ে ফেলুন।
  3. গন্তব্য পৃষ্ঠার XML-এ প্রেফারেন্সটি যোগ করুন।
  4. মূল পেজের জাভা ইমপ্লিমেন্টেশন থেকে এই প্রেফারেন্সের জন্য PreferenceController টি সরিয়ে ফেলুন। সাধারণত এটি createPreferenceControllers() ফাংশনের মধ্যে থাকে। কন্ট্রোলারটি সরাসরি XML-এও ডিক্লেয়ার করা থাকতে পারে।

    দ্রষ্টব্য : প্রেফারেন্সটির কোনো PreferenceController নাও থাকতে পারে।

  5. গন্তব্য পৃষ্ঠার createPreferenceControllers() ফাংশনে PreferenceController ইনস্ট্যানশিয়েট করুন। যদি পুরোনো পৃষ্ঠার XML-এ PreferenceController সংজ্ঞায়িত করা থাকে, তবে নতুন পৃষ্ঠার XML-এও এটি সংজ্ঞায়িত করুন।

অ্যান্ড্রয়েড ৯-এ ডাইনামিক মুভ

  1. মূল এবং গন্তব্য পৃষ্ঠা কোন ক্যাটাগরির অন্তর্ভুক্ত তা খুঁজে বের করুন। এই তথ্যটি আপনি DashboardFragmentRegistry তে খুঁজে পাবেন।
  2. যে সেটিংটি সরাতে হবে, সেটি থাকা AndroidManifest.xml ফাইলটি খুলুন এবং এই সেটিংটির প্রতিনিধিত্বকারী Activity এন্ট্রিটি খুঁজুন।
  3. অ্যাক্টিভিটির মেটাডেটা ভ্যালু হিসেবে com.android.settings.category কে নতুন পেজের category কী-তে সেট করুন।

অ্যান্ড্রয়েড ৮.x রিলিজগুলিতে স্ট্যাটিক মুভ

  1. মূল পৃষ্ঠা এবং গন্তব্য পৃষ্ঠার জন্য প্রেফারেন্স XML ফাইলগুলো খুঁজুন।
  2. আপনি পেজটির getPreferenceScreenResId() মেথড থেকে এই তথ্যটি পেতে পারেন।
  3. মূল পৃষ্ঠার XML থেকে প্রেফারেন্সটি সরিয়ে ফেলুন।
  4. গন্তব্য পৃষ্ঠার XML-এ প্রেফারেন্সটি যোগ করুন।
  5. মূল পেজের জাভা ইমপ্লিমেন্টেশন থেকে এই প্রেফারেন্সের জন্য PreferenceController টি সরিয়ে ফেলুন। সাধারণত এটি getPreferenceControllers() মধ্যে থাকে।
  6. দ্রষ্টব্য: এমন হতে পারে যে প্রেফারেন্সটির কোনো PreferenceController নেই।

  7. গন্তব্য পৃষ্ঠার getPreferenceControllers() ফাংশনে PreferenceController টি ইনস্ট্যানশিয়েট করুন।

অ্যান্ড্রয়েড ৮.x রিলিজগুলিতে ডাইনামিক মুভ

  1. মূল এবং গন্তব্য পৃষ্ঠা কোন ক্যাটাগরির অন্তর্ভুক্ত তা খুঁজে বের করুন। এই তথ্যটি আপনি DashboardFragmentRegistry তে খুঁজে পাবেন।
  2. যে সেটিংটি সরাতে হবে, সেটি থাকা AndroidManifest.xml ফাইলটি খুলুন এবং এই সেটিংটির প্রতিনিধিত্বকারী Activity এন্ট্রিটি খুঁজুন।
  3. অ্যাক্টিভিটির com.android.settings.category মেটাডেটা ভ্যালুটি পরিবর্তন করুন এবং ভ্যালুটি নতুন পেজের category কী-এর দিকে নির্দেশ করে সেট করুন।

একটি পৃষ্ঠায় একটি নতুন পছন্দ তৈরি করুন

যদি প্রেফারেন্সটি মূল পেজের প্রেফারেন্স XML ফাইলে স্থিরভাবে তালিকাভুক্ত থাকে, তাহলে নিচের স্ট্যাটিক পদ্ধতিটি অনুসরণ করুন। অন্যথায় ডাইনামিক পদ্ধতিটি অনুসরণ করুন।

একটি স্থির পছন্দ তৈরি করুন

  1. পেজটির জন্য প্রেফারেন্স XML ফাইলগুলো খুঁজুন। আপনি পেজটির getPreferenceScreenResId() মেথড থেকে এই তথ্যটি পেতে পারেন।
  2. XML-এ একটি নতুন Preference আইটেম যোগ করুন। নিশ্চিত করুন যে এটির একটি অনন্য android:key আছে।
  3. পেজের getPreferenceControllers() মেথডে এই প্রেফারেন্সের জন্য একটি PreferenceController সংজ্ঞায়িত করুন।
    • Android 8.x-এ এবং ঐচ্ছিকভাবে Android 9-এ, পেজের createPreferenceControllers() মেথডে এই প্রেফারেন্সের জন্য একটি PreferenceController ইনস্ট্যানশিয়েট করুন।

      যদি এই প্রেফারেন্সটি আগে থেকেই অন্য কোথাও বিদ্যমান থাকে, তাহলে সম্ভবত এর জন্য ইতিমধ্যেই একটি PreferenceController রয়েছে। আপনি নতুন করে তৈরি না করেই PreferenceController টি পুনরায় ব্যবহার করতে পারেন।

    • অ্যান্ড্রয়েড ৯ থেকে, আপনি প্রেফারেন্সের পাশে XML-এ PreferenceController ঘোষণা করার বিকল্পটি বেছে নিতে পারেন। উদাহরণস্বরূপ:
      <Preference
              android:key="reset_dashboard"
              android:title="@string/reset_dashboard_title"
              settings:controller="com.android.settings.system.ResetPreferenceController"/>

একটি গতিশীল পছন্দ তৈরি করুন

  1. মূল এবং গন্তব্য পৃষ্ঠা কোন ক্যাটাগরির অন্তর্ভুক্ত তা খুঁজে বের করুন। এই তথ্যটি আপনি DashboardFragmentRegistry তে খুঁজে পাবেন।
  2. AndroidManifest এ একটি নতুন Activity তৈরি করুন
  3. সেটিংটি নির্ধারণ করতে নতুন অ্যাক্টিভিটিতে প্রয়োজনীয় মেটাডেটা যোগ করুন। com.android.settings.category এর মেটাডেটা মানটি ধাপ ১-এ নির্ধারিত মানের সমান করে সেট করুন।

একটি নতুন পৃষ্ঠা তৈরি করুন

  1. DashboardFragment থেকে উত্তরাধিকার সূত্রে একটি নতুন ফ্র্যাগমেন্ট তৈরি করুন।
  2. DashboardFragmentRegistry তে এর ক্যাটাগরি নির্ধারণ করুন।

    দ্রষ্টব্য: এই ধাপটি ঐচ্ছিক। এই পৃষ্ঠায় আপনার কোনো ডাইনামিক প্রেফারেন্সের প্রয়োজন না হলে, ক্যাটাগরি কী প্রদান করার প্রয়োজন নেই।

  3. এই পৃষ্ঠার জন্য প্রয়োজনীয় সেটিংস যোগ করতে ধাপগুলো অনুসরণ করুন। আরও তথ্যের জন্য, বাস্তবায়ন বিভাগটি দেখুন।

বৈধতা

  • সেটিংসে রোবোইলেকট্রিক পরীক্ষাগুলো চালান। বিদ্যমান ও নতুন সব পরীক্ষাই সফল হতে হবে।
  • সেটিংস তৈরি ও ইনস্টল করুন, তারপর যে পৃষ্ঠাটি পরিবর্তন করতে চান সেটি ম্যানুয়ালি খুলুন। পৃষ্ঠাটি সঙ্গে সঙ্গে আপডেট হয়ে যাবে।