初步理解Service組件

1、Service與Activity相同與不同

2、Service組件創建步驟

3、Service組件生命週期方法

4、Service組件兩種運行方式

5、Service組件與調用者的通訊方式Binder和IBinder區別和用法

———————————–1、service與Activity的相同與不同——————————————
相同點:都是從Context上派生出來的,可以調用context的getResoutces()和getContextResolver
()等方法。他們都代表可執行的程序,都有不同的生命週期,不同的生命週期回調相應的方法。實現方式相似,子類繼承他們,重載不同生命週期的相應方法就可以實現業務邏輯。創建方式上都是需要再manifest中進行註冊。對應耗時任務,都不建議在主進程中進行,而是開闢新的進程來處理。
不同點:Service代表後臺程序,在後臺運行,沒有用戶界面,不出現在前臺。啓動方式上,安卓5.0以上要求Activity必須顯示啓動Service。
如何選擇Service和Activity:當一個程序需要和用戶交互,或者呈現想要的界面給用戶,那麼就用Activity,否則就用Service。

————————————–2、Service的創建步驟—————————————–
創建步驟:
首先定義一個繼承Service的子類(這裏需要添加不同生命週期的方法,詳細見下面的實例)
在AndroidManifest.xml中配置,以< service android:name=”xxx”>< /service>進行

———————————–3、Service的生命週期方法————————————
1、必須實現的方法IBinder onBind(Intent intent),注意該方法如果不需要與調用者進行通訊,則return null;如果需要與調用者通訊,那麼則要返回一個IBinder對象,這個對象可以通過內部類的方式來實現,具體表現方式見兩種創建方式中的第二個;
2、void onCreate()方法,它表示該Service第一次創建的時候立刻回調,有點類似Activity;注意他只執行一次;
3、void onDestroy()方法,它表示該Service被關閉之前調用,如果斷開連接的時候也回調該方法(第二種啓動方式);
4、void onStartCommandr(Intent intent,int flags,int startId)方法,該方法是每次Service被調用的時候回調它,與onCreate()的區別在於,onCreate()只是在第一次建立的時候回調,但是這個void onStartCommand(Intent intent,int flags,int startId)它每次都湊熱鬧啓動。
5、boolean onUnbind(Intent intent)方法,當Service上綁定的所有客戶端都斷開連接的時候回調它,我們也可以主動斷開Service,那麼就用到它了,主動斷開,注意主動斷開Service的時候,ServiceConnection 中的onServiceDisconnected方法將不會回調。
示例:Service的框架

————————4、Service的兩種運行方式———————————–
方式一:通過Context的StartService()和stopService()來運行,該方法啓動的Service和調用者並沒有半毛錢關係,當調用者退出了,Service繼續運行。
寫多了累,上圖!
顯示StartService和關閉StopService
這個實例就是簡單的啓動和關閉服務,沒有什麼其他的,只是調用的Activity關閉了,Service繼續運行。

方式二:通過Context的bindService()方法啓動,重點來了,使用該方法調用者與Service有着綁定關係,訪問者一旦退出,Service也就終止了。下面詳細講解第二種運行方式及如何通過IBinder對象進行通訊的,下面的內容默認爲第二種運行方式:
——————————–小強來了——————————
運行此種方法的原因:
由於第一種方式調用者與Service雖然有啓動關係,但是啓動之後他們之間就沒有任何關係,所以當需要調用者與被啓動的Service需要數據傳輸或者通訊的時候,就需要我們的bindService()來解決了;

此種方法全名和參數詳解:
bindService(Intent service,ServiceConnection conn,int flags)
參數Intent service:建立一個意圖,明確我們需要啓動那個Service,如Intent intent = new Intent(this,BindService.class);
參數ServiceConnection conn: 是個ServiceConnection對象,他用於監聽訪問者與需要啓動的 Service是否建立聯繫,
如果連接成功則回調方法:ServiceConnection.onServiceConnected(ComponentName name**,IBinder service)**;
如果斷開連接則回調方法:ServiceConnection.onServiceDisConnected(ComponentName name,IBinder service);
注意:這裏的斷開連接是系統自動斷開的,如果是我們自己主動斷開的,則不調用ServiceConnection.onServiceDisConnected(ComponenetName name,IBinder service);
參數:flags看着名字也知道是什麼意思,這裏分爲自動創建和不自動創建,自動創建爲BIND_AUTO_CREATE;不自動創建爲0;
上代碼:service代碼

import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;

