สถาปัตยกรรมสารสนเทศ

Android 8.0 เปิดตัวสถาปัตยกรรมข้อมูลแบบใหม่สำหรับแอปการตั้งค่าเพื่อ ลดความซับซ้อนของวิธีจัดระเบียบการตั้งค่า และช่วยให้ผู้ใช้ ค้นหาการตั้งค่าเพื่อปรับแต่งอุปกรณ์ Android ได้อย่างรวดเร็ว Android 9 ได้เปิดตัวการปรับปรุงบางอย่างเพื่อมอบรางวัลเพิ่มเติม ฟังก์ชันการตั้งค่าและการใช้งานที่ง่ายขึ้น

ตัวอย่างและแหล่งที่มา

ปัจจุบันหน้าเว็บส่วนใหญ่ในการตั้งค่ามีการใช้งานโดยใช้เฟรมเวิร์กใหม่ ระดับพอดี ตัวอย่างเช่น DisplaySettings packages/apps/Settings/src/com/android/settings/DisplaySettings.java

เส้นทางไฟล์สําหรับคอมโพเนนต์สําคัญมีดังนี้

  • CategoryKey: packages/SettingsLib/src/com/android/settingslib/drawer/CategoryKey.java
  • dashboardFragmentRegistry มีดังนี้ packages/apps/Settings/src/com/android/settings/dashboard/DashboardFragmentRegistry.java
  • dashboardFragment: packages/apps/Settings/src/com/android/settings/dashboard/DashboardFragment.java
  • AbstractPreferenceController: frameworks/base/packages/SettingsLib/src/com/android/settingslib/core/AbstractPreferenceController.java
  • BasePreferenceController (เปิดตัวใน Android 9) packages/apps/Settings/src/com/android/settings/core/BasePreferenceController.java

การใช้งาน

ขอแนะนำให้ผู้ผลิตอุปกรณ์ปรับเปลี่ยนข้อมูลการตั้งค่าที่มีอยู่ สถาปัตยกรรมและแทรกหน้าการตั้งค่าเพิ่มเติม ตามความจำเป็น ฟีเจอร์เฉพาะพาร์ทเนอร์ การย้ายค่ากำหนดจากหน้าเดิม (ใช้งานเป็น SettingsPreferencePage) ไปยังหน้าใหม่ (ใช้งานโดยใช้ DashboardFragment) อาจมีความซับซ้อน ค่ากำหนดจาก หน้าเดิมน่าจะไม่ได้ติดตั้งใช้งานกับ PreferenceController

ดังนั้นเมื่อย้ายค่ากำหนดจากหน้าเดิมไปยังหน้าใหม่ คุณต้องสร้าง PreferenceControllerและย้ายโค้ดไปไว้ในตัวควบคุมก่อน กำลังสร้างอินสแตนซ์ใน DashboardFragment ใหม่ API ที่ อธิบายข้อกำหนด PreferenceController ในชื่อและ เป็นเอกสารใน Javadoc

ขอแนะนำให้เพิ่มการทดสอบ 1 หน่วยสำหรับ PreferenceController แต่ละรายการ หากส่งการเปลี่ยนแปลงไปยัง AOSP คุณต้องทำการทดสอบ 1 หน่วย หากต้องการข้อมูลเพิ่มเติมเกี่ยวกับวิธีเขียนการทดสอบที่อิงตาม Robolectric โปรดดูที่ ไฟล์ Readme packages/apps/Settings/tests/robotests/README.md

สถาปัตยกรรมข้อมูลในรูปแบบปลั๊กอิน

ระบบจะใช้การตั้งค่าแต่ละรายการเป็นค่ากำหนด ค่ากำหนดสามารถ ย้ายจากหน้าหนึ่งไปยังอีกหน้าหนึ่ง

Android 8.0 ได้เปิดตัวการตั้งค่าต่างๆ เพื่อให้สามารถย้ายการตั้งค่าต่างๆ ได้ง่ายขึ้น ส่วนย่อยของโฮสต์รูปแบบปลั๊กอินที่มีรายการการตั้งค่า รายการการตั้งค่าคือ โมเดลดังกล่าวเป็นตัวควบคุมรูปแบบปลั๊กอิน หน้าการตั้งค่าจึงสร้างขึ้นโดย ส่วนย่อยของโฮสต์เดียวและตัวควบคุมการตั้งค่าหลายรายการ

ส่วนย่อยของแดชบอร์ด

DashboardFragment เป็นโฮสต์ของตัวควบคุมค่ากำหนดรูปแบบปลั๊กอิน ส่วนย่อยมาจาก PreferenceFragment และมีฮุกไปยัง ขยายและอัปเดตทั้งรายการค่ากำหนดแบบคงที่และรายการค่ากำหนดแบบไดนามิก

ค่ากำหนดแบบคงที่

