學習Service

本次內容參考於《瘋狂的android》第3版的個人學習筆記
———————————————————————————————————————————————————


  Service是Android四大組件之一(其餘是Activity、BroadcastReceiver)。作用是在後臺工作,比如播放着音樂時候啓動小說軟件,音樂仍然在播放;在後臺檢測網絡的變化等等;總而言之,在暗地裏默默付出的人。
  Service在android四大組件中是與Activity最相似的組件,他們都代表可執行的程序。
區別:
Service一直在後臺運行,沒有用戶界面。
選擇標準
如果某個程序組件需要在運行時向用戶呈現某種界面,或者與用戶交互,就需要用到Activity,否則使用Service了。
相似:
1、創建的步驟很像,先定義繼承子類,在AndroidManifest.xml文件中配置。
2、Service也具有自己的生命週期。
3、都是從Context派生出來的,都可以調用Context.getResources()、getContentResolver()等方法。

Service的兩種啓動模式:startService()、bindService()
  • 通過Context的startService()來啓動Service,訪問者與Service之間沒有關聯,即使訪問者退出了,Service也仍然運行。
  • 通過Context的bindService()來啓動Service,訪問者與Service綁定在一起,訪問者一旦退出,Service也結束。

      號稱前者爲:持續不斷,後者稱爲一退就斷!

-------------------------------------------

      接下來是startService的啓動和停止的代碼,該Activity的界面中包含2個按鈕,一個按鈕用於啓動Service,另一個用於停止Service。

Activity的代碼:

public class MainActivity extends Activity implements View.OnClickListener, ServiceConnection {
 
    private Button btnStartService;
    private Button btnStoptService;//定義兩個按鈕

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        btnStartService = (Button) findViewById(R.id.btnStartService);
        btnStoptService = (Button) findViewById(R.id.btnStoptService);//獲取兩個按鈕

        btnStartService.setOnClickListener(this);
        btnStoptService.setOnClickListener(this);//按鈕事件
    }

    @Override
    public void onClick(View v) {
 
        Intent intent = new Intent(MainActivity.this, MyService.class); //1、創建啓動Service的Intent

       switch (v.getId()) {
            case R.id.btnStartService:
                startService(intent); //2、啓動指定的Service
                break;
            case R.id.btnStoptService:
                stopService(intent);//3、停止指定的Service
                break;
        }
    }
}
  調用Context裏的startService()、stopService()方法即可啓動、停止Service,操作十分簡單。而且程序使用了顯式Intent來啓動Service,因爲從5.0開始,Google要求必須使用顯式Intent啓動Service組件。我個人覺得這樣十分好,因爲像Service這樣使用頻率高,而且用到的地方都是比較重要部位,這樣會提高安全性吧。

接下來是通過startService()啓動Service的生命週期:

context.startService() ->onCreate()  ->onStartCommand()  ->Service running

context.stopService() ->onDestroy() ->Service stop

如果Service已經運行,這是再點擊啓動按鈕,就不會再調用onCreate() 方法,則只會調用onStartCommand()方法,而且可以執行多次.

總結得出 onCreate->onStartCommand(可以多次調用) ->onDestroy

--------------------------------

接下來是bindService()綁定本地Service,並與之通信。

當程序使用startService()來啓動Service時,Service和訪問者無法進行通信、交換數據。因此如果需要做以上動作,就應該使用bindService()和unbindService方法來啓動、關閉Service。

Context的bindService()方法的完整方法簽名爲:bindService(Intent service,ServiceConnection conn,int flags)

Intent service:該參數通過Intent指定要啓動的Service。

ServiceConnection conn該對象用於監聽訪問者與Service之間的連接情況(一般情況爲this,但要實現ServiceConnection)。

int flags指定綁定時是否自動創建Service(該參數可以指定0(不自動創建)或BIND_AUTO_CREATE(自動創建))。

  當開發Service類時,該Service類必須提供一個IBinder onBind(Intent intent)方法,在綁定本地Service的情況下,onBind(Intent intent)方法所返回的IBinder對象將會傳給ServiceConnection對象裏onServiceConndected()方法的service參數,這樣訪問者就可以通過IBinder對象與Service進行通信了。

  實際上,開發通常會採用繼承Binder(IBinder的實現類)的方式實現自己的IBinder對象。

  接下來在Activity中綁定本地Service:

public class MyService extends Service {

    public MyService() {
    }

    @Override
    public IBinder onBind(Intent intent) {

        System.out.println("onBind");
        return new Binder();//返回一個Binder對象
    }

    @Override
    //當啓動成功後會執行的方法
    public int onStartCommand(Intent intent, int flags, int startId) {


        System.out.println("onStartCommand");
        new Thread() {
            public void run() {
                super.run();
        
                while (ture) {
                    System.out.println("服務正在運行中...");
                    try {
                        sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }.start();
        return super.onStartCommand(intent, flags, startId);
    }

    @Override
    public void onCreate() {
        super.onCreate();
        System.out.println("onCreate");
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        System.out.println("onDestroy");
    }

    @Override
    public boolean onUnbind(Intent intent) {
        System.out.println("onUnbind");
        return super.onUnbind(intent);
    }
}
MainActivity 的代碼如下

public class MainActivity extends Activity implements View.OnClickListener, ServiceConnection {
    private Button btnStartService;
    private Button btnStoptService;
    private Button btnBindService;  //綁定服務
    private Button btnUnBindService;//解除綁定服務


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        btnStartService = (Button) findViewById(R.id.btnStartService);
        btnStoptService = (Button) findViewById(R.id.btnStoptService);
        btnBindService = (Button) findViewById(R.id.btnBindService);//綁定服務
        btnUnBindService = (Button) findViewById(R.id.btnUnBindService);//解除綁定服務


        btnStartService.setOnClickListener(this);
        btnStoptService.setOnClickListener(this);
        btnBindService.setOnClickListener(this);//按鈕事件
        btnUnBindService.setOnClickListener(this);

    }

    @Override
    public void onClick(View v) {

       Intent intent = new Intent(MainActivity.this, MyService.class); //指定Intent

        switch (v.getId()) {
            case R.id.btnStartService:
                startService(intent);
                break;
            case R.id.btnStoptService:
                stopService(intent);
                break;
            case R.id.btnBindService:
                bindService(intent, this, Context.BIND_AUTO_CREATE);//綁定服務
                break;
            case R.id.btnUnBindService:
                unbindService(this);//解除綁定服務
                break;
        }
    }

    @Override
    public void onServiceConnected(ComponentName name, IBinder service) {//服務被綁定成功的時候運行
        System.out.println("onServiceConnected");
    }

    @Override
    public void onServiceDisconnected(ComponentName name) { //進程被殺掉 或者 奔潰的時候運行
        System.out.println("onServiceDisconnected");
    }
使用context.bindService()啓動Service的經歷:
  context.bindService() -> onCreate() ->onBind()     ->Service running
  unbindService()  -> onUnbind() ->  onDestroy()      ->Service stop

總而言之,onCreate --> onBind(只一次,不可多次綁定) --> onUnbind --> onDestory。













發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章