การสร้าง APK หลายรายการสำหรับพื้นผิว GL ที่แตกต่างกัน

หากเผยแพร่แอปใน Google Play คุณควรสร้างและอัปโหลด Android App Bundle เมื่อคุณเผยแพร่ APK หลายรายการ Google Play จะสร้างและแสดง APK ที่เพิ่มประสิทธิภาพแล้วโดยอัตโนมัติสำหรับการกำหนดค่าอุปกรณ์ของผู้ใช้แต่ละราย เพื่อให้ผู้ใช้ดาวน์โหลดเฉพาะโค้ดและทรัพยากรที่จำเป็นต่อการใช้งานแอปของคุณ การเผยแพร่ APK หลายรายการมีประโยชน์ในกรณีที่คุณไม่ได้เผยแพร่แอปใน Google Play แต่ต้องสร้าง รับรอง และจัดการ APK แต่ละรายการด้วยตนเอง

เมื่อพัฒนาแอปพลิเคชัน Android เพื่อใช้ประโยชน์จาก APK หลายรายการใน Google Play คุณควรใช้แนวทางปฏิบัติแนะนำตั้งแต่เริ่มต้น เพื่อหลีกเลี่ยงปัญหาที่ไม่จำเป็นในกระบวนการพัฒนาแอป บทเรียนนี้จะแสดงวิธีสร้าง APK หลายรายการของแอป โดยแต่ละรายการรองรับรูปแบบพื้นผิว OpenGL ชุดย่อยที่แตกต่างกัน นอกจากนี้ คุณยังจะได้รับเครื่องมือที่จําเป็นในการทำให้การดูแลรักษาโค้ดฐาน APK หลายรายการเป็นไปอย่างราบรื่นที่สุด

ยืนยันว่าคุณต้องการ APK หลายรายการ

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

หากคุณจัดการได้ การจำกัดแอปพลิเคชันของคุณให้อยู่ใน APK เดียวมีข้อดีหลายประการ ได้แก่

  • การเผยแพร่และการทดสอบทำได้ง่ายขึ้น
  • มีฐานโค้ดเพียงฐานเดียวที่ต้องดูแลรักษา
  • แอปพลิเคชันสามารถปรับตัวตามการเปลี่ยนแปลงการกำหนดค่าอุปกรณ์
  • กู้คืนแอปในอุปกรณ์ต่างๆ ได้
  • หมดห่วงเรื่องความชื่นชอบของตลาด พฤติกรรมจาก "การอัปเกรด" จาก APK หนึ่งไปยัง APK ถัดไป หรือ APK ที่ใช้กับอุปกรณ์ระดับใด

ส่วนที่เหลือของบทนี้จะถือว่าคุณได้ค้นคว้าหัวข้อนี้ ศึกษาเนื้อหาในแหล่งข้อมูลที่ลิงก์มาอย่างละเอียด และพิจารณาแล้วว่า APK หลายรายการเป็นเส้นทางที่เหมาะสมสำหรับแอปพลิเคชันของคุณ

ทำแผนภูมิข้อกำหนดของคุณ

คู่มือนักพัฒนาซอฟต์แวร์ Android มีข้อมูลอ้างอิงที่เป็นประโยชน์เกี่ยวกับพื้นผิวที่รองรับทั่วไปบางส่วนในหน้า support-gl-texture หน้านี้ยังมีคำแนะนำบางอย่างเกี่ยวกับโทรศัพท์ (หรือตระกูลโทรศัพท์) ที่รองรับรูปแบบพื้นผิวหนึ่งๆ ด้วย โปรดทราบว่าโดยทั่วไปควรให้ APK รายการหนึ่งของคุณรองรับ ETC1 เนื่องจากอุปกรณ์ที่ใช้ Android ทั้งหมดรองรับข้อมูลจำเพาะของ OpenGL ES 2.0

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

ETC1 ATI PowerVR

การระบายสีในแผนภูมิไม่เพียงทำให้คู่มือนี้ดูมีสีสันมากขึ้นเท่านั้น แต่ยังช่วยให้การสื่อสารภายในทีมง่ายขึ้นด้วย ตอนนี้คุณเรียก APK แต่ละรายการว่า "น้ำเงิน" "เขียว" หรือ "แดง" แทนที่จะเรียก "เวอร์ชันที่รองรับรูปแบบพื้นผิว ETC1" ฯลฯ ก็ได้

นำโค้ดและทรัพยากรทั่วไปทั้งหมดไปวางในโปรเจ็กต์ไลบรารี

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