รายการค่ากำหนดแบบคงที่กำหนดไว้ใน XML โดยใช้แท็ก <Preference> ต การใช้งาน DashboardFragment ใช้เมธอด getPreferenceScreenResId() เมธอดในการกำหนดว่าไฟล์ XML ใดมี รายการค่ากำหนดแบบคงที่ที่จะแสดง

ค่ากำหนดแบบไดนามิก

รายการแบบไดนามิกแสดงการ์ดที่มีความตั้งใจ ซึ่งนำไปสู่โฆษณาภายนอกหรือภายใน กิจกรรม โดยปกติแล้ว Intent จะนำไปยังหน้าการตั้งค่าอื่น ตัวอย่างเช่น "Google" รายการการตั้งค่าในหน้าแรกของการตั้งค่าเป็นรายการแบบไดนามิก ไดนามิก รายการได้รับการกำหนดไว้ใน AndroidManifest (กล่าวถึงด้านล่าง) และโหลดแล้ว ผ่าน FeatureProvider (หมายถึง DashboardFeatureProvider)

การตั้งค่าแบบไดนามิกนั้นใช้ภาระงานหนักกว่าการกำหนดค่าแบบคงที่ ดังนั้นตามปกติแล้วนักพัฒนาซอฟต์แวร์ควรใช้การตั้งค่าแบบคงที่ อย่างไรก็ตาม การตั้งค่าแบบไดนามิกอาจมีประโยชน์เมื่อเงื่อนไขใดๆ ต่อไปนี้เป็นจริง

  • การตั้งค่านี้ไม่มีการใช้งานในแอปการตั้งค่าโดยตรง (เช่น การแทรกการตั้งค่าที่ใช้งานโดยแอป OEM/ผู้ให้บริการ)
  • การตั้งค่านี้ควรปรากฏในหน้าแรกของการตั้งค่า
  • คุณมีกิจกรรมสำหรับการตั้งค่านี้อยู่แล้ว และไม่ต้องการใช้ การกำหนดค่าแบบคงที่เพิ่มเติม

ในการกำหนดค่ากิจกรรมเป็นการตั้งค่าแบบไดนามิก ให้ทำดังนี้

  • ทำเครื่องหมายกิจกรรมเป็นการตั้งค่าแบบไดนามิกโดยเพิ่มตัวกรอง Intent ลงใน กิจกรรม
  • บอกให้แอปการตั้งค่าอยู่ในหมวดหมู่ใด หมวดหมู่เป็นค่าคงที่ กำหนดไว้ใน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 ได้รับการกำหนดไว้ในโค้ด Java หรือใน XML DashboardFragment จะจัดการตรรกะการจัดการของการตั้งค่าแต่ละรายการ ถึง PreferenceController (กล่าวถึงด้านล่าง) แล้วก็คือ แสดงใน UI เป็นรายการแบบผสม

PreferenceController

การติดตั้งใช้งาน PreferenceController นั้นแตกต่างกัน ใน Android 9 และ Android 8.x ตามที่อธิบายไว้ใน

PreferenceController ใน Android 9 รุ่น

PreferenceController มีตรรกะทั้งหมดในการโต้ตอบกับ ค่ากำหนด ซึ่งรวมถึงการแสดง การอัปเดต การจัดทำดัชนีการค้นหา ฯลฯ

อินเทอร์เฟซของ PreferenceController คือ BasePreferenceController ตัวอย่างเช่น ดูโค้ดใน packages/apps/Settings/src/com/android/settings/core/ BasePreferenceController.java

มีคลาสย่อยของ BasePreferenceController อยู่หลายคลาส แต่ละคลาส การแมปกับรูปแบบ UI ที่เฉพาะเจาะจงซึ่งแอปการตั้งค่ารองรับโดยค่าเริ่มต้น สำหรับ ตัวอย่างเช่น TogglePreferenceController มี API ที่แมปโดยตรง วิธีที่ผู้ใช้ควรโต้ตอบกับ UI ค่ากำหนดแบบสลับ

BasePreferenceController มี API เช่น getAvailabilityStatus() displayPreference() handlePreferenceTreeClicked(), ฯลฯ เอกสารโดยละเอียดสำหรับแต่ละ API อยู่ในคลาสอินเทอร์เฟซ

ข้อจำกัดในการใช้ BasePreferenceController (และ คลาสย่อย เช่น TogglePreferenceController) คือ ลายเซ็นของเครื่องมือสร้างต้องตรงกับรายการใดรายการหนึ่งต่อไปนี้

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

ขณะติดตั้งค่ากำหนดลงในส่วนย่อย หน้าแดชบอร์ดมีวิธีในการ แนบ PreferenceController ก่อนเวลาแสดง ณ เวลาติดตั้ง ตัวควบคุมต่อสายไฟเข้ากับส่วนย่อย ดังนั้นเหตุการณ์ที่เกี่ยวข้องในอนาคตทั้งหมดจึง ที่ส่งไปยังตัวควบคุม

