Android總結篇系列:Android Service

來源:互聯網
上載者:User

標籤:

Service作為Android中四大基本組件之一,也是App中經常要用到的。其實,Service這塊的知識點還是有些多的,下面要分別一一總結下。

Service通常總是稱之為“後台服務”,其中“後台”一詞是相對於前台而言的,具體是指其本身的運行並不依賴於使用者可視的UI介面,因此,從實際業務需求上來理解,Service的適用情境應該具備以下條件:

1.並不依賴於使用者可視的UI介面(當然,這一條其實也不是絕對的,如前台Service就是與Notification介面結合使用的);

2.具有較長時間的運行特性。

1.Service AndroidManifest.xml 聲明

一般而言,從Service的啟動方式上,可以將Service分為Started Service和Bound Service。無論哪種具體的Service啟動類型,都是通過繼承Service基類自訂而來。在使用Service時,要想系統能夠找到此自訂Service,無論哪種類型,都需要在AndroidManifest.xml中聲明,文法格式如下:

 1 <service android:enabled=["true" | "false"] 2     android:exported=["true" | "false"] 3     android:icon="drawable resource" 4     android:isolatedProcess=["true" | "false"] 5     android:label="string resource" 6     android:name="string" 7     android:permission="string" 8     android:process="string" > 9     . . .10 </service>

其中,android:exported屬性上一篇博文中對此已進行詳盡描述,android:name對應Service類名,android:permission是許可權聲明,android:process設定具體的進程名稱。需要注意的是Service能否單獨使用一個進程與其啟動方式有關,本後下面會給出具體說明。其他的屬性此處與其他組件基本相同,不再過多描述。

註:如果自訂Service沒有在AndroidManifest.xml中聲明,當具體使用時,不會像Activity那樣直接崩潰報錯,但是Service沒法啟動,這反而使得有時候不容易發現忘了聲明而一時定位不到問題。

 

2.Started Service

 Started Service相對比較簡單,通過context.startService(Intent serviceIntent)啟動Service,context.stopService(Intent serviceIntent)停止此Service。當然,在Service內部,也可以通過stopSelf(...)方式停止其本身。

1)Started Service自訂

下面程式碼片段顯示的是一個最基本的Started Service的自訂方式:

 1 public class MyService extends Service { 2  3     public static final String TAG = "MyService"; 4  5     @Override 6     public IBinder onBind(Intent intent) { 7         return null; 8     } 9 10     @Override11     public void onCreate() {12         super.onCreate();13         Log.w(TAG, "in onCreate");14     }15 16     @Override17     public int onStartCommand(Intent intent, int flags, int startId) {18         Log.w(TAG, "in onStartCommand");19         Log.w(TAG, "MyService:" + this);20         String name = intent.getStringExtra("name");21         Log.w(TAG, "name:" + name);22         return START_STICKY;23     }24 25     @Override26     public void onDestroy() {27         super.onDestroy();28         Log.w(TAG, "in onDestroy");29     }30 }

其中,onBind(...)函數是Service基類中的唯一抽象方法,子類都必須重寫實現,此函數的傳回值是針對Bound Service類型的Service才有用的,在Started Service類型中,此函數直接返回 null 即可。onCreate(...)、onStartCommand(...)和onDestroy()都是Started Service相應生命週期階段的回呼函數。

2) Started Service使用

 1 public class MainActivity extends Activity { 2  3     public static final String TAG = "MainActivity"; 4  5     private Button startServiceBtn; 6     private Button stopServideBtn; 7     private Button goBtn; 8  9     private Intent serviceIntent;10 11     @Override12     protected void onCreate(Bundle savedInstanceState) {13         super.onCreate(savedInstanceState);14         setContentView(R.layout.activity_main);15 16         startServiceBtn = (Button) findViewById(R.id.start_service);17         stopServideBtn = (Button) findViewById(R.id.stop_service);18         goBtn = (Button) findViewById(R.id.go);19 20         startServiceBtn.setOnClickListener(new View.OnClickListener() {21             @Override22             public void onClick(View v) {23                 serviceIntent = new Intent(MainActivity.this, MyService.class);24                 startService(serviceIntent);25             }26         });27 28         stopServideBtn.setOnClickListener(new View.OnClickListener() {29             @Override30             public void onClick(View v) {31                 stopService(serviceIntent);32             }33         });34 35         goBtn.setOnClickListener(new View.OnClickListener() {36             @Override37             public void onClick(View v) {38                 Intent intent = new Intent(MainActivity.this, BActivity.class);39                 startActivity(intent);40             }41         });42 43     }44 45     @Override46     protected void onDestroy() {47         super.onDestroy();48         Log.w(TAG, "in onDestroy");49     }50 }

如上程式碼片段,

當Client調用startService(Intent serviceIntent)後,如果MyService是第一次啟動,首先會執行 onCreate()回調,然後再執行onStartCommand(Intent intent, int flags, int startId),當Client再次調用startService(Intent serviceIntent),將只執行onStartCommand(Intent intent, int flags, int startId),因為此時Service已經建立了,無需執行onCreate()回調。無論多少次的startService,只需要一次stopService()即可將此Service終止,執行onDestroy()函數(其實很好理解,因為onDestroy()與onCreate()回調是相對的)。

下面重點關注下onStartCommand(Intent intent, int flags, int startId)方法。

其中參數flags預設情況下是0,對應的常量名為START_STICKY_COMPATIBILITY。startId是一個唯一的整型,用於表示此次Client執行startService(...)的請求請求標識,在多次startService(...)的情況下,呈現0,1,2....遞增。另外,此函數具有一個int型的傳回值,具體的可選值及含義如下:

START_NOT_STICKY:當Service因為記憶體不足而被系統kill後,接下來未來的某個時間內,即使系統記憶體足夠可用,系統也不會嘗試重新建立此Service。除非程式中Client明確再次調用startService(...)啟動此Service。

START_STICKY:當Service因為記憶體不足而被系統kill後,接下來未來的某個時間內,當系統記憶體足夠可用的情況下,系統將會嘗試重新建立此Service,一旦建立成功後將回調onStartCommand(...)方法,但其中的Intent將是null,pendingintent除外。

START_REDELIVER_INTENT:與START_STICKY唯一不同的是,回調onStartCommand(...)方法時,其中的Intent將是非空,將是最後一次調用startService(...)中的intent。

START_STICKY_COMPATIBILITY:compatibility version of {@link #START_STICKY} that does not guarantee that {@link #onStartCommand} will be called again after being killed。此值一般不會使用,所以注意前面三種情形就好。

以上的描述中,”當Service因為記憶體不足而被系統kill後“一定要非常注意,因為此函數的傳回值設定只是針對此種情況才有意義的,換言之,當認為的kill掉Service進程,此函數傳回值無論怎麼設定,接下來未來的某個時間內,即使系統記憶體足夠可用,Service也不會重啟。

 

 

 

 

Android總結篇系列:Android 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.