Android 02 Started Service--之被啟動的服務

來源:互聯網
上載者:User

 

本文

 

 

1 Started Service介紹

Started Service,即被啟動的服務。它是2種常見服務之一,另一種是Bound Service。Started Service常被用在執行進程的某個後台操作,如通過該服務來實現檔案下載等功能。

實現步驟和使用方法

(01) 建立一個Started Service類,該類要繼承於Service。

(02) 在Started Service類中實現以下介面:
onStartCommand():必須實現!在其中啟動服務提供的功能。例如,若該服務是在後台下載檔案,則在該函數中啟動一個新的線程(Thread),線上程中實現下載功能。當客>戶端通過startService()啟動函數時,系統會自動執行服務對應的onStartCommand()函數。
onBind():必須實現!返回null即可。onBind()是Bound Service中用到的函數,在Started Service服務不會執行onBind();但必須實現它,因為onBind()是Service類
的抽象方法。
onCreate():可以不用實現,視使用者需求而定。當服務被建立時,系統會自動調用該函數。一般在該函數中進行初始化工作,例如:建立線程。
onDestroy():可以不用實現,視使用者需求而定。當服務被銷毀時,系統會自動調用該函數。一般在該函數中進行清除工作,例如,終止並回收線程。

(03) 用戶端通過startService()啟動服務。

(04) 用戶端通過endService()結束服務。

下面以實際例子來說明“Started Service”的實現方式。

2 Service樣本

採用Service來實現“Android IntentService”中的樣本,即:編寫一個activity,包含2個按鈕和1個進度條,2個按鈕分別是開始按鈕、結束按鈕。點擊“開始”按鈕:進度條開始載入;“開始”變成“重啟”按鈕;顯示“結束”按鈕(預設情況,“結束”按鈕是隱藏狀態)。

BaseServiceTest包括了兩個主要的類:

StartServiceImpl.java —— Service的子類。當服務被啟動時,它會並建立一個線程,每隔200ms將一個數字+2,並通過廣播發送出去。

StartServiceTest.java —— 調用StartServiceImpl的Activity。

StartServiceImpl.java的內容如下

