Android學習筆記二十四.Service入門(二)綁定本地Service並與之通訊

來源:互聯網
上載者:User

標籤:android開發

綁定本地Service並與之通訊    通過上一篇博文的前3步,我們就算完成了一個Service及使用該Service的應用程式(Service為該應用程式的組成部分)。但當程式通過startService()和stopService()啟動、關閉Service時,Service與訪問者之間基本上不存在太多的關聯,因此Service和訪問者之間也無法進行通訊、資料交換。如果我們希望開發的Service能與訪問者之間實現方法調用或資料交換,我們可以讓訪問者使用bindService()和unbindService()方法啟動、關閉Service,從而實現訪問者與本地Service之間的綁定。 1.啟動Service方法Context.bindService(Intent service,ServiceConnection conn,int flags)參數說明:service:該參數用於設定Activity通過Intent指定啟動哪個Service;conn:該參數是一個ServiceConnection對象,該對象用於監聽訪問者與Service之間的串連情況。當訪問者與Service之間串連成功時將回調該ServiceConnection對象的onServiceConnected(ComponentName name,IBinder service)方法;當Service所在的宿主進程由於異常中止或由於其他原因終止,導致該Service與訪問者之間中斷連線時回調ServiceConnection對象的onServiceDisconnected(ComponentName name)方法。注意:當調用者主動通過unBindService()方法斷開與Service的串連時,ServiceConnection對象的onServiceDisconnected(ComponentName name)方法並不會被調用。flags:指定綁定時是否自動建立Service(如果Service還未建立)。flags=0,不自動建立;flags=BIND_AUTO_CREATE,自動建立。 2.源碼分析(1)在Service子類中,通過繼承Binder的方式實現IBinder類並聲明一個IBinder對象;(2)當訪問者綁定該Service後,Service通過onBind()方法返回一個IBinder對象給訪問者;(3)在訪問者子類中,當訪問者與Service串連成功將回調ServiceConnection對象的onServiceConnected(ComponentName name,IBinder service)方法來擷取Service的onBind方法所返回的MyBinder對象;,該IBinder對象可訪問該Service狀態資料,即count的值。 3.源碼實戰(1)/com/exanple/android_service_bind/BindService.java功能:實現一個Service子類,並再其實現一個IBinder內部類和一個線程
package com.example.android_service_bind;import android.app.Service;import android.content.Intent;import android.os.Binder;import android.os.IBinder;public class BindService extends Service { private int count; private boolean quit; private MyIBinder binder=new MyIBinder();//聲明一個IBinder對象 //1.定義一個IBinder子類並實現一個擷取Service運行狀態(count)的方法 public class MyIBinder extends Binder {  public int getCount()  {   return count; //返回Service運行狀態:count  } } //2.Service子類必須實現的一個類,用於返回IBinder對象 public IBinder onBind(Intent intent) {  System.out.println("Service is Binded!");  return binder;//返回IBinder對象 } //3.Service被建立時回調該方法 @Override public void onCreate() {  super.onCreate();  System.out.println("Service is Created.");  //建立並啟動一個線程,實現動態修改count狀態值  new Thread()  {   @Override   public void run()   {    while(!quit)//標識Service關閉啟動狀態    {     try     {      Thread.sleep(1000);     }catch(InterruptedException e)     {     }     count++;    }   }  }.start(); } //4.Service被中斷連線時回調方法 @Override public boolean onUnbind(Intent intent) {  System.out.println("Service is Unbinded");  return true; } //5.Service被關閉之前回調該方法 @Override public void onDestroy() {  super.onDestroy();  this.quit=true; //當調用該方法後(!quit)為假,線程結束  System.out.println("Service is Destroy"); }}
(2)AndroidManifest.xml實現:為Service子類配置一個Service組件,並為該Service組件的intent-filter配置action
<?xml version="1.0" encoding="utf-8"?><manifest xmlns:android="http://schemas.android.com/apk/res/android"    package="com.example.android_service_bind"    android:versionCode="1"    android:versionName="1.0" >    <uses-sdk        android:minSdkVersion="8"        android:targetSdkVersion="19" />    <application        android:allowBackup="true"        android:icon="@drawable/ic_launcher"        android:label="@string/app_name"        android:theme="@style/AppTheme" >        <activity            android:name=".BindServiceTest"            android:label="@string/app_name" >            <intent-filter>                <action android:name="android.intent.action.MAIN" />                <category android:name="android.intent.category.LAUNCHER" />            </intent-filter>        </activity>       <!-- 配置一個Service組件 -->       <service android:name=".BindService">        <intent-filter>             <!-- 為該Service組件的intent-filter配置action -->             <action android:name="com.example.service.BIND_SERVICE"/>        </intent-filter>       </service>      </application></manifest>
(3)/com/exanple/android_service_bind/BindServiceTest.java實現:定義一個ServiceConnection對象,通過該對象的onServiceConnected()方法擷取Service返回的IBinder對象,並通過Intent對象啟動和綁定指定Service。
package com.example.android_service_bind;import android.app.Activity;import android.app.Service;import android.content.ComponentName;import android.content.Intent;import android.content.ServiceConnection;import android.os.Bundle;import android.os.IBinder;import android.view.View;import android.view.View.OnClickListener;import android.widget.Button;import android.widget.Toast;public class BindServiceTest extends Activity { Button bind,unbind,status; //1.保持所啟動的Service的IBinder對象 BindService.MyIBinder binder; //2.定義一個ServiceConnection對象 private ServiceConnection conn = new ServiceConnection() {  //a.當該Activity與Service串連成功時回調該方法  @Override  public void onServiceConnected(ComponentName name    , IBinder service)  {   System.out.println("---Service is connected---");   //擷取Service的onBind方法所返回的MyBinder對象   binder=(BindService.MyIBinder)service;  }  //b.當該Activity與Service串連不成功時回調該方法  @Override  public void onServiceDisconnected(ComponentName name) {   System.out.println("---Service is Disconnected---");  } }; @Override protected void onCreate(Bundle savedInstanceState) {  super.onCreate(savedInstanceState);  setContentView(R.layout.main);  //a.擷取程式介面中的start、stop、getServiceStatus按鈕  bind = (Button)findViewById(R.id.bind);  unbind = (Button)findViewById(R.id.unbind);  status = (Button)findViewById(R.id.getServiceStatus);  //b.建立啟動Service的Intent  final Intent intent = new Intent();  intent.setAction("com.example.service.BIND_SERVICE");  //c.綁定指定Service  bind.setOnClickListener(new OnClickListener(){   @Override   public void onClick(View v) {    bindService(intent,conn,Service.BIND_AUTO_CREATE);   }  });  //d.解除綁定的Service  unbind.setOnClickListener(new OnClickListener(){   @Override   public void onClick(View v) {    unbindService(conn);   }  });  //e.擷取Service的狀態,顯示Service的count值  status.setOnClickListener(new OnClickListener(){   @Override   public void onClick(View v) {    Toast.makeText(BindServiceTest.this,"Service的count值為:"+binder.getCount()       , Toast.LENGTH_SHORT).show();   }  }); } }
(4)主介面布局/res/layout/main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:orientation="vertical"    android:layout_width="match_parent"    android:layout_height="match_parent"> <LinearLayout     android:orientation="horizontal"     android:layout_width="match_parent"     android:layout_height="match_parent">     <Button         android:id="@+id/bind"         android:layout_width="wrap_content"         android:layout_height="wrap_content"         android:layout_weight="1"         android:text="綁定service"/>      <Button         android:id="@+id/unbind"         android:layout_width="wrap_content"         android:layout_height="wrap_content"         android:layout_weight="1"         android:text="解除綁定"/>       <Button         android:id="@+id/getServiceStatus"         android:layout_width="wrap_content"         android:layout_height="wrap_content"         android:layout_weight="1"         android:text="擷取狀態"/>    </LinearLayout></LinearLayout>



效果示範:(1)當點擊綁定Service時,訪問者調用bindService()方法啟動指定Service並與之綁定。觀察DDMS的LogCat:
(2)當點擊擷取Service狀態時,訪問者通過IBinder對象binder調用Service內部類MyIBinder的getCount()方法擷取count值;
(3)當點擊解除綁定後,訪問者通過unbindService(ServiceConnection conn) 方法解除對某個Service的綁定時,系統會先回調該Service的onUnbind()方法,然後再回調onDestroy()方法,Service服務被關閉。
注意:這裡所謂的Service狀態,實際上就是在Service服務中啟動並執行實現count值累加的一個線程(在Service的onCreate()方法中實現)。當訪問者調用bindService()方法啟動並綁定該Service後,這個線程開始運行且count不停的進行累加1,直到訪問者解除Service的綁定。升華筆記:關於IBinder對象?   IBinder對象相當於Service組件的內部鉤子,該鉤子關聯到綁定的Service組件,當其他程式組件綁定該Service時,Service子類將會把IBinder對象並返回給其他程式組件,其他程式組件通過該IBinder對象即可與Service組件進行即時通訊。出生:Service採用繼承Binder(IBinder的實作類別)的方法實現自己的IBinder對象,由Service提供的IBinder onBinder(Intent intent)方法返回該IBinder對象,去向:其他程式組件調用該ServiceConnection對象的onServiceConnected(ComponentName name,IBinder service)方法時,傳入Service組件返回的IBinder對象,從而實現了其他程式組件與被綁定的Service之間的通訊。
參考:http://wear.techbrood.com/reference/android/app/Service.html

Android學習筆記二十四.Service入門(二)綁定本地Service並與之通訊

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.