public class MyService extends Service {
    private int count;
    private boolean quit;
    private MyBinder binder = new MyBinder();
    public class MyBinder extends Binder{
        public int getCount(){
            return count;
        }
    }
    /*
     * IBinder和Binder的關係:
     *   1.IBinder是接口,Binder是具體實現類,實現了IBinder的類需要重載編寫行爲和邏輯,而Binder是具體類,具有自己的功能。
     *   2.一個繼承了Binder的類就實現了一個IBinder接口.Binder是IBinder的實現類;
     */
    //必須實現的方法
    @Override
    public IBinder onBind(Intent intent) {
        System.out.println("Service is Binder!");
        return binder;
    }
    //當創建Service時調用
    @Override
    public void onCreate() {
        super.onCreate();
        System.out.println("Service is Create!");
        new Thread(){
            @Override
            public void run(){
                while(!quit){
                    try{
                        Thread.sleep(1000);
                    }catch(InterruptedException e){

                    }
                    count++;
                }
            }
        }.start();
    }
    //當被斷開連接的時候調用該方法
    @Override
    public boolean onUnbind(Intent intent) {
        System.out.println("Service is unConnection!");
        return true;
    }
    //當關閉Service的之前調用該方法
    @Override
    public void onDestroy() {
        super.onDestroy();
        this.quit = true;
        System.out.println("Service is Destroy!");
    }
}

上代碼:Activity代碼:

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 {
    /*
     * 創建ServiceConnection對象,關於ServiceConnection的詳細理解隨後查閱
     * 當創建ServiceConnection之後,必須要重載他的兩個方法,
     *          一個是建立連接的時候調用的onServiceConnected(ComponenetName name,iBinder service);
     *          一個是斷開連接的時候調用的onServiceDisConneced(ComponentName name);
     * 
     * 
     */
    private MyService.MyBinder binder;
    private Button create,unBind,get;
    private ServiceConnection conn = new ServiceConnection(){
        //當該Activity與Service建立連接的時候回調該方法
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            System.out.println("--Service connection---!");
            binder = (MyService.MyBinder)service;
        }
        //當該Activity與Service斷開連接的時候回調該方法
        @Override
        public void onServiceDisconnected(ComponentName name) {
            System.out.println("Server Disconnection");
        }
    };
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        create = (Button)findViewById(R.id.create);
        unBind = (Button)findViewById(R.id.unbind);
        get = (Button)findViewById(R.id.get);
        final Intent intent = new Intent(this,MyService.class);//創建啓動Service的Intent
        create.setOnClickListener(new OnClickListener(){
            @Override
            public void onClick(View resources){
                bindService(intent,conn,Service.BIND_AUTO_CREATE);
            }
        });
        unBind.setOnClickListener(new OnClickListener(){
            @Override
            public void onClick(View resources){
                unbindService(conn);
            }
        });

        get.setOnClickListener(new OnClickListener(){
            @Override
            public void onClick(View resources){
                Toast.makeText(MainActivity.this,String.valueOf(binder.getCount()), Toast.LENGTH_LONG).show();
            }
        });
    }
}

這裏重點說下用bindService(intent,conn,flags)運行的程序如何在調用者和Service頁面傳遞數據的:
首先是方法bindService(Intent intent,ServiceConnection conn,int flags) 啓動了程序。
啓動程序後Service的onCreate()開始運行,丟丟丟丟丟……..開始運行了。
然後運行onBind()方法了,create之後就能確認綁定了,這個方法的回調條件是確認Service綁定,這裏需要注意了,重點來了:這裏我們return binder;了,這個binder是繼承了Binder的內部類的實例化,代碼在這兩行:

    private MyBinder binder = new MyBinder();
    public class MyBinder extends Binder{
        public int getCount(){
            return count;
        }
    }

然後開始回調方法onServiceConnected(ComponentName name,IBinder service了,該方法回調條件就是建立連接。這裏的service是IBinder類型,她(注意有一個美女的她來表示)等於前面方法onBind()方法return binder,她接受了return的結果,因爲不是大腿,不是老司機,所以不知道底層怎麼傳輸的,這裏我就記住吧,這裏的service就是前面繼承了IBinder的內部類的實例化,實際上通過這個繼承了IBinder的內部類實例化,我們可以調用很多Service裏面的東西,只要需要!下面應用書上的一段話來總結,加深下印象:

IBinder對象相當於Service組件的內部鉤子,該鉤子關聯到綁定的Service組件,當其他程序組件綁定了該Service時,Service將把Ibinder對象返回給其他程序組件,其他程序組件通過Ibinder對象即可進行實施通信!

還有一段哈,是這樣說的:

對於Service的onBind()方法返回的IBinder對象來說,他可以被當成該Service組件所返回的代理對象,Service允許調用者通過該IBinder對象來訪問Service內部數據,這樣就可以實現調用者或者客戶端與Service之間的數據傳輸

對於Service頁面中利用繼承了Binder的內部類實例化對象來返回給調用者,書上說是通用的做法,那就記住吧,小白的我也不知道其他辦法,說實話我都不知道怎麼用,先記住吧。

發佈了16 篇原創文章 · 獲贊 6 · 訪問量 3萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章