參考另一篇文章[綁定服務](http://note.youdao.com/noteshare?id=de140840a1da668b7f2f7f3facb34620)
原文出處——>[綁定服務](https://developer.android.com/guide/components/services.html#Basics)
**關鍵類**
[Service](https://developer.android.com/reference/android/app/Service.html)
[ServiceConnection](https://developer.android.com/reference/android/content/ServiceConnection.html)
[IBinder](https://developer.android.com/reference/android/os/IBinder.html)
**示例**
[RemoteService](https://developer.android.com/resources/samples/ApiDemos/src/com/example/android/apis/app/RemoteService.html)
[LocalService](https://developer.android.com/resources/samples/ApiDemos/src/com/example/android/apis/app/LocalService.html)
**另請參閱**
[服務](https://developer.android.com/guide/components/services.html)
綁定服務是客戶端-服務器接口中的服務器。綁定服務可讓組件(例如 Activity)綁定到服務、發送請求、接收響應,甚至執行進程間通信 (IPC)。 綁定服務通常只在為其他應用組件服務時處于活動狀態,不會無限期在后臺運行。
本文向您介紹如何創建綁定服務,包括如何綁定到來自其他應用組件的服務。 不過,您還應參閱服務文檔,了解有關一般服務的更多信息,例如:如何利用服務傳送通知、如何將服務設置為在前臺運行等等。
#### **基礎知識**
綁定服務是 Service 類的實現,可讓其他應用與其綁定和交互。要提供服務綁定,您必須實現 onBind() 回調方法。該方法返回的 IBinder 對象定義了客戶端用來與服務進行交互的編程接口。
#### **綁定到已啟動服務**
正如服務文檔中所述,您可以創建同時具有已啟動和綁定兩種狀態的服務。 也就是說,可通過調用 startService() 啟動該服務,讓服務無限期運行;此外,還可通過調用 bindService() 使客戶端綁定到服務。
如果您確實允許服務同時具有已啟動和綁定狀態,則服務啟動后,系統“不會”在所有客戶端都取消綁定時銷毀服務。 為此,您必須通過調用 stopSelf() 或 stopService() 顯式停止服務。
盡管您通常應該實現 onBind() 或 onStartCommand(),但有時需要同時實現這兩者。例如,音樂播放器可能發現讓其服務無限期運行并同時提供綁定很有用處。 這樣一來,Activity 便可啟動服務進行音樂播放,即使用戶離開應用,音樂播放也不會停止。 然后,當用戶返回應用時,Activity 可綁定到服務,重新獲得回放控制權。
請務必閱讀管理綁定服務的生命周期部分,詳細了解有關為已啟動服務添加綁定時該服務的生命周期信息。
客戶端可通過調用 bindService() 綁定到服務。調用時,它必須提供 ServiceConnection 的實現,后者會監控與服務的連接。bindService() 方法會立即無值返回,但當 Android 系統創建客戶端與服務之間的連接時,會對 ServiceConnection 調用 onServiceConnected(),向客戶端傳遞用來與服務通信的 IBinder。
多個客戶端可同時連接到一個服務。不過,只有在第一個客戶端綁定時,系統才會調用服務的 onBind() 方法來檢索 IBinder。系統隨后無需再次調用 onBind(),便可將同一 IBinder 傳遞至任何其他綁定的客戶端。
當最后一個客戶端取消與服務的綁定時,系統會將服務銷毀(除非 startService() 也啟動了該服務)。
當您實現綁定服務時,最重要的環節是定義您的 onBind() 回調方法返回的接口。您可以通過幾種不同的方法定義服務的 IBinder 接口,下文對這些方法逐一做了闡述。
創建綁定服務
創建提供綁定的服務時,您必須提供 IBinder,用以提供客戶端用來與服務進行交互的編程接口。 您可以通過三種方法定義接口:
* **[擴展 Binder 類](https://developer.android.com/guide/components/bound-services.html#Binder)**
如果服務是供您的自有應用專用,并且在與客戶端相同的進程中運行(常見情況),則應通過擴展 Binder 類并從 onBind() 返回它的一個實例來創建接口。客戶端收到 Binder 后,可利用它直接訪問 Binder 實現中乃至 Service 中可用的公共方法。
如果服務只是您的自有應用的后臺工作線程,則優先采用這種方法。 不以這種方式創建接口的唯一原因是,您的服務被其他應用或不同的進程占用。
* **[使用 Messenger](https://developer.android.com/guide/components/bound-services.html#Messenger)**
如需讓接口跨不同的進程工作,則可使用 Messenger 為服務創建接口。服務可以這種方式定義對應于不同類型 Message 對象的 Handler。此 Handler 是 Messenger 的基礎,后者隨后可與客戶端分享一個 IBinder,從而讓客戶端能利用 Message 對象向服務發送命令。此外,客戶端還可定義自有 Messenger,以便服務回傳消息。
這是執行進程間通信 (IPC) 的最簡單方法,因為 Messenger 會在單一線程中創建包含所有請求的隊列,這樣您就不必對服務進行線程安全設計。
* **使用 AIDL**
AIDL(Android 接口定義語言)執行所有將對象分解成原語的工作,操作系統可以識別這些原語并將它們編組到各進程中,以執行 IPC。 之前采用 Messenger 的方法實際上是以 AIDL 作為其底層結構。 如上所述,Messenger 會在單一線程中創建包含所有客戶端請求的隊列,以便服務一次接收一個請求。 不過,如果您想讓服務同時處理多個請求,則可直接使用 AIDL。 在此情況下,您的服務必須具備多線程處理能力,并采用線程安全式設計。
如需直接使用 AIDL,您必須創建一個定義編程接口的 .aidl 文件。Android SDK 工具利用該文件生成一個實現接口并處理 IPC 的抽象類,您隨后可在服務內對其進行擴展。
> 注:大多數應用“都不會”使用 AIDL 來創建綁定服務,因為它可能要求具備多線程處理能力,并可能導致實現的復雜性增加。因此,AIDL 并不適合大多數應用,本文也不會闡述如何將其用于您的服務。如果您確定自己需要直接使用 AIDL,請參閱 [AIDL](https://developer.android.com/guide/components/aidl.html) 文檔。
**擴展 Binder 類**
如果您的服務僅供本地應用使用,不需要跨進程工作,則可以實現自有 Binder 類,讓您的客戶端通過該類直接訪問服務中的公共方法。
> 注:此方法只有在客戶端和服務位于同一應用和進程內這一最常見的情況下方才有效。 例如,對于需要將 Activity 綁定到在后臺播放音樂的自有服務的音樂應用,此方法非常有效。
以下是具體的設置方法:
1. 在您的服務中,創建一個可滿足下列任一要求的 [Binder](https://developer.android.com/reference/android/os/Binder.html) 實例:
* 包含客戶端可調用的公共方法
* 返回當前 Service 實例,其中包含客戶端可調用的公共方法
* 或返回由服務承載的其他類的實例,其中包含客戶端可調用的公共方法
2. 從 onBind() 回調方法返回此 Binder 實例。
3. 在客戶端中,從 onServiceConnected() 回調方法接收 Binder,并使用提供的方法調用綁定服務。
> 注:之所以要求服務和客戶端必須在同一應用內,是為了便于客戶端轉換返回的對象和正確調用其 API。服務和客戶端還必須在同一進程內,因為此方法不執行任何跨進程編組。
例如,以下這個服務可讓客戶端通過 Binder 實現訪問服務中的方法:
~~~
public class LocalService extends Service {
// Binder given to clients
private final IBinder mBinder = new LocalBinder();
// Random number generator
private final Random mGenerator = new Random();
/**
* Class used for the client Binder. Because we know this service always
* runs in the same process as its clients, we don't need to deal with IPC.
*/
public class LocalBinder extends Binder {
LocalService getService() {
// Return this instance of LocalService so clients can call public methods
return LocalService.this;
}
}
@Override
public IBinder onBind(Intent intent) {
return mBinder;
}
/** method for clients */
public int getRandomNumber() {
return mGenerator.nextInt(100);
}
}
~~~
LocalBinder 為客戶端提供 getService() 方法,以檢索 LocalService 的當前實例。這樣,客戶端便可調用服務中的公共方法。 例如,客戶端可調用服務中的 getRandomNumber()。
點擊按鈕時,以下這個 Activity 會綁定到 LocalService 并調用 getRandomNumber() :
~~~
public class BindingActivity extends Activity {
LocalService mService;
boolean mBound = false;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
@Override
protected void onStart() {
super.onStart();
// Bind to LocalService
Intent intent = new Intent(this, LocalService.class);
bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
}
@Override
protected void onStop() {
super.onStop();
// Unbind from the service
if (mBound) {
unbindService(mConnection);
mBound = false;
}
}
/** Called when a button is clicked (the button in the layout file attaches to
* this method with the android:onClick attribute) */
public void onButtonClick(View v) {
if (mBound) {
// Call a method from the LocalService.
// However, if this call were something that might hang, then this request should
// occur in a separate thread to avoid slowing down the activity performance.
int num = mService.getRandomNumber();
Toast.makeText(this, "number: " + num, Toast.LENGTH_SHORT).show();
}
}
/** Defines callbacks for service binding, passed to bindService() */
private ServiceConnection mConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName className,
IBinder service) {
// We've bound to LocalService, cast the IBinder and get LocalService instance
LocalBinder binder = (LocalBinder) service;
mService = binder.getService();
mBound = true;
}
@Override
public void onServiceDisconnected(ComponentName arg0) {
mBound = false;
}
};
}
~~~
上例說明了客戶端如何使用 ServiceConnection 的實現和 onServiceConnected() 回調綁定到服務。下文更詳細介紹了綁定到服務的過程。
> 注:在上例中,onStop() 方法將客戶端與服務取消綁定。 客戶端應在適當時機與服務取消綁定,如附加說明中所述。
如需查看更多示例代碼,請參見 ApiDemos 中的 LocalService.java 類和 LocalServiceActivities.java 類。
**使用 Messenger**
與 AIDL 比較
當您需要執行 IPC 時,為您的接口使用 Messenger 要比使用 AIDL 實現它更加簡單,因為 Messenger 會將所有服務調用排入隊列,而純粹的 AIDL 接口會同時向服務發送多個請求,服務隨后必須應對多線程處理。
對于大多數應用,服務不需要執行多線程處理,因此使用 Messenger 可讓服務一次處理一個調用。如果您的服務必須執行多線程處理,則應使用 AIDL 來定義接口。
如需讓服務與遠程進程通信,則可使用 Messenger 為您的服務提供接口。利用此方法,您無需使用 AIDL 便可執行進程間通信 (IPC)。
以下是 Messenger 的使用方法摘要:
* 服務實現一個 [Handler](https://developer.android.com/reference/android/os/Handler.html),由其接收來自客戶端的每個調用的回調
* Handler 用于創建 Messenger 對象(對 Handler 的引用)
* Messenger 創建一個 [IBinder](https://developer.android.com/reference/android/os/IBinder.html),服務通過 onBind() 使其返回客戶端
* 客戶端使用 IBinder 將 Messenger(引用服務的 Handler)實例化,然后使用后者將 [Message](https://developer.android.com/reference/android/os/Message.html) 對象發送給服務
* 服務在其 Handler 中(具體地講,是在 handleMessage() 方法中)接收每個 Message。
這樣,客戶端并沒有調用服務的“方法”。而客戶端傳遞的“消息”(Message 對象)是服務在其 Handler 中接收的。
以下是一個使用 Messenger 接口的簡單服務示例:
~~~
public class MessengerService extends Service {
/** Command to the service to display a message */
static final int MSG_SAY_HELLO = 1;
/**
* Handler of incoming messages from clients.
*/
class IncomingHandler extends Handler {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case MSG_SAY_HELLO:
Toast.makeText(getApplicationContext(), "hello!", Toast.LENGTH_SHORT).show();
break;
default:
super.handleMessage(msg);
}
}
}
/**
* Target we publish for clients to send messages to IncomingHandler.
*/
final Messenger mMessenger = new Messenger(new IncomingHandler());
/**
* When binding to the service, we return an interface to our messenger
* for sending messages to the service.
*/
@Override
public IBinder onBind(Intent intent) {
Toast.makeText(getApplicationContext(), "binding", Toast.LENGTH_SHORT).show();
return mMessenger.getBinder();
}
}
~~~
請注意,服務就是在 Handler 的 handleMessage() 方法中接收傳入的 Message,并根據 [what](https://developer.android.com/reference/android/os/Message.html#what) 成員決定下一步操作。
客戶端只需根據服務返回的 IBinder 創建一個 Messenger,然后利用 send() 發送一條消息。例如,以下就是一個綁定到服務并向服務傳遞 MSG_SAY_HELLO 消息的簡單 Activity:
~~~
public class ActivityMessenger extends Activity {
/** Messenger for communicating with the service. */
Messenger mService = null;
/** Flag indicating whether we have called bind on the service. */
boolean mBound;
/**
* Class for interacting with the main interface of the service.
*/
private ServiceConnection mConnection = new ServiceConnection() {
public void onServiceConnected(ComponentName className, IBinder service) {
// This is called when the connection with the service has been
// established, giving us the object we can use to
// interact with the service. We are communicating with the
// service using a Messenger, so here we get a client-side
// representation of that from the raw IBinder object.
mService = new Messenger(service);
mBound = true;
}
public void onServiceDisconnected(ComponentName className) {
// This is called when the connection with the service has been
// unexpectedly disconnected -- that is, its process crashed.
mService = null;
mBound = false;
}
};
public void sayHello(View v) {
if (!mBound) return;
// Create and send a message to the service, using a supported 'what' value
Message msg = Message.obtain(null, MessengerService.MSG_SAY_HELLO, 0, 0);
try {
mService.send(msg);
} catch (RemoteException e) {
e.printStackTrace();
}
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
@Override
protected void onStart() {
super.onStart();
// Bind to the service
bindService(new Intent(this, MessengerService.class), mConnection,
Context.BIND_AUTO_CREATE);
}
@Override
protected void onStop() {
super.onStop();
// Unbind from the service
if (mBound) {
unbindService(mConnection);
mBound = false;
}
}
}
~~~
請注意,此示例并未說明服務如何對客戶端作出響應。如果您想讓服務作出響應,則還需要在客戶端中創建一個 Messenger。然后,當客戶端收到 onServiceConnected() 回調時,會向服務發送一條 Message,并在其 send() 方法的 [replyTo](https://developer.android.com/reference/android/os/Message.html#replyTo) 參數中包含客戶端的 Messenger。
如需查看如何提供雙向消息傳遞的示例,請參閱 [MessengerService.java](https://developer.android.com/resources/samples/ApiDemos/src/com/example/android/apis/app/MessengerService.html)(服務)和 [MessengerServiceActivities.java](https://developer.android.com/resources/samples/ApiDemos/src/com/example/android/apis/app/MessengerServiceActivities.html)(客戶端)示例。
#### **綁定到服務**
應用組件(客戶端)可通過調用 bindService() 綁定到服務。Android 系統隨后調用服務的 onBind() 方法,該方法返回用于與服務交互的 IBinder。
綁定是異步的。bindService() 會立即返回,“不會”使 IBinder 返回客戶端。要接收 IBinder,客戶端必須創建一個 ServiceConnection 實例,并將其傳遞給 bindService()。ServiceConnection 包括一個回調方法,系統通過調用它來傳遞 IBinder。
> 注:只有 Activity、服務和內容提供程序可以綁定到服務 — 您無法從廣播接收器綁定到服務。
因此,要想從您的客戶端綁定到服務,您必須:
1. 實現 [ServiceConnection](https://developer.android.com/reference/android/content/ServiceConnection.html)。
您的實現必須重寫兩個回調方法:
* onServiceConnected()
系統會調用該方法以傳遞服務的 onBind() 方法返回的 IBinder。
* onServiceDisconnected()
Android 系統會在與服務的連接意外中斷時(例如當服務崩潰或被終止時)調用該方法。當客戶端取消綁定時,系統“不會”調用該方法。
2. 調用 bindService(),傳遞 ServiceConnection 實現。
3. 當系統調用您的 onServiceConnected() 回調方法時,您可以使用接口定義的方法開始調用服務。
4. 要斷開與服務的連接,請調用 unbindService()。
如果應用在客戶端仍綁定到服務時銷毀客戶端,則銷毀會導致客戶端取消綁定。 更好的做法是在客戶端與服務交互完成后立即取消綁定客戶端。 這樣可以關閉空閑服務。如需了解有關綁定和取消綁定的適當時機的詳細信息,請參閱[附加說明](https://developer.android.com/guide/components/bound-services.html#Additional_Notes)。
例如,以下代碼段通過[擴展 Binder 類](https://developer.android.com/guide/components/bound-services.html#Binder)將客戶端與上面創建的服務相連,因此它只需將返回的 IBinder 轉換為 LocalService 類并請求 LocalService 實例:
~~~
LocalService mService;
private ServiceConnection mConnection = new ServiceConnection() {
// Called when the connection with the service is established
public void onServiceConnected(ComponentName className, IBinder service) {
// Because we have bound to an explicit
// service that is running in our own process, we can
// cast its IBinder to a concrete class and directly access it.
LocalBinder binder = (LocalBinder) service;
mService = binder.getService();
mBound = true;
}
// Called when the connection with the service disconnects unexpectedly
public void onServiceDisconnected(ComponentName className) {
Log.e(TAG, "onServiceDisconnected");
mBound = false;
}
};
~~~
客戶端可通過將此 ServiceConnection 傳遞至 bindService() 綁定到服務。例如:
~~~
Intent intent = new Intent(this, LocalService.class);
bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
~~~
* bindService() 的第一個參數是一個 Intent,用于顯式命名要綁定的服務(但 Intent 可能是隱式的)
* 第二個參數是 ServiceConnection 對象
* 第三個參數是一個指示綁定選項的標志。它通常應該是 BIND_AUTO_CREATE,以便創建尚未激活的服務。其他可能的值為 BIND_DEBUG_UNBIND 和 BIND_NOT_FOREGROUND,或 0(表示無)。
**附加說明**
以下是一些有關綁定到服務的重要說明:
* 您應該始終捕獲 DeadObjectException 異常,它們是在連接中斷時引發的。這是遠程方法引發的唯一異常。
* 對象是跨進程計數的引用。
* 您通常應該在客戶端生命周期的匹配引入 (bring-up) 和退出 (tear-down) 時刻期間配對綁定和取消綁定。 例如:
* 如果您只需要在 Activity 可見時與服務交互,則應在 onStart() 期間綁定,在 onStop() 期間取消綁定。
* 如果您希望 Activity 在后臺停止運行狀態下仍可接收響應,則可在 onCreate() 期間綁定,在 onDestroy() 期間取消綁定。請注意,這意味著您的 Activity 在其整個運行過程中(甚至包括后臺運行期間)都需要使用服務,因此如果服務位于其他進程內,那么當您提高該進程的權重時,系統終止該進程的可能性會增加。
> 注:通常情況下,切勿在 Activity 的 onResume() 和 onPause() 期間綁定和取消綁定,因為每一次生命周期轉換都會發生這些回調,您應該使發生在這些轉換期間的處理保持在最低水平。此外,如果您的應用內的多個 Activity 綁定到同一服務,并且其中兩個 Activity 之間發生了轉換,則如果當前 Activity 在下一個 Activity 綁定(恢復期間)之前取消綁定(暫停期間),系統可能會銷毀服務并重建服務。 (Activity文檔中介紹了這種有關 Activity 如何協調其生命周期的 Activity 轉換。)
如需查看更多顯示如何綁定到服務的示例代碼,請參閱 [ApiDemos](https://developer.android.com/resources/samples/ApiDemos/index.html) 中的 RemoteService.java 類。
#### **管理綁定服務的生命周期**
當服務與所有客戶端之間的綁定全部取消時,Android 系統便會銷毀服務(除非還使用 onStartCommand() 啟動了該服務)。因此,如果您的服務是純粹的綁定服務,則無需對其生命周期進行管理 — Android 系統會根據它是否綁定到任何客戶端代您管理。
不過,如果您選擇實現 onStartCommand() 回調方法,則您必須顯式停止服務,因為系統現在已將服務視為已啟動。在此情況下,服務將一直運行到其通過 stopSelf() 自行停止,或其他組件調用 stopService() 為止,無論其是否綁定到任何客戶端。
此外,如果您的服務已啟動并接受綁定,則當系統調用您的 onUnbind() 方法時,如果您想在客戶端下一次綁定到服務時接收 onRebind() 調用,則可選擇返回 true。onRebind() 返回空值,但客戶端仍在其 onServiceConnected() 回調中接收 IBinder。下文圖 1 說明了這種生命周期的邏輯。

圖 1. 允許綁定的已啟動服務的生命周期。
如需了解有關已啟動服務生命周期的詳細信息,請參閱[服務](https://developer.android.com/guide/components/services.html#Lifecycle)文檔。
- 前言
- Google官網對Android API各版本的介紹
- jelly Bean(果凍豆)Android 4.1、4.2、4.3
- Android 4.1
- Android 4.2
- Android 4.3
- KitKat(Android 4.4.*)巧克力
- Android 4.4 APIS
- Lollipop(棒棒糖)Android 5.*
- Android 5.0 APIs
- Android 5.0 Changes(變更)
- Android 5.1APIs
- Marshmallow(棉花糖)Android 6.0
- Android 6.0 APIs
- Android 6.0 Changes(變更)
- Android 6.0 Samples
- Android 6.0 Testing
- Nougat(牛扎塘)Android 7.*
- Android 7.0
- API
- 行為變更
- 示例
- Android 7.1
- 開發者API
- 示例Sample
- Oreo(奧利奧)8.*
- Android 8.0
- 功能和 API
- Android 8.0 行為變更
- 向 Android 8.0 遷移應用
- Android 8.0 示例
- Android 8.1
- 后臺執行限制
- 后臺位置限制
- API指南
- Android 簡介
- 應用基礎知識
- 設備兼容性
- 系統權限
- 請求權限
- 定義權限
- 平臺架構
- Java8 概覽
- 在ART上驗證應用行為
- 應用組件
- Intent 和 Intent 過濾器(Google官網介紹)
- 通用intent
- Activity
- 任務和返回棧(官網譯文)
- 概覽屏幕
- 活動簡介
- 活動生命周期
- 活動狀態更改
- 進程和應用程序生命周期
- 包裹和捆綁
- 最近的屏幕
- 片段
- 加載器
- 服務Service
- 綁定服務
- AIDL
- 內容提供程序
- 內容提供程序基礎知識
- 創建內容提供程序
- 日歷提供程序
- 聯系人提供程序
- 存儲訪問框架
- 使用存儲訪問框架打開文件
- 創建自定義文檔提供程序
- 應用小部件
- 應用小部件主機
- 進程和線程
- 應用資源
- 概覽
- 提供資源
- 訪問資源
- 處理運行時變更
- 本地化
- ICU4J Android框架API
- Android上的國際化
- 語言和語言區域
- 復雜的XML資源
- 資源類型
- 動畫
- 顏色狀態列表
- 可繪制對象
- 布局
- 菜單
- 字符串
- 樣式
- 其他類型
- 應用清單
- <action>
- <activity>
- <activity-alias>
- <application>
- <category>
- <compatiable-screens>
- <data>
- <grant-uri-permission>
- <intent-filter>
- <manifest>
- <meta-data>
- <path-permission>
- <permission>
- <permission-group>
- <permission-tree>
- <provider>
- <receiver>
- <service>
- <supporte-gl-texture>
- <supports-screens>
- <uses-configuration>
- <uses-feature>
- <uses-library>
- <uses-permission>
- <uses-permission-sdk-23>
- <uses-sdk>
- 用戶界面
- 界面概覽
- 界面布局
- 線性布局
- 相對布局
- 列表視圖
- 網格視圖
- 回收站視圖
- 外觀和感覺
- 可下載的字體
- XML中的字體
- 表情符號兼容性
- 自動調整TextView
- 樣式和主題-
- 輸入控件
- 按鈕
- 文本字段
- 復選框
- 單選按鈕
- 切換按鈕
- 微調框
- 選取器
- 輸入事件
- 菜單Menu
- 設置
- 對話框
- 通知
- Toast
- 自適應圖標
- 應用快捷方式
- 搜索
- 創建搜索界面
- 添加近期查詢建議
- 添加自定義建議
- 可搜索配置
- 多窗口支持
- 拖放
- 無障礙功能
- 為應用設置無障礙功能
- 無障礙功能開發者檢查單
- 構建無障礙服務
- 讓應用更容易訪問
- 使用節點樹調試
- 構建可訪問自定義視圖
- 樣式和主題
- 自定義組件
- 動畫和圖形
- 概覽介紹
- 屬性動畫
- 視圖動畫
- 可繪制動畫
- 畫布和可繪制對象
- 基于物理的動畫
- Spring Animation
- Fling Animation
- OpenGL ES
- 硬件加速
- 計算
- RenderScript
- 高級RenderScript
- Runtime API Reference(參考)
- Numerical Types(數字類型)
- Object Types(對象類型)
- Conversion Functions(轉換函數)
- Mathematical Constants and Functions(數學常量和函數)
- Vector Math Functions(矢量數學函數)
- Matrix Functions(矩陣函數)
- Quaternion Functions(四元數函數)
- Atomic Update Functions(原子更新函數)
- Time Functions and Types(時間函數和類型)
- Allocation Data Access Functions(分配數據訪問函數)
- Object Characteristics Functions(對象特性函數)
- Kernel Invocation Functions and Types(內核調用函數和類型)
- Input/Output Functions(輸入輸出函數)
- Debugging Functions(調試函數)
- Graphics Functions and Types(圖形函數和類型)
- Index(索引)
- Media Apps(媒體應用)
- Media Apps Overview(媒體應用程序概述)
- Working with a Media Session(使用媒體會話)
- Building an Audio App(建立一個音頻應用)
- Building a Media Browser Service(構建媒體瀏覽器服務)
- Building a Media Browser Client(構建媒體瀏覽器客戶端)
- Media Session Callbacks(媒體會話回調)
- Building a Video App(建立一個視頻應用)
- Building a Video Player Activity(建立一個視頻播放器Activity)
- Media Session Callbacks-(媒體會話回調)
- Responding to Media Buttons(響應媒體按鈕)
- Handling Changes in Audio Output(處理音頻輸出的變化)
- Managing Audio Focus(管理音頻焦點)
- The Google Assistant and Media Apps(Google智能助理和媒體應用)
- 媒體和相機
- Supported Media Formats(支持的媒體格式)
- MediaPlayer(媒體播放器)
- MediaRecorder
- ExoPlayer
- Controller Amplitude with VolumeShaper(VolumeShaper控制器振幅)
- Media Routing(媒體路由)
- MediaRouter API
- MediaRouteProvider API
- Camera API(相機API)
- 位置和傳感器
- Location and Maps(位置和地圖)
- Location Strategies(位置策略)
- Sensors Overview(傳感器概覽)
- Motion Sensors(運動傳感器)
- Position Sensors(位置傳感器)
- Environment Sensors(環境傳感器)
- Raw GNSS Measurements(原始的GNSS測量)
- 連接
- Bluetooth
- Bluetooth Low Energy(藍牙低功耗)
- NFC
- NFC Basics(NFC基礎知識)
- Advanced NFC(高級NFC)
- Host-based Card Emulation(基于主機的卡模擬)
- Telecom(電信)
- Self-Managed ConnectionServices(自我管理的連接服務)
- Wi-Fi P2P
- Wi-Fi Aware
- Companion Device Pairing
- USB
- Accessory(配件)
- Host(主機)
- SIP
- 文本和輸入
- Autofill Framework(自動填充框架)
- Test your app with autofill(使用自動填充測試你的應用)
- Building autofill services(構建自動填充服務)
- Copy and Paste(復制和粘貼)
- Creating an IME(創建IME)
- Image Keyboard(圖像鍵盤)
- Spelling Checker(拼寫檢查程序)
- 數據存儲
- Storage Options(存儲選項)
- Data Backup(數據備份)
- Account Transfer API(賬戶轉移API)
- Auto Backup(自動備份)
- Key/Value Backup(鍵值備份)
- Testing Backup and Restore(測試備份和還原)
- App Install Location(應用安裝位置)
- 庫
- 支持庫
- 功能
- 修訂歷史記錄
- 庫設置
- 數據綁定庫
- 測試支持庫
- 管理
- 設備策略
- 網絡應用
- Supporting Different Screens in Web Apps(在網絡應用中支持不同屏幕)
- Building Web Apps in WebView(在WebView中構建網絡應用)
- Managing WebViews
- Migrating to WebView in Android 4.4(遷移到Android4.4中的WebView)
- Debugging Web Apps(調試網絡應用)
- Best Practices for Web Apps(網絡應用最佳做法)
- 最佳實踐
- Supporting Multiple Screens(支持多種屏幕)
- Distributing to Specific Screens(分配到特定屏幕)
- Screen Compatibility Mode(屏幕兼容性模式)
- Designing for Seamlessness
- Supporting Tablets and Handsets
- 培訓