หมายเหตุ: แม้ว่ารายละเอียดการใช้งานเกี่ยวกับวิธีสร้างและรวมโปรเจ็กต์ไลบรารีจะอยู่นอกขอบเขตของบทเรียนนี้ แต่คุณสามารถทบทวนข้อมูลได้โดยอ่านหัวข้อสร้างไลบรารี Android

หากคุณแปลงแอปพลิเคชันที่มีอยู่ให้รองรับ APK หลายรายการ ให้ค้นหาไฟล์สตริงที่แปลแล้วทุกไฟล์ รายการค่า สีธีม ไอคอนเมนู และเลย์เอาต์ที่จะไม่เปลี่ยนแปลงใน APK ต่างๆ แล้วใส่ทั้งหมดไว้ในโปรเจ็กต์ไลบรารี โค้ดที่จะเปลี่ยนแปลงไม่มากนักควรอยู่ในโปรเจ็กต์ไลบรารีด้วย คุณอาจพบว่าตัวเองขยายคลาสเหล่านี้ เพื่อเพิ่ม 1-2 เมธอดจาก APK ไปยัง APK

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

สร้างโปรเจ็กต์ APK ใหม่

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

alexlucas:~/code/multi-apks-root$ ls
foo-blue
foo-green
foo-lib
foo-red

เมื่อสร้างโปรเจ็กต์แล้ว ให้เพิ่มโปรเจ็กต์คลังเป็นข้อมูลอ้างอิงสำหรับโปรเจ็กต์ APK แต่ละโปรเจ็กต์ หากเป็นไปได้ ให้กำหนดกิจกรรมเริ่มต้นในโปรเจ็กต์คลัง และขยายกิจกรรมนั้นในโปรเจ็กต์ APK การกําหนดกิจกรรมเริ่มต้นในโปรเจ็กต์ไลบรารีช่วยให้คุณรวมการเริ่มต้นแอปพลิเคชันทั้งหมดไว้ในที่เดียวได้ เพื่อให้แต่ละ APK ไม่จำเป็นต้องใช้งาน "สากล" ซ้ำ เช่น การเริ่มต้น Analytics, การตรวจสอบการอนุญาตให้ใช้สิทธิ และกระบวนการเริ่มต้นอื่นๆ ที่ไม่ได้เปลี่ยนแปลงมากนักจาก APK หนึ่งไปยังอีก APK หนึ่ง

ปรับไฟล์ Manifest

เมื่อผู้ใช้ดาวน์โหลดแอปพลิเคชันที่ใช้ APK หลายรายการผ่าน Google Play ระบบจะเลือก APK ที่ถูกต้องให้โดยใช้กฎง่ายๆ ดังนี้

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

กฎข้อสุดท้ายนี้สำคัญอย่างยิ่งสำหรับพื้นผิว GL ซึ่งหมายความว่าคุณควรระมัดระวังอย่างยิ่งในการใช้รูปแบบ GL ที่แตกต่างกันในแอปพลิเคชันเดียวกัน หากคุณใช้ PowerVR 99% ของเวลา แต่ใช้ ETC1 สำหรับหน้าจอแนะนำ... ไฟล์ Manifest ของคุณจึงต้องระบุการรองรับทั้ง 2 รูปแบบ ระบบจะถือว่าอุปกรณ์ที่รองรับ ETC1 เท่านั้นเข้ากันได้ แอปจะดาวน์โหลด และผู้ใช้จะเห็นข้อความข้อขัดข้องที่น่าตื่นเต้น กรณีทั่วไปคือหากคุณใช้ APK หลายรายการเพื่อกำหนดเป้าหมายไปยังอุปกรณ์ต่างๆ โดยเฉพาะตามการรองรับพื้นผิว GL รูปแบบพื้นผิวจะเป็น 1 รูปแบบต่อ APK

ซึ่งทำให้การรองรับพื้นผิวแตกต่างออกไปเล็กน้อยจากมิติข้อมูล APK หลายรายการอีก 2 รายการ ได้แก่ ระดับ API และขนาดหน้าจอ อุปกรณ์หนึ่งๆ จะมี API ระดับเดียวและขนาดหน้าจอเดียว และ APK จะรองรับ API และขนาดหน้าจอต่างๆ ได้มากน้อยเพียงใดนั้นขึ้นอยู่กับ APK นั้นๆ เมื่อใช้พื้นผิว โดยทั่วไปแล้ว APK จะรองรับพื้นผิว 1 รายการ และอุปกรณ์จะรองรับพื้นผิวหลายรายการ อุปกรณ์เครื่องหนึ่งมักรองรับ APK หลายรายการ แต่วิธีแก้ปัญหาก็เหมือนกัน นั่นคือ รหัสเวอร์ชัน

