Android-服務(wù)的基本用法(一)

服務(wù)作為安卓開發(fā)的四大組件之一,發(fā)揮著非常重要的作用,下面我們以一些簡(jiǎn)單實(shí)例嘱能,總結(jié)一下服務(wù)的基本用法。

定義一個(gè)服務(wù)

新建一個(gè)項(xiàng)目员咽,在項(xiàng)目中定義一個(gè)服務(wù):com.example.adiqueen.servicetest->New->Service->Service,我們會(huì)看到對(duì)話框:


new Service

exported表示是否允許當(dāng)前程序意外的其他程序本服務(wù)退客。
enabled表示是否啟用這個(gè)服務(wù)骏融。
點(diǎn)擊finish完成創(chuàng)建。
這個(gè)時(shí)候我們可以看到MyService中的代碼:

public class MyService extends Service {
    public MyService() {
    }

    @Override
    public IBinder onBind(Intent intent) {
        // TODO: Return the communication channel to the service.
        throw new UnsupportedOperationException("Not yet implemented");
    }
}

MyService繼承自Service 有一個(gè)方法onBind()方法萌狂,這個(gè)方法是Service惟一的一個(gè)抽象方法档玻,必須要在子類中實(shí)現(xiàn)。如果我們要處理一些事情的話茫藏,就要用到幾個(gè)常見的其他方法误趴。

    /*
    服務(wù)中最常用的幾個(gè)方法
     */
    //服務(wù)在創(chuàng)建的時(shí)候調(diào)用的方法
    @Override
    public void onCreate() {
        Log.d("MyService","onCreate()-------");
        super.onCreate();
    }

    //服務(wù)在每次啟動(dòng)的時(shí)候調(diào)用的方法 如果某些行為在服務(wù)已啟動(dòng)的時(shí)候就執(zhí)行,可以把處理邏輯寫在這個(gè)方法里面

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {

        Log.d("MyService","onStartCommand()-------");

        return super.onStartCommand(intent, flags, startId);
    }

    //服務(wù)銷毀的時(shí)候調(diào)用的方法 可以回收部分不再使用的資源
    @Override
    public void onDestroy() {
        Log.d("MyService","onDestroy()-------");
        super.onDestroy();
    }

這個(gè)時(shí)候還沒完务傲,如果我們是使用此服務(wù)的話 這個(gè)服務(wù)在manifest中注冊(cè)才能正常使用凉当。

        <service
            android:name=".MyService"
            android:enabled="true"
            android:exported="true"></service>

啟用和停止服務(wù)

服務(wù)的啟用和停止我們不會(huì)感到陌生,因?yàn)橹饕墙柚鶬ntent來實(shí)現(xiàn)的售葡。下面我們看一下如何啟用和停止服務(wù)看杭。在這里我們?cè)O(shè)置兩個(gè)按鈕,分別點(diǎn)擊按鈕實(shí)現(xiàn)服務(wù)的啟用和停止挟伙。

public class MainActivity extends AppCompatActivity {

    private Button start_servece;

    private Button stop_servece;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        start_servece = (Button)findViewById(R.id.start_servece);
        stop_servece = (Button)findViewById(R.id.stop_servece);


        start_servece.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {

                Intent startIntent =  new Intent(MainActivity.this,MyService.class);

                startService(startIntent); //啟動(dòng)服務(wù)

            }
        });
        
        stop_servece.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {

                Intent stopIntent =  new Intent(MainActivity.this,MyService.class);

                stopService(stopIntent); //停止服務(wù)

                //MyService類中的任何一個(gè)位置調(diào)用stopSelf()也能停止服務(wù)
            }
        });

    }
}

因?yàn)榍懊嫖覀円呀?jīng)在服務(wù)的部分方法中添加了打印日志的代碼楼雹,這個(gè)時(shí)候我們點(diǎn)擊開啟按鈕,再點(diǎn)擊關(guān)閉按鈕之后的控制臺(tái)信息如下:

log

說明我們完成了服務(wù)的啟用和停止。

活動(dòng)和服務(wù)進(jìn)行通信

服務(wù)是在活動(dòng)里啟動(dòng)的贮缅,但是服務(wù)啟動(dòng)之后就和活動(dòng)沒有關(guān)系了榨咐。但是,活動(dòng)具體運(yùn)行的是什么邏輯呢谴供?活動(dòng)就控制不了了块茁。如果這樣的話,我們對(duì)服務(wù)的可控性是不是就差了很多桂肌。有沒有什么方式可以把活動(dòng)和服務(wù)綁定一下呢数焊?能夠方便活動(dòng)對(duì)服務(wù)更好的控制。答案是肯定的崎场。這個(gè)時(shí)候就要用到前面我們提到的Service的唯一抽象方法onBind()昌跌。我們來看一個(gè)簡(jiǎn)單的實(shí)例:在服務(wù)里實(shí)現(xiàn)下載的功能,并能實(shí)時(shí)查看下載的進(jìn)度照雁。
實(shí)現(xiàn)的思路是在MyService類中創(chuàng)建一個(gè)Buider對(duì)象來對(duì)下載功能進(jìn)行管理。
//新建一個(gè)DownloadBinder類繼承自Binder
//接著在MyService的onBind()方法中返回DownloadBinder實(shí)例答恶。

    private DownloadBinder mBinder = new DownloadBinder();

    class DownloadBinder extends Binder{

        public void startDownLoad(){

            Log.d("MyService","startDownLoad()----");

        }

        public int getProgress(){

            Log.d("MyService","getProgress()----");

            return 0;
        }
    }

    @Override
    public IBinder onBind(Intent intent) {

        return mBinder;
    }

MainActivity類中

public class MainActivity extends AppCompatActivity {

    private Button bind_servece;

    private Button unbind_servece;

    private MyService.DownloadBinder downloadBinder;

    private ServiceConnection serviceConnection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName componentName, IBinder iBinder) {

            downloadBinder = (MyService.DownloadBinder) iBinder;
            downloadBinder.startDownLoad();
            downloadBinder.getProgress();
        }

        @Override
        public void onServiceDisconnected(ComponentName componentName) {

        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        bind_servece = (Button)findViewById(R.id.bind_servece);
        unbind_servece = (Button)findViewById(R.id.unbind_servece);

        bind_servece.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {

                Intent bindIntent =  new Intent(MainActivity.this,MyService.class);

                bindService(bindIntent,serviceConnection,BIND_AUTO_CREATE);//綁定服務(wù)

            }
        });


        unbind_servece.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {

                unbindService(serviceConnection);//解綁服務(wù)

            }
        });

    }
}

在MainActivity類中:
創(chuàng)建了ServiceConnection匿名類 重寫了onServiceConnected()和onServiceDisconnected()方法饺蚊。這兩個(gè)方法會(huì)在活動(dòng)與服務(wù)綁定和解綁的時(shí)候調(diào)用。
在onServiceConnected()方法中我們向下轉(zhuǎn)型得到downloadBinder的實(shí)例悬嗓,有了這個(gè)實(shí)例活動(dòng)和服務(wù)之間的關(guān)系就變得很緊密了污呼。

在這里只是一個(gè)簡(jiǎn)單的打印日志,并未做過多的任務(wù)包竹。
部署程序燕酷、點(diǎn)擊按鈕可以看到日志:


log

服務(wù)的生命周期

服務(wù)和活動(dòng)一樣,也有自己的生命周期周瞎。前面有幾個(gè)方法我們都已經(jīng)使用到了苗缩。

一旦在項(xiàng)目中調(diào)用了Context的startService()方法,服務(wù)就會(huì)被啟動(dòng)起來声诸,并回調(diào)onStartCommand()方法酱讶。如果這個(gè)服務(wù)之前沒有被創(chuàng)建過,還會(huì)在onStartCommand()方法運(yùn)行之前彼乌,執(zhí)行onCreate() 方法泻肯。

服務(wù)一旦被啟用就會(huì)保持啟用的狀態(tài),知道調(diào)用了方法stopService()或者stopSelf()慰照。

另外灶挟,還可以調(diào)用Context的bindService()方法獲取一個(gè)持久的鏈接,Service的onBind()方法會(huì)被執(zhí)行毒租。而作為調(diào)用方的話可以或者onBind()方法里返回的IBinder對(duì)象的實(shí)例稚铣,這樣就能自由的和服務(wù)進(jìn)行通訊了。

調(diào)用了startService()方法以后,再調(diào)用stopService()方法的話榛泛,Service的onDestroy()方法就會(huì)執(zhí)行蝌蹂,證明服務(wù)已經(jīng)銷毀了。類似的調(diào)用bindService()曹锨、unbindService()方法后onDestroy()方法也會(huì)執(zhí)行孤个。加入我們同時(shí)調(diào)用了startService()和bindService(),那么這種情況該如何讓服務(wù)銷毀呢沛简?根據(jù)Android系統(tǒng)的機(jī)制齐鲤,一個(gè)服務(wù)只要調(diào)用startService()或bindService()中的一個(gè),就會(huì)一直處于運(yùn)行態(tài)椒楣。必須以上通知滿足给郊,onDestroy()方法才會(huì)執(zhí)行,服務(wù)才能銷毀捧灰。這個(gè)時(shí)候要同事調(diào)用stopService()和unbindService()方法淆九。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市毛俏,隨后出現(xiàn)的幾起案子炭庙,更是在濱河造成了極大的恐慌,老刑警劉巖煌寇,帶你破解...
    沈念sama閱讀 218,682評(píng)論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件焕蹄,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡阀溶,警方通過查閱死者的電腦和手機(jī)腻脏,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,277評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來银锻,“玉大人永品,你說我怎么就攤上這事』魑常” “怎么了腐碱?”我有些...
    開封第一講書人閱讀 165,083評(píng)論 0 355
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)掉弛。 經(jīng)常有香客問我症见,道長(zhǎng),這世上最難降的妖魔是什么殃饿? 我笑而不...
    開封第一講書人閱讀 58,763評(píng)論 1 295
  • 正文 為了忘掉前任谋作,我火速辦了婚禮,結(jié)果婚禮上乎芳,老公的妹妹穿的比我還像新娘遵蚜。我一直安慰自己帖池,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,785評(píng)論 6 392
  • 文/花漫 我一把揭開白布吭净。 她就那樣靜靜地躺著睡汹,像睡著了一般。 火紅的嫁衣襯著肌膚如雪寂殉。 梳的紋絲不亂的頭發(fā)上囚巴,一...
    開封第一講書人閱讀 51,624評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音友扰,去河邊找鬼彤叉。 笑死,一個(gè)胖子當(dāng)著我的面吹牛村怪,可吹牛的內(nèi)容都是我干的秽浇。 我是一名探鬼主播,決...
    沈念sama閱讀 40,358評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼甚负,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼柬焕!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起梭域,我...
    開封第一講書人閱讀 39,261評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤击喂,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后碰辅,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,722評(píng)論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡介时,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,900評(píng)論 3 336
  • 正文 我和宋清朗相戀三年没宾,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片沸柔。...
    茶點(diǎn)故事閱讀 40,030評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡循衰,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出褐澎,到底是詐尸還是另有隱情会钝,我是刑警寧澤,帶...
    沈念sama閱讀 35,737評(píng)論 5 346
  • 正文 年R本政府宣布工三,位于F島的核電站迁酸,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏俭正。R本人自食惡果不足惜奸鬓,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,360評(píng)論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望掸读。 院中可真熱鬧串远,春花似錦宏多、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,941評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至留搔,卻和暖如春更胖,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背催式。 一陣腳步聲響...
    開封第一講書人閱讀 33,057評(píng)論 1 270
  • 我被黑心中介騙來泰國(guó)打工函喉, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人荣月。 一個(gè)月前我還...
    沈念sama閱讀 48,237評(píng)論 3 371
  • 正文 我出身青樓管呵,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親哺窄。 傳聞我的和親對(duì)象是個(gè)殘疾皇子捐下,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,976評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容