package com.skywang.service;import android.os.IBinder;import android.app.Service;import android.content.Intent;import android.util.Log;import java.lang.Thread;/** * @desc 服務:每隔200ms將一個數字+2並通過廣播發送出去 * @author skywang * */public class StartServiceImpl extends Service {    private static final String TAG = skywang-->StartServiceImpl;        // 發送的廣播對應的action    private static final String COUNT_ACTION = com.skywang.service.startservice.COUNT_ACTION;        // 線程:用來實現每隔200ms發送廣播    private static CountThread mCountThread = null;    // 數位索引    private static int index = 0;        @Override    public void onCreate() {        Log.d(TAG, onCreate);        super.onCreate();    }        @Override    public void onDestroy() {        Log.d(TAG, onDestroy);        // 終止服務        if ( mCountThread != null) {            mCountThread.interrupt();            mCountThread = null;        }        super.onDestroy();    }        @Override    public int onStartCommand(Intent intent, int flags, int startId) {        Log.d(TAG, onStartCommand);                // 非首次運行服務時,執行下面操作        // 目的是將index設為0        if ( mCountThread != null) {            Log.d(TAG, mCountThread != null);            index = 0;            return START_STICKY;        }                Log.d(TAG, start thread);        // 首次運行時,建立並啟動線程        mCountThread = new CountThread();        mCountThread.start();                return START_STICKY;    }        @Override    public IBinder onBind(Intent intent) {        Log.d(TAG, onBind);        return null;    }        private class CountThread extends Thread {        @Override         public void run() {            index = 0;            try {                while (true) {                    // 將數字+2,                    index += 2;                                                            // 將index通過廣播發送出去                    Intent intent = new Intent(COUNT_ACTION);                    intent.putExtra(count, index);                    sendBroadcast(intent);//                    Log.d(TAG, CountThread index:+index);                                        // 若數字>=100 則退出                    if (index >= 100) {                        if ( mCountThread != null) {                            mCountThread = null;                        }                        return ;                    }                                        // 修改200ms                    this.sleep(100);                }            } catch (InterruptedException e) {                e.printStackTrace();            }        }    }}
StartServiceTest.java的內容如下:

 

package com.skywang.service;import android.os.Bundle;import android.app.Activity;import android.content.BroadcastReceiver;import android.content.Context;import android.content.Intent;import android.content.IntentFilter;import android.view.View;import android.widget.Button;import android.widget.ProgressBar;import android.util.Log;public class StartServiceTest extends Activity {    private static final String TAG = skywang-->StartServiceTest;    private static final String COUNT_ACTION = com.skywang.service.startservice.COUNT_ACTION;    private CurrentReceiver mReceiver;    private Button mStart = null;    private Button mStop = null;    private Intent mIntent = null;    private Intent mServiceIntent = null;     private ProgressBar mProgressBar = null;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.start_service_test);                mStart = (Button) findViewById(R.id.start);        mStart.setOnClickListener(new View.OnClickListener() {                        @Override            public void onClick(View arg0) {                Log.d(TAG, click start button);                // 顯示“結束”按鈕                mStop.setVisibility(View.VISIBLE);                // 將“開始”按鈕更名為“重啟”按鈕                mStart.setText(R.string.text_restart);                // 啟動服務,用來更新進度                if (mServiceIntent == null)                     mServiceIntent = new Intent(com.skywang.service.StartService);                startService(mServiceIntent);            }        });                mStop = (Button) findViewById(R.id.stop);        mStop.setOnClickListener(new View.OnClickListener() {                        @Override            public void onClick(View view) {                Log.d(TAG, click stop button);                if (mServiceIntent != null) {                    // 結束服務。                    stopService(mServiceIntent);                    mServiceIntent = null;                }            }        });        mStop.setVisibility(View.INVISIBLE);                mProgressBar = (ProgressBar) findViewById(R.id.pbar_def);        // 隱藏進度條        mProgressBar.setVisibility(View.INVISIBLE);                // 動態註冊監聽COUNT_ACTION廣播        mReceiver = new CurrentReceiver();        IntentFilter filter = new IntentFilter();        filter.addAction(COUNT_ACTION);        this.registerReceiver(mReceiver, filter);    }    @Override      public void onDestroy(){          super.onDestroy();            if(mIntent != null)            stopService(mIntent);                if(mReceiver != null)            this.unregisterReceiver(mReceiver);    }        /**     * @desc 更新進度條     * @param index     */    private void updateProgressBar(int index) {        int max = mProgressBar.getMax();        if (index < max) {            mProgressBar.setProgress(index);            mProgressBar.setVisibility(View.VISIBLE);        } else {            // 隱藏進度條            mProgressBar.setVisibility(View.INVISIBLE);            // 隱藏“結束”按鈕            mStop.setVisibility(View.INVISIBLE);            // 將“重啟”按鈕更名為“開始”按鈕            mStart.setText(R.string.text_start);        }//        Log.d(TAG, progress : +mProgressBar.getProgress()+ , max : +max);    }        /**     * @desc 廣播:監聽COUNT_ACTION,擷取索引值,並根據索引值來更新進度條     * @author skywang     *     */    private class CurrentReceiver extends BroadcastReceiver {        @Override        public void onReceive(Context context, Intent intent) {            String action  = intent.getAction();            if (COUNT_ACTION.equals(action)) {                int index = intent.getIntExtra(count, 0);                updateProgressBar(index);            }        }    }}
layout檔案start_service_test.xml的內容如下:
                        
manifest內容如下:
                                                                                                                                                    

 

點擊下載: 原始碼

3 補充說明

在樣本中,我們自訂了onStartCommand()的傳回值。Android API文檔中說明它的傳回值,可以有以下4種:

START_STICKY

如果service進程被kill掉,保留service的狀態為開始狀態,但不保留遞送的intent對象。隨後系統會嘗試重新建立service,由於服務狀態為開始狀態,所以建立服務後一定會調用onStartCommand(Intent,int,int)方法。如果在此期間沒有任何啟動命令被傳遞到service,那麼參數Intent將為null。

START_NOT_STICKY

“非粘性的”。使用這個傳回值時,如果在執行完onStartCommand後,服務被異常kill掉,系統不會自動重啟該服務。

START_REDELIVER_INTENT

重傳Intent。使用這個傳回值時,如果在執行完onStartCommand後,服務被異常kill掉,系統會自動重啟該服務,並將Intent的值傳入。

START_STICKY_COMPATIBILITY

START_STICKY的相容版本,但不保證服務被kill後一定能重啟。



聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.