หากต้องการดำเนินการกับเครือข่ายในแอปพลิเคชันของคุณ Manifest ต้องมีสิทธิ์ต่อไปนี้
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
แนวทางปฏิบัติแนะนำสำหรับการสื่อสารในเครือข่ายที่ปลอดภัย
ก่อนที่จะเพิ่มฟังก์ชันการทํางานของเครือข่ายลงในแอป คุณต้องตรวจสอบว่าข้อมูลภายในแอปปลอดภัยเมื่อส่งผ่านเครือข่าย โดยทำตามแนวทางปฏิบัติแนะนำด้านความปลอดภัยของเครือข่ายต่อไปนี้
- ลดปริมาณข้อมูลผู้ใช้ที่ละเอียดอ่อนหรือเป็นส่วนตัวซึ่งคุณส่งผ่านเครือข่าย
- ส่งการรับส่งข้อมูลทั้งหมดจากแอปผ่าน SSL
- ลองสร้างการกำหนดค่าความปลอดภัยของเครือข่าย ซึ่งจะช่วยให้แอปเชื่อถือผู้ออกใบรับรอง (CA) ที่กําหนดเอง หรือจํากัดชุด CA ของระบบที่เชื่อถือสําหรับการสื่อสารที่ปลอดภัย
ดูข้อมูลเพิ่มเติมเกี่ยวกับวิธีใช้หลักการของเครือข่ายที่ปลอดภัยได้ที่เคล็ดลับด้านความปลอดภัยของเครือข่าย
เลือกไคลเอ็นต์ HTTP
แอปที่เชื่อมต่อเครือข่ายส่วนใหญ่ใช้ HTTP เพื่อส่งและรับข้อมูล แพลตฟอร์ม Android ประกอบด้วยไคลเอ็นต์ HttpsURLConnection
ซึ่งรองรับ TLS, การอัปโหลดและการดาวน์โหลดสตรีมมิง, การหมดเวลาที่กำหนดค่าได้, IPv6 และการเชื่อมต่อพูล
นอกจากนี้ คุณยังใช้ไลบรารีของบุคคลที่สามที่มี API ระดับสูงขึ้นสําหรับการดำเนินการของเครือข่ายได้ด้วย ซึ่งรองรับฟีเจอร์ต่างๆ ที่อำนวยความสะดวก เช่น การจัดรูปแบบข้อมูลของเนื้อหาคำขอและการถอดรูปแบบข้อมูลของเนื้อหาคำตอบ
- Retrofit: ไคลเอ็นต์ HTTP ที่ปลอดภัยต่อประเภทสําหรับ JVM จาก Square ซึ่งสร้างขึ้นจาก OkHttp Retrofit ช่วยให้คุณสร้างอินเทอร์เฟซไคลเอ็นต์แบบประกาศได้ และรองรับไลบรารีการแปลงเป็นอนุกรมหลายรายการ
- Ktor: ไคลเอ็นต์ HTTP จาก JetBrains ที่สร้างขึ้นเพื่อ Kotlin โดยเฉพาะและทำงานด้วย Coroutines Ktor รองรับเครื่องมือ โปรแกรมแปลงรูปแบบ และแพลตฟอร์มต่างๆ
แก้ปัญหาการค้นหา DNS
อุปกรณ์ที่ใช้ Android 10 (API ระดับ 29) ขึ้นไปจะรองรับการค้นหา DNS แบบเฉพาะทางในตัวผ่านทั้งการค้นหาแบบข้อความที่อ่านได้และโหมด DNS-over-TLS
DnsResolver
API ให้ความละเอียดแบบทั่วไปแบบไม่พร้อมกัน ซึ่งช่วยให้คุณค้นหา SRV
, NAPTR
และระเบียนประเภทอื่นๆ ได้ การสํารวจคําตอบจะขึ้นอยู่กับแอป
ในอุปกรณ์ที่ใช้ Android 9 (API ระดับ 28) และต่ำกว่า เครื่องมือแก้ไข DNS ของแพลตฟอร์มจะรองรับเฉพาะระเบียน A
และ AAAA
ซึ่งช่วยให้คุณค้นหาที่อยู่ IP ที่เชื่อมโยงกับชื่อได้ แต่ไม่รองรับระเบียนประเภทอื่นๆ
สำหรับแอปที่ใช้ NDK โปรดดู
android_res_nsend
บรรจุการดำเนินการของเครือข่ายไว้ในที่เก็บ
คุณสามารถใช้รูปแบบการออกแบบที่เก็บข้อมูลเพื่อลดความซับซ้อนของกระบวนการดำเนินการทางเครือข่ายและลดการเขียนโค้ดซ้ำในส่วนต่างๆ ของแอป รีพอสิทอรี่คือคลาสที่จัดการการดำเนินการกับข้อมูลและให้ข้อมูลทั่วไปของ API ที่สะอาดสำหรับข้อมูลหรือทรัพยากรที่เฉพาะเจาะจง
คุณสามารถใช้ Retrofit เพื่อประกาศอินเทอร์เฟซที่ระบุเมธอด HTTP, URL, อาร์กิวเมนต์ และประเภทการตอบกลับสําหรับการดําเนินการของเครือข่าย ดังตัวอย่างต่อไปนี้
Kotlin
interface UserService { @GET("/users/{id}") suspend fun getUser(@Path("id") id: String): User }
Java
public interface UserService { @GET("/user/{id}") Call<User> getUserById(@Path("id") String id); }
ภายในคลาสที่เก็บข้อมูล ฟังก์ชันสามารถรวมการดำเนินการของเครือข่ายและแสดงผลลัพธ์ การรวมช่องนี้ช่วยให้มั่นใจว่าคอมโพเนนต์ที่เรียกใช้ที่เก็บข้อมูลไม่จำเป็นต้องทราบวิธีจัดเก็บข้อมูล การเปลี่ยนแปลงในอนาคตเกี่ยวกับวิธีจัดเก็บข้อมูลจะแยกออกจากคลาสที่เก็บข้อมูลด้วย เช่น คุณอาจมีการเปลี่ยนแปลงจากระยะไกล เช่น การอัปเดตปลายทาง API หรืออาจต้องการใช้การแคชในเครื่อง
Kotlin
class UserRepository constructor( private val userService: UserService ) { suspend fun getUserById(id: String): User { return userService.getUser(id) } }
Java
class UserRepository { private UserService userService; public UserRepository( UserService userService ) { this.userService = userService; } public Call<User> getUserById(String id) { return userService.getUser(id); } }
อย่าดำเนินการกับเครือข่ายในเธรดหลักเพื่อหลีกเลี่ยงการสร้าง UI ที่ไม่ตอบสนอง โดยค่าเริ่มต้น Android จะกำหนดให้คุณดำเนินการเกี่ยวกับเครือข่ายในเธรดอื่นที่ไม่ใช่เธรด UI หลัก หากพยายามดําเนินการเครือข่ายในเทรดหลัก ระบบจะแสดงข้อผิดพลาด NetworkOnMainThreadException
ในตัวอย่างโค้ดก่อนหน้า ระบบไม่ได้ทริกเกอร์การดำเนินการของเครือข่าย ผู้เรียกใช้ UserRepository
ต้องใช้การแยกชุดข้อความโดยใช้ coroutine หรือใช้ฟังก์ชัน enqueue()
ดูข้อมูลเพิ่มเติมได้ที่โค้ดแล็บรับข้อมูลจากอินเทอร์เน็ต ซึ่งสาธิตวิธีใช้การแยกชุดข้อความโดยใช้โคโริวทีนของ Kotlin
อยู่รอดจากการเปลี่ยนแปลงการกําหนดค่า
เมื่อเกิดการเปลี่ยนแปลงการกําหนดค่า เช่น การหมุนหน้าจอ ระบบจะทำลายและสร้างข้อมูลโค้ดโค้ดหรือกิจกรรมขึ้นมาใหม่ ข้อมูลที่ไม่ได้บันทึกไว้ในสถานะอินสแตนซ์สําหรับกิจกรรมของข้อมูลโค้ดที่ฝัง ซึ่งเก็บข้อมูลได้เพียงจํานวนเล็กน้อยจะสูญหาย ในกรณีนี้ คุณอาจต้องส่งคำขอเครือข่ายอีกครั้ง
คุณสามารถใช้ ViewModel
เพื่อให้ข้อมูลอยู่รอดได้แม้จะมีการเปลี่ยนแปลงการกําหนดค่า คอมโพเนนต์ ViewModel
ได้รับการออกแบบมาเพื่อจัดเก็บและจัดการข้อมูลที่เกี่ยวข้องกับ UI ในลักษณะที่คำนึงถึงอายุการใช้งาน เมื่อใช้ UserRepository
ก่อนหน้า ViewModel
จะส่งคำขอเครือข่ายที่จำเป็นและแสดงผลลัพธ์ไปยังข้อมูลโค้ดหรือกิจกรรมได้โดยใช้ LiveData
ดังนี้
Kotlin
class MainViewModel constructor( savedStateHandle: SavedStateHandle, userRepository: UserRepository ) : ViewModel() { private val userId: String = savedStateHandle["uid"] ?: throw IllegalArgumentException("Missing user ID") private val _user = MutableLiveData<User>() val user = _user as LiveData<User> init { viewModelScope.launch { try { // Calling the repository is safe as it moves execution off // the main thread val user = userRepository.getUserById(userId) _user.value = user } catch (error: Exception) { // Show error message to user } } } }
Java
class MainViewModel extends ViewModel { private final MutableLiveData<User> _user = new MutableLiveData<>(); LiveData<User> user = (LiveData<User>) _user; public MainViewModel( SavedStateHandle savedStateHandle, UserRepository userRepository ) { String userId = savedStateHandle.get("uid"); Call<User> userCall = userRepository.getUserById(userId); userCall.enqueue(new Callback<User>() { @Override public void onResponse(Call<User> call, Response<User> response) { if (response.isSuccessful()) { _user.setValue(response.body()); } } @Override public void onFailure(Call<User> call, Throwable t) { // Show error message to user } }); } }
อ่านคู่มือที่เกี่ยวข้อง
ดูข้อมูลเพิ่มเติมเกี่ยวกับหัวข้อนี้ได้ในคู่มือที่เกี่ยวข้องต่อไปนี้
- ลดการใช้แบตเตอรี่ของเครือข่าย: ภาพรวม
- ลดผลกระทบของการอัปเดตเป็นประจำ
- เนื้อหาในเว็บ
- พื้นฐานของแอปพลิเคชัน
- คู่มือสถาปัตยกรรมแอป