如要在應用程式中執行網路作業,資訊清單必須包含下列權限:
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
安全網路通訊的最佳做法
將應用程式加入網路功能之前,您必須確保 將資料和資訊傳輸到應用程式時, 更是如此如要這麼做的話,請按照下列網路安全性最佳做法操作:
如要進一步瞭解如何套用安全網路的原則,請參閱 網路安全性提示。
選擇 HTTP 用戶端
大多數具備網路連線的應用程式會使用 HTTP 傳送及接收資料。Android
平台包含
HttpsURLConnection
用戶端,
,支援 TLS、串流上傳和下載、可設定逾時
IPv6 及連線集區
第三方程式庫提供高階網路作業 API 也可選擇建立大型語言模型這些 API 可支援各種便利功能,例如將要求主體序列化,以及將回應主體反序列化。
- Retrofit:類型安全的 HTTP 這個 JVM 用戶端以 OkHttp 為建構基礎。Retrofit 可讓您 以宣告方式建立用戶端介面,同時支援多個 序列化程式庫
- Ktor:這個 JetBrains 的 HTTP 用戶端全為 Kotlin 建構而成,採用協同程式提供的技術。Ktor 支援多種引擎 序列化程式和平台
解析 DNS 查詢
搭載 Android 10 (API 級別 29) 以上版本的裝置內建支援功能,可同時透過明文查詢和「透過 TLS 執行 DNS」模式專門處理 DNS 查詢。DnsResolver
API 提供一般的非同步解析,可讓您查詢 SRV
、NAPTR
和其他記錄類型。請注意,剖析回應會留在應用程式中執行。
在搭載 Android 9 (API 級別 28) 或以下版本的裝置上,平台 DNS 解析器僅支援 A
和 AAAA
記錄。這可讓您查詢與名稱相關聯的 IP 位址,但不支援任何其他記錄類型。
如需以 NDK 為基礎的應用程式,請參閱 android_res_nsend
的說明。
使用存放區封裝網路作業
如要簡化執行網路作業的流程,並減少應用程式中各部分的程式碼重複,您可以使用存放區設計模板。存放區是一種資料處理作業的類別,也是針對某些特定資料或資源提供簡潔的 API 抽象層。
您可以使用 Retrofit 宣告介面,指定網路作業的 HTTP 方法、網址、引數和回應類型,如以下範例所示:
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
的呼叫者
必須使用協同程式或 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 } }); } }
閱讀相關指南
如要進一步瞭解這個主題,請參閱下列相關指南: