Android筆記三十一.Service綜合執行個體(一),android.service

來源:互聯網
上載者:User

Android筆記三十一.Service綜合執行個體(一),android.service
綜合執行個體1:訪問本地Service服務    a)通過Context的startService()方法啟動和停止Service ;    b)通過Context的bindService()方法綁定和解除綁定 ;           實現本地Activity擷取service服務,並與之通訊,擷取service相關資料。
1.源碼(1)src/MainActivity.java:應用程式主Acitvity功能:擷取介面組件並為相關組件註冊事件監聽器(內部類形式)、啟動指定Service、與Service通訊開發核心步驟:         a)執行個體化兩個Intent對象(Intent service),用於指定啟動本地哪個Service服務;         b)   對於非綁定式Service:            >調用Context.startService(Intent service)啟動非綁定式Service;            >調用Context.stopService(Intent intent)關閉Service;                 對於綁定式Service:            >調用Context.bindService(Intent service, ServiceConnection conn, int flags) 啟動綁定式Service;               >調用unbindService(ServiceConnection conn)解除與Servcie的綁定並關閉Service;            >建立一個ServcieConnection對象,用於監聽訪問者與Service之間的串連情況                   (1)串連成功:回調該ServiceConnection對象的onServiceConnected(ComponentName name,IBinder service)方法                   (2)串連失敗:回調其onServiceDisconnected(ComponentName name)方法               其中,onServiceConnected方法用於擷取Service的onBind()方法返回的IBinder對象,通過該對象我們可以實現與Service的通訊。

