第七章:四大元件之Service

自助者天助發表於2014-11-28

Service是Android系統中的一種元件,它跟Activity的級別差不多,但是它不能自己執行,只能後臺執行,並且可以和其他元件進行互動。Service是沒有介面的長生命週期的程式碼。Service是一種程式,它可以執行很長時間,但是它卻沒有使用者介面。這麼說有點枯燥,來看個例子,開啟一個音樂播放器的程式,這個時候若想上網了,那麼,我們開啟Android瀏覽器,這個時候雖然我們已經進入了瀏覽器程式,但是,歌曲播放並沒有停止,而是在後臺繼續一首接著一首地播放。其實這個播放就是由播放音樂的Service進行控制的。   
當然這個播放音樂的Service也可以停止,例如,當播放列表裡邊的歌曲都結束,或者使用者按下了停止音樂播放的快捷鍵等。Service可以在很多場合的應用中使用,比如播放多媒體的時候使用者啟動了其他Activity,這個時候程式要在後臺繼續播放,比如檢測SD卡上檔案的變化,再或者在後臺記錄使用者地理資訊位置的改變等等。總之服務嘛,總是藏在後頭的。

一、註冊Service

service的註冊跟activity的註冊類似,同樣是要在AndroidManifest.xml的檔案裡註冊。

 

<service android:name=".MyService">
        <intent-filter>
                <action android:name="android.guo.service.playmusic.MyService"/>
            </intent-filter>
        </service>
View Code

 

二、Service的兩種模式

 

service有兩種模式,本地服務和遠端服務。我們一般開發應用都是用的本地服務,而遠端服務經常在做系統開發時被用到。所以今天我會主要講本地的服務,遠端服務放著以後再講吧(其實UP主也沒用過遠端服務就是了==)

 

類別 區別  優點 缺點   應用
本地服務(Local) 該服務依附在主程式上,  服務依附在主程式上而不是獨立的程式,這樣在一定程度上節約了資源,另外Local服務因為是在同一程式因此不需要IPC,也不需要AIDL。相應bindService會方便很多。  主程式被Kill後,服務便會終止。  非常常見的應用如:HTC的音樂播放服務,天天動聽音樂播放服務。
遠端服務(Remote) 該服務是獨立的程式,  服務為獨立的程式,對應程式名格式為所在包名加上你指定的android:process字串。由於是獨立的程式,因此在Activity所在程式被Kill的時候,該服務依然在執行,不受其他程式影響,有利於為多個程式提供服務具有較高的靈活性。  該服務是獨立的程式,會佔用一定資源,並且使用AIDL進行IPC稍微麻煩一點。  一些提供系統服務的Service,這種Service是常駐的。

 

三、Service的生命週期及兩種啟動方式

service的生命週期比activity簡單多了,原因是service是在後臺執行的,它是一直執行的,所以不需要那麼多的狀態判斷。它只繼承了onCreate()、onStart()或者說是onStartCommand()// 2.0 API level之後,實現onStart等同於重寫onStartCommand並返回  關於onStartCommon()的詳解:http://blog.csdn.net/lizzy115/article/details/7001731

onDestroy()三個方法。 服務不能自己執行,需要通過呼叫Context.startService()或Context.bindService()方法啟動服務。這兩個方法都可以啟動Service,但是它們的使用場合有所不同。

  1. 使用startService()方法啟用服務,呼叫者與服務之間沒有關連,即使呼叫者退出了,服務仍然執行。    如果打算採用Context.startService()方法啟動服務,在服務未被建立時,系統會先呼叫服務的onCreate()方法,接著呼叫onStart()方法。如果呼叫startService()方法前服務已經被建立,多次呼叫startService()方法並不會導致多次建立服務,但會導致多次呼叫onStart()方法。 採用startService()方法啟動的服務,只能呼叫Context.stopService()方法結束服務,服務結束時會呼叫onDestroy()方法。
  2. 使用bindService()方法啟用服務,呼叫者與服務繫結在了一起,呼叫者一旦退出,服務也就終止,大有“不求同時生,必須同時死”的特點。onBind()只有採用Context.bindService()方法啟動服務時才會回撥該方法。該方法在呼叫者與服務繫結時被呼叫,當呼叫者與服務已經繫結,多次呼叫Context.bindService()方法並不會導致該方法被多次呼叫。採用Context.bindService()方法啟動服務時只能呼叫onUnbind()方法解除呼叫者與服務解除,服務結束時會呼叫onDestroy()方法。

 

四、Service例項

ServiceActivity.java:

package com.example.helloandroid;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;

public class ServiceActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_service);
        Button btnStartService = (Button)this.findViewById(R.id.btnStartService);
        Button btnStopService = (Button)this.findViewById(R.id.btnStopService);
        btnStartService.setOnClickListener(new OnClickListener(){
            @Override
            public void onClick(View v) {
                startService(new Intent(ServiceActivity.this, MyService.class));
            }
        });
        btnStopService.setOnClickListener(new OnClickListener(){
            @Override
            public void onClick(View v) {
                stopService(new Intent(ServiceActivity.this, MyService.class));
            }
        });
    }

    @Override  
    protected void onStart() {  
        super.onStart();   
    }  
    @Override  
    protected void onResume() {  
        super.onResume();   
    }  
    @Override  
    protected void onPause() {  
        super.onPause();  
    }  
    @Override  
    protected void onStop() {  
        super.onStop();   
    }  
    @Override  
    protected void onDestroy() {  
        super.onDestroy();   
    }
}
View Code

activicy_service.xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >
    <TextView
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="服務" />
    <Button
        android:id="@+id/btnStartService"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="啟動服務" />
    <Button
        android:id="@+id/btnStopService"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="停止服務" />
</LinearLayout>
View Code

MyService.java:

package com.example.helloandroid;

import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.util.Log;
import android.widget.Toast;

public class MyService  extends Service{
    private final String STR_TAG ="TAG";
    @Override
    public IBinder onBind(Intent intent) {

        // TODO Auto-generated method stub

        return null;

    }
    @Override
    public void onCreate(){

        Log.v(STR_TAG, "My Service Create");
    }
    @Override

    public void onStart(Intent intent, int startId)

    {

         Log.v(STR_TAG, "My Service Started");

    }
    @Override

    public void onDestroy(){
         Log.v(STR_TAG, "My Service Destroy");

    }


}
View Code

 

啟動Service過程如下:
context.startService()  ->onCreate()- >onStart()->Service running
其中onCreate()可以進行一些服務的初始化工作.

停止Service過程如下:
context.stopService() | ->onDestroy() ->Service stop

 

相關文章