ตัวอย่างเช่น เลือกอุปกรณ์ 2-3 เครื่อง แล้วดูว่า APK ที่กําหนดไว้ก่อนหน้านี้มีจำนวนเท่าใดที่เหมาะกับอุปกรณ์แต่ละเครื่อง

FooPhone Nexus S Evo
ETC1 ETC1 ETC1
PowerVR ATI TC

สมมติว่าทั้งรูปแบบ PowerVR และ ATI ได้รับการแนะนำมากกว่า ETC1 หากมี ตามกฎ "หมายเลขเวอร์ชันสูงสุดจะชนะ" หากเราตั้งค่าแอตทริบิวต์ versionCode ใน APK แต่ละรายการเพื่อให้สีแดง ≥ เขียว ≥ น้ำเงิน ระบบจะเลือกทั้งสีแดงและสีเขียวเหนือน้ำเงินในอุปกรณ์ที่รองรับเสมอ และหากมีอุปกรณ์ที่รองรับทั้งสีแดงและสีเขียว ระบบจะเลือกสีแดง

คุณต้องมีรูปแบบรหัสเวอร์ชันที่ดีเพื่อให้ APK ทั้งหมดอยู่ใน "แทร็ก" แยกกัน รหัสที่แนะนําจะอยู่ในส่วนรหัสเวอร์ชันของคู่มือนักพัฒนาซอฟต์แวร์ เนื่องจากชุด APK ตัวอย่างจัดการกับมิติข้อมูล 1 ใน 3 ที่เป็นไปได้เท่านั้น การแยก APK แต่ละรายการด้วย 1, 000 และเพิ่มจากจำนวนนั้นจึงเพียงพอแล้ว ซึ่งอาจมีลักษณะดังนี้

น้ำเงิน: 1001, 1002, 1003, 1004...
สีเขียว: 2001, 2002, 2003, 2004...
สีแดง:3001, 3002, 3003, 3004...

เมื่อรวมทั้งหมดเข้าด้วยกันไฟล์ Manifest ของ Android ของคุณอาจมีลักษณะดังนี้

สีน้ำเงิน:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    android:versionCode="1001" android:versionName="1.0" package="com.example.foo">
    <supports-gl-texture android:name="GL_OES_compressed_ETC1_RGB8_texture" />
    ...

สีเขียว:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    android:versionCode="2001" android:versionName="1.0" package="com.example.foo">
    <supports-gl-texture android:name="GL_AMD_compressed_ATC_texture" />
    ...

สีแดง:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    android:versionCode="3001" android:versionName="1.0" package="com.example.foo">
    <supports-gl-texture android:name="GL_IMG_texture_compression_pvrtc" />
    ...

ตรวจสอบเช็กลิสต์ก่อนการเปิดตัว

โปรดตรวจสอบรายการต่อไปนี้อีกครั้งก่อนอัปโหลดไปยัง Google Play โปรดทราบว่ารายการเหล่านี้เกี่ยวข้องกับ APK หลายรายการโดยเฉพาะ และไม่ได้แสดงรายการตรวจสอบที่สมบูรณ์สำหรับแอปพลิเคชันทั้งหมดที่อัปโหลดไปยัง Google Play

  • APK ทั้งหมดต้องมีชื่อแพ็กเกจเดียวกัน
  • APK ทั้งหมดต้องรับรองด้วยใบรับรองเดียวกัน
  • ตรวจสอบตัวกรองไฟล์ Manifest อีกครั้งเพื่อหาข้อมูลที่ขัดแย้งกัน (APK ที่รองรับเฉพาะ Cupcake ในหน้าจอขนาดใหญ่พิเศษจะไม่มีใครเห็น)
  • ไฟล์ Manifest ของ APK แต่ละรายการต้องไม่ซ้ำกันสำหรับหน้าจอ พื้นผิว OpenGL หรือเวอร์ชันแพลตฟอร์มที่รองรับอย่างน้อย 1 รายการ
  • ลองทดสอบ APK แต่ละรายการในอุปกรณ์อย่างน้อย 1 เครื่อง แต่คุณมีโปรแกรมจำลองอุปกรณ์ที่ปรับแต่งได้มากที่สุดแห่งหนึ่งในธุรกิจอยู่ในเครื่องสำหรับพัฒนาซอฟต์แวร์ สนุกได้เลย

