【Android】17.2 Activity与Local Service的绑定
分類:C#、Android、VS2015;
創建日期:2016-03-03
一、簡介
如果服務是你的應用程序所私有的,即服務(Service)與客戶端(Activity)都在同一個項目中(大部分應用程序的情況都是如此),這種服務稱為本地服務。
對于本地服務,應該在繼承自Binder的類中創建接口,并從重寫的OnBind()方法中返回一個Binder的實例??蛻舳私邮者@個Binder對象并用它來直接訪問Binder甚至Service中可用的公共(public)方法。
二、示例1運行截圖
?
三、主要設計步驟
1、添加ch1701_main.xml文件
在layout文件夾下添加該文件,模板選擇【XML】,因為布局比較簡單,就不讓它帶設計界面了。當然也可以添加ch1701_main.axml文件讓其帶設計界面。
<?xml version="1.0" encoding="utf-8" ?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:orientation="vertical"android:padding="4dip"android:gravity="center_horizontal"android:layout_width="match_parent"android:layout_height="match_parent"><Buttonandroid:id="@+id/ch1701_bind"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="啟動服務綁定"><requestFocus /></Button><Buttonandroid:id="@+id/ch1701_call"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="調用服務提供的方法"><requestFocus /></Button><Buttonandroid:id="@+id/ch1701_unbind"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="解除服務綁定" /> </LinearLayout>2、創建服務—ch1701Service
要創建一個可被綁定的服務(bound service),必須在提供的服務中實現OnBind()回調方法,并在該方法中返回一個IBinder類型的對象,此對象定義了與服務進行通信的接口,該接口用于指明客戶端如何與服務進行通信。
ch1701Service.cs文件的代碼如下:
using Android.App; using Android.Content; using Android.OS; namespace MyDemos.SrcDemos {[Service]public class ch1701LocalService : Service{// 用于讓客戶端綁定的IBinder接口private readonly IBinder binder;// 用于獲取隨機數private readonly System.Random r = new System.Random();public ch1701LocalService(){binder = new ch1701LocalBinder(this);}public override IBinder OnBind(Intent intent){return binder;}// 聲明讓客戶端調用的公共方法public int GetRandomNumber(){return r.Next(100);}}// 因為本服務總是運行于與客戶端相同的進程中,因此不需要用IPC進行處理。public class ch1701LocalBinder : Binder{// 客戶端可通過它調用服務提供的公共方法public ch1701LocalService localService { get; private set; }public ch1701LocalBinder(ch1701LocalService service){localService = service;}} }(1)代碼解釋
(a)在MyService中包含可供客戶端調用的公共方法。
既然是服務,就要在Service中包含可供客戶端調用的公共方法,該例子僅僅用GetRandomNumber()方法來演示。當然,也可以通過這些公共方法方返回其它類的實例。
(b)從回調方法OnBind()中返回Binder的實例。
在客戶端中,通過在回調方法OnServiceConnected()中接收Binder并調用服務提供的方法,即可實現對綁定的服務進行調用。
ch1701LocalBinder為客戶端提供了localService屬性,通過該屬性得到ch1701LocalService的實例后,客戶端就可以通過它調用服務中提供的公共方法(比如調用服務示例代碼中的GetRandomNumber()方法)。
(c)注意事項。
服務和客戶端之所以必須位于同一個應用程序中(同一個項目中),是為了讓客戶端能夠正確轉換(cast)返回的對象并調用對象的API。 另外,服務和客戶端也必須位于同一個進程中,因為這種方式不能執行任何跨進程的序列化(marshalling)操作。要實現跨進程的序列化操作,可利用消息傳遞來實現。
(2)創建繼承自Binder的類
要實現可被綁定的服務,除了創建服務外,還需要自定義一個繼承自Binder的子類,在該子類中提供一個返回服務實例的方法。該子類是IBinder接口的默認實現。
Binder子類通過返回的Service實例響應客戶端請求。
例如,在ch1701Service.cs文件中定義了一個名為ch1701ServiceBind的類,當客戶端第1次連接服務時,Android會自動調用服務中提供的OnBind方法。這樣以來,客戶端就可以通過Service調用服務提供的公共方法了。
3、創建客戶端—ch1701BindingActivity.cs
ch1701BindingActivity.cs文件的代碼如下:
using Android.App; using Android.Content; using Android.OS; using Android.Widget; namespace MyDemos.SrcDemos {[Activity(Label = "【例17-1】綁定到本地服務")]public class ch1701BindingActivity : Activity{ch1701LocalService mService;ch1701ServiceConnection mConnection;bool mBound = false;protected override void OnCreate(Bundle bundle){base.OnCreate(bundle);SetContentView(Resource.Layout.ch1701_main);mConnection = new ch1701ServiceConnection(this);var btnBind = FindViewById<Button>(Resource.Id.ch1701_bind);btnBind.Click += delegate{if (mBound == false){// 綁定到LocalServiceIntent intent = new Intent(this, typeof(ch1701LocalService));BindService(intent, mConnection, Bind.AutoCreate);}Toast.MakeText(this, "已綁定", ToastLength.Short).Show();};var btnCall = FindViewById<Button>(Resource.Id.ch1701_call);btnCall.Click += delegate{if(mBound==false){Toast.MakeText(this, "請先綁定", ToastLength.Short).Show();return;}// 注意如果該調用會導致某些操作的掛起,應該在單獨的線程中調用它,// 以免降低activity的性能。int num = mService.GetRandomNumber();Toast.MakeText(this, "獲取的值為: " + num, ToastLength.Short).Show();};var btnUnbind = FindViewById<Button>(Resource.Id.ch1701_unbind);btnUnbind.Click += delegate{// 與服務解除綁定if (mBound == true){UnbindService(mConnection);Toast.MakeText(this, "綁定已解除", ToastLength.Short).Show();}};}public class ch1701ServiceConnection : Java.Lang.Object, IServiceConnection{private ch1701BindingActivity activity;public ch1701ServiceConnection(ch1701BindingActivity activity){this.activity = activity;}public void OnServiceConnected(ComponentName name, IBinder service){ch1701LocalBinder binder = (ch1701LocalBinder)service;activity.mService = binder.localService;activity.mBound = true;}public void OnServiceDisconnected(ComponentName name){activity.mBound = false;}}} }(1)代碼解釋
該例子展示了客戶端如何利用 ServiceConnection 和 OnServiceConnected() 回調方法綁定到服務。
(2)將客戶端綁定到服務
客戶端可以通過調用BindService() 方法來綁定服務。當客戶端完成交互時,可調用UnbindService()來解除綁定。
調用BindService() 方法來綁定服務時,必須提供一個 ServiceConnection 的實現代碼,用于監控與服務的連接。
BindService() 將會立即返回,沒有返回值。但是Android系統在創建客戶端與服務之間的連接時,會自動調用 ServiceConnection 中的 OnServiceConnected() 方法傳遞一個 IBinder ,客戶端利用它即可與服務進行通信。
ch1701ServiceConnection類負責提供客戶端和服務之間的調用接口,注意該類實現了IServiceConnection接口,由于ServiceConnection類是通過Java定義的,所以ch1701ServiceConnection類必須繼承自Java.Lang.Object。
BindService方法實現的功能是:如果存在綁定,就使用Bind.AutoCreate值自動創建服務(Android 5.0及更高版本才有此選項)。該方法是一個異步調用,如果沒有可綁定的服務該方法將返回false,如果有可綁定的服務,則通過回調將建立的連接發送到ch1701ServiceConnection類中的OnServiceConnected()方法。
MyServiceConnection類繼承自ServiceConnection類,在這個類中,重寫了OnServiceConnected方法。在這種情況下,IBinder是MyServiceBinder的一個實例。MyServiceBinder用于獲取對MyService的引用,以便客戶端可以利用它調用服務中定義的方法。
注意在MyServiceConnection的構造函數中,將MainActivity的實例傳遞到本類中聲明的activity(例子中只是以MainActivity為例,但也可以是其他的Activity),這是為了可以在Activity中通過它自身定義的OnServiceConnected回調方法得到對服務的引用,這樣以來,Activity就可以調用服務中提供的方法了。
(3)調用服務提供的方法
客戶端通過Binder實例獲取被綁定的服務的引用后,就可以調用服務中提供的方法了。在這個例子中,ch1701Service服務只定義了一個GetRandomNumber()方法。一旦Activity通過OnServiceConnected方法實現了綁定,這個Activity就可以利用binder來獲取對服務的引用,隨后就可以調用服務中提供的GetRandomNumber()方法了。
(4)取消服務綁定(Unbinding from the Service)
客戶端(Activity)完成對服務的調用后,必須取消對該服務的綁定(即:在不使用服務時要及時關閉服務)。服務斷開連接后,會自動調用ServiceConnection類的OnServiceDisconnected方法。
要解除被綁定的服務,客戶端調用UnbindService方法即可,通過它可傳遞在綁定中使用的ServiceConnection實例。
如果沒有Activity通過StartService方法調用該服務,也沒有其他客戶端綁定到該服務,則安卓系統將自動關閉該服務。
轉載于:https://www.cnblogs.com/rainmj/p/5237276.html
總結
以上是生活随笔為你收集整理的【Android】17.2 Activity与Local Service的绑定的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: bzoj 1901: Zju2112 D
- 下一篇: 让你完全理解base64是怎么回事