DashboardFragment เก็บรายการ PreferenceControllerในหน้าจอ ที่แท็ก Fragment onCreate() ระบบจะเรียกใช้ตัวควบคุมทั้งหมดสำหรับ getAvailabilityStatus() และหากแสดงเป็น "จริง" เรียกใช้ displayPreference() เพื่อประมวลผลตรรกะการแสดงผล getAvailabilityStatus()ก็สำคัญต่อการบอกการตั้งค่า กำหนดรายการที่จะแสดงขณะค้นหา

PreferenceController ใน Android 8.x รุ่น

PreferenceController มีตรรกะทั้งหมดในการโต้ตอบกับ ค่ากำหนด ซึ่งรวมถึงการแสดง การอัปเดต การจัดทำดัชนีการค้นหา อื่นๆ

อินเทอร์เฟซของ PreferenceController มี API isAvailable(), displayPreference(), handlePreferenceTreeClicked() ฯลฯ เพื่อให้สอดคล้องกับการโต้ตอบของค่ากำหนด ดูเอกสารประกอบโดยละเอียดเกี่ยวกับ API แต่ละรายการได้ในคลาสอินเทอร์เฟซ

ขณะติดตั้งค่ากำหนดลงในส่วนย่อย หน้าแดชบอร์ดมีวิธีในการ แนบ PreferenceController ก่อนเวลาแสดง ณ เวลาติดตั้ง ตัวควบคุมต่อสายไฟเข้ากับส่วนย่อย ดังนั้นเหตุการณ์ที่เกี่ยวข้องในอนาคตทั้งหมดจึง ที่ส่งไปยังตัวควบคุม

DashboardFragment จะแสดงรายการ PreferenceControllers ไว้ในหน้าจอ ที่ onCreate() ของส่วนย่อย, ทั้งหมด คอนโทรลเลอร์จะถูกเรียกใช้สำหรับเมธอด isAvailable() และ ส่งคืนค่าจริง ระบบจะเรียกใช้ displayPreference() เพื่อประมวลผลการแสดงผล

ใช้ DashboardFragment

ย้ายค่ากำหนดจากหน้า A ไป B

หากค่ากำหนดนั้นระบุแบบคงที่ใน XML ค่ากำหนดของหน้าเดิม ให้ทำตามขั้นตอนการย้ายแบบคงที่สำหรับ Android ของคุณ ด้านล่าง หรือทําตามขั้นตอนการย้ายแบบไดนามิก สำหรับรุ่น Android ของคุณ

การเคลื่อนไหวแบบคงที่ใน Android 9

  1. ค้นหาไฟล์ XML ค่ากำหนดสำหรับหน้าเดิมและปลายทาง คุณดูข้อมูลนี้ได้จาก getPreferenceScreenResId() วิธี
  2. นำค่ากำหนดออกจาก XML ของหน้าเดิม
  3. เพิ่มค่ากำหนดใน XML ของหน้าปลายทาง
  4. นำ PreferenceController สำหรับค่ากำหนดนี้ออกจาก การใช้ Java ของหน้าเว็บเดิม โดยปกติจะอยู่ใน createPreferenceControllers() ตัวควบคุมอาจมีการประกาศใน XML โดยตรง

    หมายเหตุ: ค่ากำหนดอาจไม่มีค่า PreferenceController

  5. สร้างอินสแตนซ์ PreferenceController ในแท็กของหน้าปลายทาง createPreferenceControllers() หาก PreferenceController กำหนดไว้ใน XML ในหน้าเก่า กำหนด ใน XML สำหรับหน้าใหม่ด้วย

การเคลื่อนไหวแบบไดนามิกใน Android 9

  1. ค้นหาหมวดหมู่ที่โฮสต์หน้าเดิมและหน้าปลายทาง คุณสามารถ หาข้อมูลนี้ได้ใน DashboardFragmentRegistry
  2. เปิดไฟล์ AndroidManifest.xml ที่มีการตั้งค่าที่คุณ ต้องย้ายและค้นหารายการกิจกรรมที่แสดงการตั้งค่านี้
  3. ตั้งค่าข้อมูลเมตาของกิจกรรมสำหรับ com.android.settings.category ไปยังคีย์หมวดหมู่ของหน้าใหม่