<span style="font-family:Times New Roman;font-size:18px;">package com.example.servicetest1;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 MainActivity extends Activity { private Button startService; private Button stopService; private Button bindService; private Button unbindService; private Button getData; private MyBindService.MyIBinder binder;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.main);        //a.擷取介面組件        startService = (Button)findViewById(R.id.start);        stopService = (Button)findViewById(R.id.stop);        bindService = (Button)findViewById(R.id.bind);        unbindService = (Button)findViewById(R.id.unbind);        getData = (Button)findViewById(R.id.get);        //b.為組件註冊同一個監聽器        MyEvent Listener = new MyEvent(); //執行個體化一個事件監聽器        startService.setOnClickListener(Listener);//為組件註冊監聽器對象        stopService.setOnClickListener(Listener);        bindService.setOnClickListener(Listener);        unbindService.setOnClickListener(Listener);        getData.setOnClickListener(Listener);    }       /*1.事件處理內部類     * 通過擷取視圖組件(v)並判定組件ID,來響應具體組件*/    public class MyEvent implements OnClickListener    {     //a.設定啟動指定Service的"意圖"     Intent intent1 = new Intent("com.jiangdongguo.MyService");  Intent intent2 = new Intent("com.jiangdongguo.MyBindService");  //b.啟動指定的service     public void onClick(View v)  {   switch (v.getId())   {    //(1)啟動普通Service    case R.id.start:     startService(intent1);//啟動"intent"指定的Service服務     break;    //(2)關閉普通Service    case R.id.stop:     stopService(intent1);//關閉"intent"指定的Service服務     break;    //(3)啟動並綁定Service    case R.id.bind:     bindService(intent2, conn, Service.BIND_AUTO_CREATE);     break;    //(4)解除與Service綁定    case R.id.unbind:     unbindService(conn);     break;    //(5)從service服務擷取資料    case R.id.get:     Toast.makeText(MainActivity.this,"從Service讀取到的資料為:count="+Integer.toString(binder.getCount()), Toast.LENGTH_SHORT).show();     break;    default:     break;   }  }         }    /*2.ServcieConnection匿名內部類:建立一個ServcieConnection對象  * 該內部類的對象用於監聽訪問者與Service之間的串連情況  * (1)串連成功:回調該ServiceConnection對象的onServiceConnected(ComponentName name,IBinder service)方法  * (2)串連失敗:回調其onServiceDisconnected(ComponentName name)方法*/ private ServiceConnection conn = new  ServiceConnection() {  //a.串連服務成功:該方法用於擷取Service返回的IBinder對象,用於與Service進行通訊  public void onServiceConnected(ComponentName name, IBinder service)  {   System.out.println("---MainActivity's onServiceConnected invoked!---");   binder = (MyBindService.MyIBinder)service;//擷取Service返回的IBinder對象  }  //b.串連服務失敗:提示失敗  public void onServiceDisconnected(ComponentName name) {   System.out.println("---MainActivity's onServiceDisconnected invoked!---");   Toast.makeText(MainActivity.this, "與Service綁定失敗,請重試。", Toast.LENGTH_SHORT).show();  } };}</span>
(2)src/MyService.java:非綁定式Service服務功能:繼承Service的子類,實現當訪問者調用相關的Context.Xxxx()方法回調的相關方法開發核心步驟:        a)重寫Context.startService(Intent service)啟動Service回調的方法                >onCreate():完成初始化或相關商務邏輯代碼                >onStartCommand(Intent intent, int flags, int startId):完成相關商務邏輯代碼        b)重寫Context.stopService(Intent intent)關閉Service回調的方法                >onDestory():關閉Service服務注意:onBind方法為抽象方法,在代碼中必須實現。但由於訪問者與Service服務無綁定關係,不能通訊,因此無需具體實現該方法,只需返回null即可。
<span style="font-family:Times New Roman;font-size:18px;">package com.example.servicetest1;import android.app.Service;import android.content.Intent;import android.os.IBinder;public class MyService extends Service { /*1.onBind方法  * service用於返回一個IBinder對象給用戶端方便通訊  * 如果是訪問者通過Context.startService啟動該Service,則返回為空白 */ @Override public IBinder onBind(Intent arg0) {  System.out.println("---MyService’s onBind invoked!---");  return null; } /*2.onCreate方法  * 當Service啟動後,自動調用該方法,用於初始化  * */ public void onCreate() {  System.out.println("---MyService’s onCreate invoked!---");  super.onCreate(); } /*3.onStartCommand方法  * 每次訪問者調用startService方法啟動該Service時都會回調該方法*/ public int onStartCommand(Intent intent, int flags, int startId) {  System.out.println("---MyService’s onStartCommand invoked!---");  return super.onStartCommand(intent, flags, startId); } /*4.onDestroy方法  * 當訪問者調用Context.stopService方法後,調用該方法關閉Service服務  * */ public void onDestroy() {  System.out.println("---MyService’s onDestory invoked!---");  super.onDestroy(); }}</span>
(3)src/MyBindService.java:綁定式Service服務功能:繼承Service的子類,實現當訪問者調用相關的Context.Xxxx()方法回調的相關方法開發核心步驟:        a)重寫Context.bindService(Intent service, ServiceConnection conn, int flags) 啟動Service回調的方法                >onCreate():完成初始化或相關商務邏輯代碼                >IBinder onBind(Intent arg0):用於返回一個IBinder對象給訪問者        b)實現一個內部類,該類繼承於Binder類並提供相關方法,使訪問者通過獲得的IBinder對象                    調用該類成員方法,從而實現訪問者與Service服務之間的通訊。            如:public class MyIBinder extends Binder                     {                            /*.....成員方法或變數......*/                     }        c)重寫Context.unbindService( ServiceConnection conn) 關閉Service回調的方法                >onUnbind(Intent intent):解除訪問者與Service服務的綁定                >onDestory():關閉Service服務注意:onBind方法為抽象方法,在代碼中必須實現。將用戶端與Service服務綁定,目的就是為了實現兩者之間的通訊,而他們的通訊媒介就IBinder對象,訪問者可以通過IBinder對象調用Service子類的IBinder內部類中的成員方法,從而實現對Service服務的資料訪問。
<span style="font-family:Times New Roman;font-size:18px;">package com.example.servicetest1;import android.app.Service;import android.content.Intent;import android.os.Binder;import android.os.IBinder;public class MyBindService extends Service { private int count=0; private boolean threadFlag=true;//結束線程標誌 MyIBinder bind = new MyIBinder();//執行個體化一個Binder對象,用於被onBind方法返回給訪問者 /*0.Binder子類  * 其對象用於與訪問者通訊,訪問者通過調用IBinder子類中的方法擷取Service中的資料*/ public class MyIBinder extends Binder {  //自訂成員方法,用於返回Service中的資料  public int getCount()  {   return count;  } } /*1.onBind方法  * service用於返回一個IBinder對象給用戶端方便通訊  * 如果是訪問者通過Context.startService啟動該Service,則返回為空白 */ @Override public IBinder onBind(Intent arg0) {  System.out.println("---MyService’s onBind invoked!---");  return bind; } /*2.onCreate方法  * 當Service啟動後,自動調用該方法,用於初始化  * */ public void onCreate() {  System.out.println("---MyService’s onCreate invoked!---");  //建立一個線程,用於按一定時間間隔更新count的值  new Thread(){   public void run()   {    while(threadFlag)//預設為true    {     try     {      Thread.sleep(500);     }     catch (InterruptedException e)     {      e.printStackTrace();     }     count++;    }   }  }.start();  super.onCreate(); } /*3.onStartCommand方法  * 每次訪問者調用startService方法啟動該Service時都會回調該方法*/ public int onStartCommand(Intent intent, int flags, int startId) {  System.out.println("---MyService’s onStartCommand invoked!---");  return super.onStartCommand(intent, flags, startId); } /*4.onDestroy方法  * 當訪問者調用Context.stopService方法後,調用該方法關閉Service服務  * */ public void onDestroy() {  System.out.println("---MyService’s onDestory invoked!---");  threadFlag=false;  super.onDestroy(); } /*5.onUnbind方法  * 當訪問者調調用Context.unBind()方法後,調用該方法與Service解除綁定*/ public boolean onUnbind(Intent intent) {  System.out.println("---MyService’s onUnbind invoked!---");  return super.onUnbind(intent); } }</span>
注意:在綁定式Service服務中,我們主要是通過線程來處理耗時任務。這裡就牽扯到一個問題,就是當我們退出應用程式後,子線程卻還是在啟動並執行,它並沒有結束,這樣子線程就會成為一個孤兒線程,很容易被系統殺死,從而導致任務失敗。為瞭解決這個問題,我們為子線程設定一個條件標誌threadFlag,當程式調用onDestory結束service服務時,順便將子線程結束。 2.效果示範(1)非綁定式
(2)綁定式(3)介面效果

3.源碼分析(1)非綁定式    每當Service被建立時會回調onCreate()方法,每次Service被啟動時都會回調onStartCommand()方法,多次啟動一個已有的Service組件將不會再回調onCreate()方法,但每次啟動時都會回調onStartCommand()方法。(2)綁定式    綁定服務的執行過程:執行單擊事件方法根據Intent找到相應的Service類,並初始化該類調用Service的onCreate()方法調用該類的onBind()方法調用onServiceConnected()方法。 多次單擊綁定服務按鈕,並不會重複執行Binder 方法。一旦解除綁定,調用onunBind()方法,然後自動銷毀。
注意:a)未啟動Service而直接停止Service不起作用,但未綁定Service而先解除綁定Service則程式出錯,強制退出;b)若該Service處於綁定狀態下,該Service不會被停止即單擊停止按鈕不起作用,當單擊解除綁定Service按鈕時,它會先解除綁定隨後直接銷毀;c)若在解除之前,沒有單擊停止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.