นอกจากนี้ คุณควรตรวจสอบ APK ที่คอมไพล์แล้วก่อนเผยแพร่เพื่อให้แน่ใจว่าไม่มีปัญหาที่ไม่คาดคิดซึ่งอาจทำให้แอปพลิเคชันของคุณใน Google Play แสดงไม่ถูกต้อง ซึ่งจริงๆ แล้วไม่ซับซ้อนเลยเมื่อใช้เครื่องมือ "aapt" Aapt (Android Asset Packaging Tool) เป็นส่วนหนึ่งของกระบวนการสร้างสำหรับการสร้างและแพ็กเกจแอปพลิเคชัน Android และเป็นเครื่องมือที่มีประโยชน์มากในการตรวจสอบแอปพลิเคชัน

>aapt dump badging
package: name='com.example.hello' versionCode='1' versionName='1.0'
sdkVersion:'11'
uses-permission:'android.permission.SEND_SMS'
application-label:'Hello'
application-icon-120:'res/drawable-ldpi/icon.png'
application-icon-160:'res/drawable-mdpi/icon.png'
application-icon-240:'res/drawable-hdpi/icon.png'
application: label='Hello' icon='res/drawable-mdpi/icon.png'
launchable-activity: name='com.example.hello.HelloActivity'  label='Hello' icon=''
uses-feature:'android.hardware.telephony'
uses-feature:'android.hardware.touchscreen'
main
supports-screens: 'xlarge'
supports-any-density: 'true'
locales: '--_--'
densities: '120' '160' '240'

เมื่อตรวจสอบเอาต์พุต aapt ให้ตรวจสอบว่าคุณไม่มีค่าที่ขัดแย้งกันสำหรับ supports-screens และ compatible-screens และไม่มีค่า "uses-feature" ที่ไม่ได้ตั้งใจซึ่งเพิ่มเข้ามาอันเป็นผลมาจากสิทธิ์ที่คุณกำหนดไว้ในไฟล์ Manifest ในตัวอย่างข้างต้น APK จะมองไม่เห็นในอุปกรณ์ส่วนใหญ่หรือทั้งหมด

เหตุผล การเพิ่มสิทธิ์ที่จำเป็น SEND_SMS จะเพิ่มข้อกำหนดฟีเจอร์ของ android.hardware.telephony โดยปริยาย เนื่องจากอุปกรณ์ขนาดใหญ่ส่วนใหญ่ (หากไม่ใช่ทั้งหมด) เป็นแท็บเล็ตที่ไม่มีฮาร์ดแวร์โทรศัพท์ Google Play จะกรอง APK นี้ออกในกรณีเหล่านี้จนกว่าจะมีอุปกรณ์ในอนาคตที่ทั้งมีขนาดใหญ่พอที่จะรายงานเป็นหน้าจอขนาดใหญ่ และมีฮาร์ดแวร์โทรศัพท์

โชคดีที่ปัญหานี้แก้ไขได้ง่ายๆ ด้วยการเพิ่มค่าต่อไปนี้ลงในไฟล์ Manifest

<uses-feature android:name="android.hardware.telephony" android:required="false" />

ระบบจะเพิ่มข้อกำหนด android.hardware.touchscreen โดยนัยด้วย หากต้องการให้แสดง APK ในทีวีซึ่งเป็นอุปกรณ์ที่ไม่ใช่หน้าจอสัมผัส คุณควรเพิ่มสิ่งต่อไปนี้ลงในไฟล์ Manifest

<uses-feature android:name="android.hardware.touchscreen" android:required="false" />

เมื่อทำตามรายการตรวจสอบก่อนการเปิดตัวเรียบร้อยแล้ว ให้อัปโหลด APK ไปยัง Google Play ระบบอาจใช้เวลาสักครู่เพื่อให้แอปพลิเคชันปรากฏขึ้นเมื่อเรียกดู Google Play แต่เมื่อปรากฏแล้ว ให้ตรวจสอบอีกครั้งเป็นครั้งสุดท้าย ดาวน์โหลดแอปพลิเคชันลงในอุปกรณ์ทดสอบที่คุณมีเพื่อตรวจสอบว่า APK กำหนดเป้าหมายไปยังอุปกรณ์ที่ต้องการ ยินดีด้วย คุณดำเนินการเสร็จแล้ว