ในการพัฒนา Android สมัยใหม่ การจัดส่งแอปพลิเคชันขนาดเล็ก รวดเร็ว และปลอดภัยเป็นความคาดหวังพื้นฐานของผู้ใช้ เครื่องมือหลักของระบบบิลด์ Android ที่ใช้ในการดำเนินการนี้คือเครื่องมือเพิ่มประสิทธิภาพ R8 ซึ่งเป็นคอมไพเลอร์ที่จัดการโค้ดที่ไม่ได้ใช้งานและการนำทรัพยากรออกเพื่อลดขนาด การเปลี่ยนชื่อโค้ดหรือการลดขนาด และการเพิ่มประสิทธิภาพแอป
การเปิดใช้ R8 เป็นขั้นตอนสำคัญในการเตรียมแอปสำหรับการเผยแพร่ แต่นักพัฒนาแอปต้องให้คำแนะนำในรูปแบบของ "กฎการเก็บรักษา"
หลังจากอ่านบทความนี้แล้ว โปรดดูวิดีโอ Performance Spotlight Week เกี่ยวกับการเปิดใช้ การแก้ไขข้อบกพร่อง และการแก้ปัญหาเครื่องมือเพิ่มประสิทธิภาพ R8 บน YouTube
เหตุผลที่ต้องใช้กฎการเก็บรักษา
ความจำเป็นในการเขียนกฎ Keep เกิดจากความขัดแย้งหลัก นั่นคือ R8 เป็นเครื่องมือวิเคราะห์แบบคงที่ แต่แอป Android มักอาศัยรูปแบบการดำเนินการแบบไดนามิก เช่น การสะท้อนหรือการเรียกเข้าและออกจากโค้ดแบบเนทีฟโดยใช้ JNI (Java Native Interface)
R8 จะสร้างกราฟของโค้ดที่ใช้โดยการวิเคราะห์การเรียกใช้โดยตรง เมื่อมีการเข้าถึงโค้ดในลักษณะแบบไดนามิก การวิเคราะห์แบบคงที่ของ R8 จะคาดการณ์ไม่ได้และจะระบุโค้ดดังกล่าวเป็นไม่ได้ใช้และนำออก ซึ่งจะทำให้เกิดข้อขัดข้องขณะรันไทม์
กฎการเก็บรักษาคือคำสั่งที่ชัดเจนสำหรับคอมไพเลอร์ R8 ซึ่งระบุว่า "คลาส เมธอด หรือฟิลด์ที่เฉพาะเจาะจงนี้เป็นจุดแรกเข้าที่จะเข้าถึงแบบไดนามิกที่รันไทม์ คุณต้องเก็บไว้ แม้ว่าจะไม่พบการอ้างอิงโดยตรงก็ตาม"
ดูรายละเอียดเพิ่มเติมเกี่ยวกับกฎการเก็บรักษาได้ในคู่มืออย่างเป็นทางการ
ตำแหน่งที่จะเขียนกฎการเก็บรักษา
กฎการเก็บรักษาที่กำหนดเองสำหรับแอปพลิเคชันจะเขียนไว้ในไฟล์ข้อความ ตามแบบแผน ไฟล์นี้จะมีชื่อว่า proguard-rules.pro และอยู่ในรูทของโมดูลแอปหรือไลบรารี จากนั้นระบบจะระบุไฟล์นี้ในประเภทบิลด์ release ของไฟล์ build.gradle.kts ของโมดูล
release {
isShrinkResources = true
isMinifyEnabled = true
proguardFiles(
getDefaultProguardFile("proguard-android-optimize.txt"),
"proguard-rules.pro",
)
}ใช้ไฟล์เริ่มต้นที่ถูกต้อง
เมธอด getDefaultProguardFile จะนำเข้าชุดกฎเริ่มต้นที่ Android SDK มีให้ เมื่อใช้ไฟล์ที่ไม่ถูกต้อง แอปอาจไม่ได้รับการเพิ่มประสิทธิภาพ โปรดใช้ proguard-android-optimize.txt ไฟล์นี้มีกฎการเก็บรักษาเริ่มต้นสำหรับคอมโพเนนต์ Android มาตรฐานและ เปิดใช้การเพิ่มประสิทธิภาพโค้ดของ R8 proguard-android.txt ที่ล้าสมัยจะให้เฉพาะกฎการเก็บ แต่ไม่เปิดใช้การเพิ่มประสิทธิภาพของ R8
เนื่องจากปัญหานี้เป็นปัญหาด้านประสิทธิภาพที่ร้ายแรง เราจึงเริ่มเตือนนักพัฒนาแอปเกี่ยวกับการใช้ไฟล์ที่ไม่ถูกต้อง โดยเริ่มตั้งแต่ฟีเจอร์ใหม่จาก Android Studio Narwhal 3 และตั้งแต่ปลั๊กอิน Android Gradle เวอร์ชัน 9.0 เป็นต้นไป เราจะไม่รองรับไฟล์ proguard-android.txt ที่ล้าสมัยอีกต่อไป ดังนั้นโปรดอัปเกรดเป็นเวอร์ชันที่เพิ่มประสิทธิภาพแล้ว
วิธีเขียนกฎการเก็บรักษา
กฎการเก็บรักษาประกอบด้วย 3 ส่วนหลักๆ ดังนี้
- ตัวเลือก เช่น
-keepหรือ-keepclassmembers - ตัวแก้ไขที่ไม่บังคับ เช่น
allowshrinking - ข้อกำหนดคลาสที่กำหนดโค้ดให้ตรงกัน
ดูไวยากรณ์และตัวอย่างทั้งหมดได้ที่คำแนะนำในการเพิ่มกฎการเก็บรักษา
รูปแบบที่ไม่ควรทำสำหรับกฎ Keep
สิ่งสำคัญคือต้องทราบเกี่ยวกับแนวทางปฏิบัติแนะนำ รวมถึงรูปแบบที่ควรหลีกเลี่ยงด้วย รูปแบบที่ไม่ควรทำเหล่านี้มักเกิดจากความเข้าใจผิดหรือทางลัดในการแก้ปัญหา และอาจส่งผลเสียต่อประสิทธิภาพของบิลด์เวอร์ชันที่ใช้งานจริง
ตัวเลือกทั่วโลก
แฟล็กเหล่านี้เป็นปุ่มเปิด/ปิดส่วนกลางที่ไม่ควรใช้ในบิลด์ที่เผยแพร่ แต่มีไว้สำหรับการแก้ไขข้อบกพร่องชั่วคราวเพื่อแยกปัญหาเท่านั้น
การใช้ -dontotptimize จะปิดใช้การเพิ่มประสิทธิภาพของ R8 ซึ่งส่งผลให้แอปทำงานช้าลง
เมื่อใช้ -dontobfuscate คุณจะปิดใช้การเปลี่ยนชื่อทั้งหมด และการใช้ -dontshrink จะปิดการนำโค้ดที่ไม่ได้ใช้ออก กฎส่วนกลางทั้ง 2 ข้อนี้จะเพิ่มขนาดแอป
หลีกเลี่ยงการใช้ Flag ส่วนกลางเหล่านี้ในสภาพแวดล้อมฮาร์ดแวร์และซอฟต์แวร์ทุกครั้งที่เป็นไปได้ เพื่อให้ผู้ใช้ได้รับประสบการณ์การใช้งานแอปที่มีประสิทธิภาพมากขึ้น
กฎการเก็บรักษาที่กว้างเกินไป
วิธีที่ง่ายที่สุดในการลบล้างประโยชน์ของ R8 คือการเขียนกฎการเก็บรักษาที่กว้างเกินไป กฎ Keep เช่นกฎด้านล่างจะสั่งให้เครื่องมือเพิ่มประสิทธิภาพ R8 ไม่ลดขนาด ไม่สร้างความสับสน และไม่เพิ่มประสิทธิภาพคลาสใดๆ ในแพ็กเกจนี้หรือแพ็กเกจย่อยใดๆ ของแพ็กเกจนี้ ซึ่งจะนำประโยชน์ของ R8 ออกจากแพ็กเกจทั้งหมดโดยสิ้นเชิง ลองเขียนกฎการเก็บรักษาที่แคบและเจาะจงแทน
-keep class com.example.package.** { *;} // WIDE KEEP RULES CAUSE PROBLEMSโอเปอเรเตอร์การกลับค่า (!)
โอเปอเรเตอร์การผกผัน (!) ดูเหมือนจะเป็นวิธีที่มีประสิทธิภาพในการยกเว้นแพ็กเกจจากกฎ แต่เรื่องนี้ไม่ได้ง่ายขนาดนั้น ลองดูตัวอย่างนี้
-keep class !com.example.my_package.** { *; } // USE WITH CAUTIONคุณอาจคิดว่ากฎนี้หมายถึง "อย่าเก็บคลาสไว้ในcom.example.package" แต่จริงๆ แล้วหมายถึง "เก็บทุกคลาส เมธอด และพร็อพเพอร์ตี้ ในแอปพลิเคชันทั้งหมดที่ไม่ได้อยู่ใน com.example.package" หากคุณรู้สึกประหลาดใจกับเรื่องนี้ เราขอแนะนำให้ตรวจสอบการปฏิเสธในการกำหนดค่า R8
กฎที่ซ้ำซ้อนสำหรับคอมโพเนนต์ Android
ข้อผิดพลาดที่พบบ่อยอีกประการหนึ่งคือการเพิ่มกฎ Keep ด้วยตนเองสำหรับ Activities, Services หรือ BroadcastReceivers ของแอป ซึ่งไม่จำเป็น ไฟล์ proguard-android-optimize.txt เริ่มต้นมีกฎที่เกี่ยวข้องสำหรับคอมโพเนนต์ Android มาตรฐานเหล่านี้อยู่แล้วเพื่อให้ทำงานได้ทันที
นอกจากนี้ คลังจำนวนมากยังมีกฎการเก็บรักษาของตนเองด้วย ดังนั้นคุณจึงไม่จำเป็นต้องเขียนกฎของคุณเองสำหรับสิ่งเหล่านี้ ในกรณีที่เกิดปัญหากับ Keep Rules จากไลบรารีที่คุณใช้อยู่ วิธีที่ดีที่สุดคือติดต่อผู้เขียนไลบรารีเพื่อดูว่าปัญหาคืออะไร
แนวทางปฏิบัติแนะนำสำหรับกฎการเก็บรักษา
เมื่อทราบแล้วว่าสิ่งใดที่ไม่ควรทำ เรามาพูดถึงแนวทางปฏิบัติแนะนำกันบ้าง
เขียนกฎการเก็บรักษาที่แคบ
กฎการเก็บรักษาที่ดีควรแคบและเฉพาะเจาะจงที่สุดเท่าที่จะเป็นไปได้ โดยควรเก็บเฉพาะสิ่งที่จำเป็นเท่านั้น เพื่อให้ R8 เพิ่มประสิทธิภาพส่วนอื่นๆ ที่เหลือได้
| กฎ | คุณภาพ |
|---|---|
| ต่ำ: เก็บทั้งแพ็กเกจและแพ็กเกจย่อยไว้ |
| ต่ำ: เก็บทั้งคลาสไว้ซึ่งอาจยังกว้างเกินไป |
-keepclassmembers class com.example.MyClass {
private java.lang.String secretMessage;
public void onNativeEvent(java.lang.String);
} | สูง: ระบบจะเก็บเฉพาะเมธอดและพร็อพเพอร์ตี้ที่เกี่ยวข้องจากคลาสที่เฉพาะเจาะจง |
ใช้ระดับบนสุดร่วมกัน
แทนที่จะเขียนกฎ Keep แยกต่างหากสำหรับโมเดลข้อมูลที่แตกต่างกันหลายโมเดล ให้เขียนกฎเดียวที่กำหนดเป้าหมายไปยังคลาสพื้นฐานหรืออินเทอร์เฟซทั่วไป กฎด้านล่างจะบอกให้ R8 เก็บสมาชิกของคลาสที่ใช้อินเทอร์เฟซนี้ไว้และปรับขนาดได้สูง
# Keep all fields of any class that implements SerializableModel
-keepclassmembers class * implements com.example.models.SerializableModel {
<fields>;
}ใช้คำอธิบายประกอบเพื่อกำหนดเป้าหมายหลายคลาส
สร้างคำอธิบายประกอบที่กำหนดเอง (เช่น @Serialize) และใช้เพื่อ "ติดแท็ก" คลาสที่ต้องเก็บรักษาฟิลด์ไว้ นี่เป็นอีกรูปแบบหนึ่งที่สะอาดตา ประกาศได้ และปรับขนาดได้สูง นอกจากนี้ คุณยังสร้างกฎการเก็บรักษาสำหรับคำอธิบายประกอบที่มีอยู่แล้วจากเฟรมเวิร์กที่ใช้อยู่ได้ด้วย
# Keep all fields of any class annotated with @Serialize
-keepclassmembers class * {
@com.example.annotations.Serialize <fields>;
}เลือกตัวเลือกการเก็บรักษาที่เหมาะสม
ตัวเลือกการเก็บรักษาเป็นส่วนที่สำคัญที่สุดของกฎ การเลือกตัวเลือกที่ไม่ถูกต้องอาจปิดใช้การเพิ่มประสิทธิภาพโดยไม่จำเป็น
| ตัวเลือกการเก็บ | สิ่งที่ทำ |
-keep | ป้องกันไม่ให้มีการนำคลาสและสมาชิกที่กล่าวถึงในการประกาศ ออกหรือเปลี่ยนชื่อ |
-keepclassmembers | ป้องกันไม่ให้สมาชิกที่ระบุถูกนำออกหรือเปลี่ยนชื่อ แต่จะอนุญาตให้นำชั้นเรียนออกได้เฉพาะในชั้นเรียนที่ไม่ได้นำออกด้วยวิธีอื่น |
-keepclasseswithmembers | แบบผสม: เก็บคลาสและองค์ประกอบต่างๆ ไว้ก็ต่อเมื่อมีองค์ประกอบที่ระบุทั้งหมดอยู่ |
ดูข้อมูลเพิ่มเติมเกี่ยวกับตัวเลือกการเก็บรักษาได้ในเอกสารประกอบสำหรับตัวเลือกการเก็บรักษา
อนุญาตการเพิ่มประสิทธิภาพด้วยตัวปรับแต่ง
ตัวแก้ไข เช่น allowshrinking และ allowobfuscation จะผ่อนคลายกฎ -keep แบบกว้างๆ ซึ่งจะช่วยเพิ่มประสิทธิภาพให้กับ R8 ตัวอย่างเช่น หากไลบรารีเดิมบังคับให้คุณใช้ -keep กับทั้งคลาส คุณอาจเรียกคืนการเพิ่มประสิทธิภาพบางอย่างได้โดยอนุญาตให้มีการย่อขนาดและการสร้างความสับสน ดังนี้
# Keep this class, but allow R8 to remove it if it's unused and allow R8 to rename it. -keep,allowshrinking,allowobfuscation class com.example.LegacyClass
เพิ่มตัวเลือกส่วนกลางเพื่อการเพิ่มประสิทธิภาพเพิ่มเติม
นอกเหนือจากกฎการเก็บรักษา คุณสามารถเพิ่มแฟล็กส่วนกลางลงในไฟล์การกำหนดค่า R8 เพื่อส่งเสริมการเพิ่มประสิทธิภาพให้ดียิ่งขึ้น
-repackageclasses เป็นตัวเลือกที่มีประสิทธิภาพซึ่งจะสั่งให้ R8 ย้ายคลาสที่สร้างความสับสนทั้งหมดไปยังแพ็กเกจเดียว ซึ่งจะช่วยประหยัดพื้นที่ในไฟล์ DEX ได้อย่างมากด้วยการนำสตริงชื่อแพ็กเกจที่ซ้ำซ้อนออก
-allowaccessmodification ช่วยให้ R8 ขยายการเข้าถึง (เช่น private เป็น public) เพื่อเปิดใช้การแทรกในบรรทัดที่ดุดันมากขึ้น ตอนนี้ระบบจะเปิดใช้ตัวเลือกนี้โดยค่าเริ่มต้นเมื่อใช้ proguard-android-optimize.txt
คำเตือน: ผู้เขียนไลบรารีต้องไม่เพิ่มแฟล็กการเพิ่มประสิทธิภาพส่วนกลางเหล่านี้ลงในกฎสำหรับผู้ใช้ เนื่องจากระบบจะบังคับใช้แฟล็กเหล่านี้กับทั้งแอป
และเพื่อให้ชัดเจนยิ่งขึ้น ในปลั๊กอิน Android Gradle เวอร์ชัน 9.0 เราจะเริ่มละเว้น Flag การเพิ่มประสิทธิภาพส่วนกลางจากไลบรารีทั้งหมด
แนวทางปฏิบัติแนะนำสำหรับไลบรารี
แอป Android ทุกแอปต้องใช้ไลบรารีไม่ทางใดก็ทางหนึ่ง เรามาพูดถึงแนวทางปฏิบัติแนะนำสำหรับไลบรารีกัน
สำหรับนักพัฒนาไลบรารี
หากไลบรารีใช้การสะท้อนหรือ JNI คุณมีหน้าที่รับผิดชอบในการระบุกฎการเก็บรักษาที่จำเป็นให้แก่ผู้ใช้ กฎเหล่านี้จะอยู่ในไฟล์ consumer-rules.pro ซึ่งจะรวมอยู่ในไฟล์ AAR ของไลบรารีโดยอัตโนมัติ
android {
defaultConfig {
consumerProguardFiles("consumer-rules.pro")
}
...
}สำหรับผู้ใช้ไลบรารี
กรองกฎการเก็บรักษาที่เป็นปัญหาออก
หากต้องใช้ไลบรารีที่มีกฎ Keep ที่เป็นปัญหา คุณสามารถกรองกฎเหล่านั้นออกได้ในไฟล์ build.gradle.kts โดยเริ่มจาก AGP 9.0 ซึ่งจะบอกให้ R8 ละเว้นกฎที่มาจากทรัพยากร Dependency ที่เฉพาะเจาะจง
release {
optimization.keepRules {
// Ignore all consumer rules from this specific library
it.ignoreFrom("com.somelibrary:somelibrary")
}
}กฎการเก็บรักษาที่ดีที่สุดคือการไม่มีกฎการเก็บรักษา
กลยุทธ์การกำหนดค่า R8 ที่ดีที่สุดคือการขจัดความจำเป็นในการเขียนกฎการเก็บรักษาทั้งหมด สำหรับแอปจำนวนมาก คุณสามารถทำได้โดยเลือกไลบรารีสมัยใหม่ที่สนับสนุนการสร้างโค้ดมากกว่าการสะท้อน การสร้างโค้ดช่วยให้เครื่องมือเพิ่มประสิทธิภาพระบุได้ง่ายขึ้นว่าโค้ดใดที่ใช้จริงในรันไทม์และโค้ดใดที่นำออกได้ นอกจากนี้ การไม่ใช้การสะท้อนแบบไดนามิกหมายความว่าไม่มีจุดเข้าใช้งานที่ "ซ่อนอยู่" ดังนั้นจึงไม่จำเป็นต้องใช้กฎ Keep เมื่อเลือกไลบรารีใหม่ ให้เลือกโซลูชันที่ใช้การสร้างโค้ดมากกว่าการสะท้อนเสมอ
ดูข้อมูลเพิ่มเติมเกี่ยวกับวิธีเลือกไลบรารีได้ที่เลือกไลบรารีอย่างชาญฉลาด
การแก้ไขข้อบกพร่องและการแก้ปัญหาการกำหนดค่า R8
เมื่อ R8 นำโค้ดที่ควรเก็บไว้ออก หรือ APK มีขนาดใหญ่กว่าที่คาดไว้ ให้ใช้เครื่องมือเหล่านี้เพื่อวิเคราะห์ปัญหา
ค้นหากฎการเก็บรักษาที่ซ้ำกันและกฎการเก็บรักษาทั่วโลก
เนื่องจาก R8 ผสานรวมกฎจากแหล่งที่มาหลายสิบแหล่ง จึงอาจเป็นเรื่องยากที่จะทราบว่ากฎ "สุดท้าย" คืออะไร การเพิ่มแฟล็กนี้ลงในไฟล์ proguard-rules.pro จะสร้างรายงานที่สมบูรณ์ ดังนี้
# Outputs the final, merged set of rules to the specified file -printconfiguration build/outputs/logs/configuration.txt
คุณสามารถค้นหาไฟล์นี้เพื่อหากฎที่ซ้ำซ้อนหรือติดตามกฎที่เป็นปัญหา (เช่น -dontoptimize) กลับไปยังไลบรารีที่เฉพาะเจาะจงซึ่งมีกฎดังกล่าวอยู่
ถาม R8: ทำไมคุณถึงเก็บสิ่งนี้ไว้
หากคลาสที่คุณคาดว่าจะถูกนำออกยังคงอยู่ในแอป R8 จะบอกสาเหตุให้คุณทราบได้ เพียงเพิ่มกฎนี้
# Asks R8 to explain why it's keeping a specific class class com.example.MyUnusedClass -whyareyoukeeping
ในระหว่างการสร้าง R8 จะพิมพ์เชนการอ้างอิงที่แน่นอนซึ่งทำให้ต้องเก็บคลาสนั้นไว้ เพื่อให้คุณติดตามการอ้างอิงและปรับกฎได้
ดูคำแนะนำฉบับเต็มได้ที่ส่วนแก้ปัญหา R8
ขั้นตอนถัดไป
R8 เป็นเครื่องมือที่มีประสิทธิภาพในการเพิ่มประสิทธิภาพของแอป Android ประสิทธิภาพของเครื่องมือนี้ขึ้นอยู่กับความเข้าใจที่ถูกต้องเกี่ยวกับการทำงานในฐานะเครื่องมือวิเคราะห์แบบคงที่
การเขียนกฎเฉพาะระดับสมาชิก การใช้ประโยชน์จากระดับบนและการกำกับเนื้อหา รวมถึงการเลือกตัวเลือกการเก็บรักษาที่เหมาะสมอย่างรอบคอบจะช่วยให้คุณเก็บรักษาเฉพาะสิ่งที่จำเป็นได้อย่างแม่นยำ แนวทางปฏิบัติที่ล้ำสมัยที่สุดคือการขจัดความจำเป็นในการใช้กฎทั้งหมดโดยเลือกใช้ไลบรารีที่อิงตาม Codegen สมัยใหม่แทนไลบรารีที่อิงตามการสะท้อน (Reflection) รุ่นก่อนหน้า
ขณะติดตามสัปดาห์ Spotlight ด้านประสิทธิภาพ อย่าลืมดูวิดีโอ Spotlight Week ของวันนี้บน YouTube และทำภารกิจ R8 ต่อไป ใช้ #optimizationEnabled สำหรับคำถามเกี่ยวกับการเปิดใช้หรือการแก้ปัญหา R8 เราพร้อมช่วยเหลือคุณ
ถึงเวลาแล้วที่คุณจะเห็นประโยชน์ด้วยตัวคุณเอง
เราขอท้าให้คุณเปิดใช้โหมดเต็มรูปแบบของ R8 สำหรับแอปวันนี้
- ทำตามคู่มือนักพัฒนาซอฟต์แวร์เพื่อเริ่มต้นใช้งาน: เปิดใช้การเพิ่มประสิทธิภาพแอป
- ตรวจสอบว่าคุณยังใช้
proguard-android.txtอยู่หรือไม่ และแทนที่ด้วยproguard-android-optimize.txt - จากนั้นวัดผลลัพธ์ อย่าเพียงแค่รู้สึกถึงความแตกต่าง แต่ให้ยืนยันด้วย วัดประสิทธิภาพที่เพิ่มขึ้นโดยปรับโค้ดจาก แอปตัวอย่าง Macrobenchmark ใน GitHub เพื่อวัดเวลาเริ่มต้นก่อนและหลัง
เรามั่นใจว่าคุณจะเห็นการปรับปรุงประสิทธิภาพของแอปอย่างมีนัยสำคัญ
และอย่าลืมใช้แท็กโซเชียล #AskAndroid เพื่อส่งคำถามของคุณ ผู้เชี่ยวชาญของเราจะคอยตรวจสอบและตอบคำถามของคุณตลอดทั้งสัปดาห์
โปรดติดตามวันพรุ่งนี้ ซึ่งเราจะพูดถึงการเพิ่มประสิทธิภาพที่อิงตามโปรไฟล์ด้วยโปรไฟล์พื้นฐานและโปรไฟล์การเริ่มต้น แชร์วิธีปรับปรุงประสิทธิภาพการแสดงผลของ Compose ในรุ่นที่ผ่านมา และแชร์ข้อควรพิจารณาด้านประสิทธิภาพสำหรับการทำงานในเบื้องหลัง
-
ข่าวสารเกี่ยวกับผลิตภัณฑ์เมื่อการพัฒนา Agent เร็วขึ้น วิศวกรรม Android กำลังก้าวเข้าสู่พรมแดนใหม่ที่น่าตื่นเต้น นั่นคือการเปลี่ยนจากการเติมโค้ดแบบช่วยเหลือไปเป็น Agent ที่ดำเนินการตั้งแต่ต้นจนจบภายใต้คำสั่งของคุณ คุณมีตัวเลือกและความยืดหยุ่นอย่างเต็มที่ในโมเดลและ Agent ที่ใช้
Jason Buchel • ใช้เวลาอ่าน 3 นาที -
ข่าวสารเกี่ยวกับผลิตภัณฑ์วันนี้เราได้แชร์วิธีที่เรากำลังนำวิสัยทัศน์ "เป็นมากกว่าร้านค้า" ไปสู่บทถัดไป Google Play ตอบสนองความต้องการของผู้ใช้ได้ทุกที่ทุกเวลา ตั้งแต่แท็บ "คุณ" ซึ่งปัจจุบันเป็นศูนย์กลางส่วนตัวสำหรับผู้ใช้ที่ใช้งานอยู่รายเดือนกว่า 250 ล้านคน ไปจนถึงแพลตฟอร์มเกมแบบรวมที่เชื่อมต่อโปรไฟล์เกมเมอร์กว่า 700 ล้านโปรไฟล์
Paul Feng • ใช้เวลาอ่าน 3 นาที -
ข่าวสารเกี่ยวกับผลิตภัณฑ์Googlebook ยินดีที่จะช่วยให้ผู้ใช้แสดงออกถึงตัวตนและเข้าถึงเครื่องมือเหล่านี้
Cyrus Stoller • ใช้เวลาอ่าน 2 นาที
รับข้อมูลเชิงลึกเกี่ยวกับการพัฒนา Android ล่าสุดที่ส่งไปยังกล่องจดหมายของคุณทุกสัปดาห์