การเคลื่อนไหวแบบคงที่ใน Android 8.x รุ่น

  1. ค้นหาไฟล์ XML ค่ากำหนดสำหรับหน้าเดิมและหน้าปลายทาง
  2. คุณดูข้อมูลนี้ได้จากเมธอด getPreferenceScreenResId() ของหน้าเว็บ
  3. นำค่ากำหนดใน XML ของหน้าเดิมออก
  4. เพิ่มค่ากำหนดใน XML ของหน้าปลายทาง
  5. นำ PreferenceController สำหรับค่ากำหนดนี้ออกใน การใช้ Java ของหน้าเว็บเดิม โดยปกติจะอยู่ที่ getPreferenceControllers()
  6. หมายเหตุ: อาจเป็นไปได้ว่าค่ากำหนดดังกล่าวไม่มี PreferenceController

  7. สร้างอินสแตนซ์ PreferenceController ในแท็กของหน้าปลายทาง getPreferenceControllers()

การเคลื่อนไหวแบบไดนามิกใน Android 8.x รุ่น

  1. ค้นหาหมวดหมู่ที่โฮสต์หน้าเดิมและหน้าปลายทาง คุณดู ข้อมูลนี้ใน DashboardFragmentRegistry
  2. เปิดไฟล์ AndroidManifest.xml ที่มีการตั้งค่าที่คุณ ต้องย้ายและค้นหารายการกิจกรรมที่แสดงการตั้งค่านี้
  3. เปลี่ยนค่าข้อมูลเมตาของกิจกรรมสำหรับ com.android.settings.category กำหนดจุดค่าเป็นคีย์หมวดหมู่ของหน้าใหม่

สร้างค่ากำหนดใหม่ในหน้าเว็บ

หากค่ากำหนดนั้นระบุแบบคงที่ใน XML ค่ากำหนดของหน้าเดิม โปรดทำตามขั้นตอนแบบคงที่ด้านล่าง หรือทำตาม ไดนามิก

สร้างค่ากำหนดแบบคงที่

  1. ค้นหาไฟล์ XML ค่ากำหนดสำหรับหน้านั้น คุณดูข้อมูลนี้ได้ จากเมธอด getPreferenceScreenResId() ของหน้าเว็บ
  2. เพิ่มรายการค่ากำหนดใหม่ใน XML โปรดตรวจสอบว่ามี android:key ที่ไม่ซ้ำกัน
  3. กำหนด PreferenceController สำหรับค่ากำหนดนี้ในองค์ประกอบ getPreferenceControllers() วิธี
    • ใน Android 8.x และ Android 9 (ไม่บังคับ) สร้างอินสแตนซ์ PreferenceController สำหรับค่ากำหนดนี้ใน เมธอด createPreferenceControllers() ของหน้าเว็บ

      หากมีค่ากำหนดนี้อยู่แล้วในที่อื่น อาจเป็นไปได้ว่า PreferenceControllerอยู่แล้ว คุณสามารถใช้ PreferenceController โดยไม่ต้องสร้างใหม่

    • ตั้งแต่ Android 9 เป็นต้นไป คุณเลือกที่จะประกาศ PreferenceController ใน XML ถัดจากค่ากำหนด ดังตัวอย่างต่อไปนี้
      <Preference
              android:key="reset_dashboard"
              android:title="@string/reset_dashboard_title"
              settings:controller="com.android.settings.system.ResetPreferenceController"/>
      

สร้างค่ากำหนดแบบไดนามิก

  1. ค้นหาหมวดหมู่ที่โฮสต์หน้าเดิมและหน้าปลายทาง คุณดู ข้อมูลนี้ใน DashboardFragmentRegistry
  2. สร้างกิจกรรมใหม่ใน AndroidManifest
  3. เพิ่มข้อมูลเมตาที่จำเป็นลงในกิจกรรมใหม่เพื่อกำหนดการตั้งค่า ตั้งค่า ค่าข้อมูลเมตาสำหรับ com.android.settings.category เป็นค่าเดียวกัน ที่กำหนดไว้ในขั้นตอนที่ 1

สร้างเพจใหม่

  1. สร้างส่วนย่อยใหม่ โดยรับค่าจาก DashboardFragment
  2. กำหนดหมวดหมู่ใน DashboardFragmentRegistry

    หมายเหตุ: นี่คือขั้นตอนที่ไม่บังคับ หากคุณไม่ต้องการ ค่ากำหนดแบบไดนามิกใดๆ ในหน้านี้ คุณไม่จำเป็นต้องระบุคีย์หมวดหมู่

  3. ทําตามขั้นตอนเพื่อเพิ่มการตั้งค่าที่จําเป็นสําหรับหน้านี้ สำหรับข้อมูลเพิ่มเติม โปรดดูที่ส่วนการใช้งาน

การตรวจสอบความถูกต้อง

  • ทำการทดสอบแบบ Robolectric ในการตั้งค่า การทดสอบที่มีอยู่และการทดสอบใหม่ทั้งหมดควร
  • สร้างและติดตั้งการตั้งค่า แล้วเปิดหน้าเว็บที่แก้ไขด้วยตนเอง หน้าเว็บควรอัปเดตทันที