成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專(zhuān)欄INFORMATION COLUMN

Android四大組件之Service

archieyang / 2784人閱讀

摘要:注意每個(gè)必須在中通過(guò)來(lái)聲明。執(zhí)行具體的下載任務(wù)接下來(lái)我們?cè)谥型ㄟ^(guò)來(lái)綁定和解除綁定可以看到,這里我們首先創(chuàng)建了一個(gè)的匿名類(lèi),在里面重寫(xiě)了方法和方法,這兩個(gè)方法分別會(huì)在與建立關(guān)聯(lián)和解除關(guān)聯(lián)的時(shí)候調(diào)用。

前言

Hi,大家好,上一期我們講了如何使用BroadcastReceiver,這一期我們講解Android四大組件之Service相關(guān)知識(shí)。每天一篇技術(shù)干貨,每天我們一起進(jìn)步。

耐心專(zhuān)注不僅僅是美德,更是一筆財(cái)富。

1.簡(jiǎn)介與定義
簡(jiǎn)介

Service是一個(gè)可以在后臺(tái)執(zhí)行長(zhǎng)時(shí)間運(yùn)行操作而不提供用戶(hù)界面的應(yīng)用組件。Service可由其他應(yīng)用組件啟動(dòng),而且即使用戶(hù)切換到其他應(yīng)用,Service仍將在后臺(tái)繼續(xù)運(yùn)行。 此外,組件可以綁定到Service,以與之進(jìn)行交互,甚至是執(zhí)行進(jìn)程間通信 (IPC)。 例如,Service可以處理網(wǎng)絡(luò)事務(wù)、播放音樂(lè),執(zhí)行文件 I/O 或與內(nèi)容提供程序交互,而所有這一切均可在后臺(tái)進(jìn)行。

定義

Service是一個(gè)專(zhuān)門(mén)在后臺(tái)處理長(zhǎng)時(shí)間任務(wù)的Android組件。

1.Service不是一個(gè)多帶帶的進(jìn)程;

2.Service也不是一個(gè)多帶帶的線(xiàn)程;

3.Service是一個(gè)多帶帶的Android組件,Service運(yùn)行在主線(xiàn)程上,如果想在Service中處理很占時(shí)間的操作時(shí),必須在Service中開(kāi)線(xiàn)程,以降低Activity沒(méi)有響應(yīng)的風(fēng)險(xiǎn);

4.Service不提供用戶(hù)界面;

它有兩種啟動(dòng)方式:startServicebindService。

2.用途

Service有三個(gè)常見(jiàn)用途。

1.功能調(diào)度:Service接收指定的廣播信息,從而進(jìn)一步分析和處理事件,最后修改數(shù)據(jù)、更新界面或者進(jìn)行其他相關(guān)的操作,調(diào)度整個(gè)應(yīng)用使其保持正確的狀態(tài)。

2.功能提供:Service并不會(huì)接收任何的廣播,只接收指定的廣播提供狀態(tài)數(shù)據(jù),這時(shí)需要綁定Service,綁定Service時(shí)要管理好Service,一般在A(yíng)ctivity的onStop函數(shù)里進(jìn)行解綁unBindService操作。

3.遠(yuǎn)程調(diào)用:定義AIDL服務(wù),跨進(jìn)程調(diào)用Service,先定義一個(gè)遠(yuǎn)程調(diào)用接口,然后為該接口提供一個(gè)IBinder實(shí)現(xiàn)類(lèi),客戶(hù)端獲取了遠(yuǎn)程的Service的IBinder對(duì)象的代理后,通過(guò)該IBinder對(duì)象去回調(diào)遠(yuǎn)程Service的屬性或方法。

3.應(yīng)用場(chǎng)景

如果某個(gè)程序組件需要在運(yùn)行時(shí)向用戶(hù)呈現(xiàn)界面,或者程序需要與用戶(hù)交互,就需要用Activity,否則就應(yīng)該考慮使用Service。

4.Service與Activity對(duì)比

相似點(diǎn):

1.都是多帶帶的Android組件;

2.都擁有獨(dú)立的生命周期;

3.都是Context的派生類(lèi),所以可以調(diào)用Context類(lèi)定義的如getResources()、getContentResolver()等方法;

4.都擁有自己生命周期回調(diào)方法;

不同點(diǎn):

1.Activity運(yùn)行于前臺(tái)有圖形用戶(hù)界面,負(fù)責(zé)與用戶(hù)交互;Service通常位于后臺(tái)運(yùn)行,不需要與用戶(hù)交互,也沒(méi)有圖形用戶(hù)界面。

5.Service的生命周期

隨著應(yīng)用程序啟動(dòng)Service方式不同,Service的生命周期也略有差異,如下圖:

如果應(yīng)用程序通過(guò)startService()方法來(lái)啟動(dòng)Service,Service的生命周期如上圖左半部分所示。

通過(guò)調(diào)用startService() 方法啟動(dòng)Service:
當(dāng)其他組件調(diào)用startService()方法時(shí),Service被創(chuàng)建,并且無(wú)限期運(yùn)行,其自身必須調(diào)用stopSelf()方法或者其他組件調(diào)用stopService() 方法來(lái)停止Service,當(dāng)Service停止時(shí),系統(tǒng)將其銷(xiāo)毀。

如果應(yīng)用程序通過(guò)bindService()方法來(lái)啟動(dòng)Service,Service的生命周期如上圖右半部分所示。

通過(guò)bindService() 方法啟動(dòng)Service:
當(dāng)其他組件調(diào)用bindService()方法時(shí),Service被創(chuàng)建。接著客戶(hù)端通過(guò)IBinder接口與Service通信??蛻?hù)端通過(guò)unbindService() 方法關(guān)閉連接。多個(gè)客戶(hù)端能綁定到同一個(gè)Service,并且當(dāng)他們都解除綁定時(shí),系統(tǒng)將銷(xiāo)毀Service(Service不需要被停止)

特別說(shuō)明:當(dāng)Activity調(diào)用bindService()綁定一個(gè)已通過(guò)startService()啟動(dòng)的Service時(shí),系統(tǒng)只是把Service內(nèi)部的IBinder對(duì)象傳給Activity,并不會(huì)把該Service生命周期完全綁定到該Activity,因而當(dāng)Activity調(diào)用unBindService()方法取消與該Service的綁定時(shí),也只是切斷該Activity與Service之間的關(guān)聯(lián),并不能停止該Service組件。要停止該Service組件,還需調(diào)用stopService()方法。

Service的生命周期里,常用的有:

4個(gè)手動(dòng)調(diào)用的方法

手動(dòng)調(diào)用方法 作用
startService() 啟動(dòng)服務(wù)
stopService() 關(guān)閉服務(wù)
bindService() 綁定服務(wù)
unbindService() 解綁服務(wù)

5個(gè)自動(dòng)調(diào)用的方法

內(nèi)部自動(dòng)調(diào)用的方法 作用
onCreate() 創(chuàng)建服務(wù)
onStartCommand() 開(kāi)始服務(wù)
onDestroy() 銷(xiāo)毀服務(wù)
onBind() 綁定服務(wù)
onUnbind() 解綁服務(wù)
6.Service的使用

當(dāng)我們開(kāi)始使用Service的時(shí)候當(dāng)然是啟動(dòng)一個(gè)Service了,啟動(dòng)Service的方法和啟動(dòng)Activity很類(lèi)似,都需要借助Intent來(lái)實(shí)現(xiàn),下面我們就通過(guò)一個(gè)具體的例子來(lái)看一下。

public class MyService extends Service {  
  
    public static final String TAG = "MyService";  
  
    @Override  
    public void onCreate() {  
        super.onCreate();  
        Log.d(TAG, "onCreate() executed");  
    }  
  
    @Override  
    public int onStartCommand(Intent intent, int flags, int startId) {  
        Log.d(TAG, "onStartCommand() executed");  
        return super.onStartCommand(intent, flags, startId);  
    }  
    
    @Override  
    public IBinder onBind(Intent intent) {  
        return null;  
    }
      
    @Override  
    public void onDestroy() {  
        super.onDestroy();  
        Log.d(TAG, "onDestroy() executed");  
    }  
  
}  

要?jiǎng)?chuàng)建一個(gè)這樣的Service,你需要讓該類(lèi)繼承Service類(lèi),然后重寫(xiě)以下方法:

onCreate()
1.如果service沒(méi)被創(chuàng)建過(guò),調(diào)用startService()后會(huì)執(zhí)行onCreate()和onStartCommand()方法;
2.如果service已處于運(yùn)行中,調(diào)用startService()不會(huì)執(zhí)行onCreate()方法,只執(zhí)行onStartCommand()方法。
也就是說(shuō),onCreate()只會(huì)在第一次創(chuàng)建service時(shí)候調(diào)用,多次執(zhí)行startService()不會(huì)重復(fù)調(diào)用onCreate(),此方法適合完成一些初始化工作。

onStartCommand()
如果多次執(zhí)行了Context的startService()方法,那么Service的onStartCommand()方法也會(huì)相應(yīng)的多次調(diào)用。onStartCommand()方法很重要,我們?cè)谠摲椒ㄖ懈鶕?jù)傳入的Intent參數(shù)進(jìn)行實(shí)際的操作,比如會(huì)在此處創(chuàng)建一個(gè)線(xiàn)程用于下載數(shù)據(jù)或播放音樂(lè)等。

onBind()
Service中的onBind()方法是抽象方法,Service類(lèi)本身就是抽象類(lèi),所以onBind()方法是必須重寫(xiě)的,即使我們用不到。

onDestroy()
在銷(xiāo)毀的時(shí)候會(huì)執(zhí)行Service的該方法。

這幾個(gè)方法都是回調(diào)方法,且在主線(xiàn)程中執(zhí)行,由Android操作系統(tǒng)在合適的時(shí)機(jī)調(diào)用。

注意:每個(gè)Service必須在manifest中 通過(guò)來(lái)聲明。

 
  ... 

現(xiàn)在我們通過(guò)繼承Service的方式定義了我們自己的MyService類(lèi),并且在manifest中聲明了我們的MyService,接下來(lái)我們應(yīng)該啟動(dòng)我們自己的服務(wù)。

啟動(dòng)Service

第一種方式:我們是通過(guò)一個(gè)Intent對(duì)象,并調(diào)用startService()方法來(lái)啟動(dòng)MyService

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

注意:假如我們是通過(guò)點(diǎn)擊Button執(zhí)行上面的代碼,那么第一次點(diǎn)擊的時(shí)候回執(zhí)行其中的onCreate()onStartCommand()方法,但是當(dāng)我們第二次點(diǎn)擊的時(shí)候就只會(huì)執(zhí)行onStartCommand()方法。

為什么會(huì)這樣呢?
這是由于onCreate()方法只會(huì)在Service第一次被創(chuàng)建的時(shí)候調(diào)用,如果當(dāng)前Service已經(jīng)被創(chuàng)建過(guò)了(第一次點(diǎn)擊創(chuàng)建了MyService),不管怎樣調(diào)用startService()方法,onCreate()方法都不會(huì)再執(zhí)行。

第二種方式:通過(guò)bindService啟動(dòng)Service。

bindService啟動(dòng)服務(wù)特點(diǎn):
1.bindService啟動(dòng)的服務(wù)和調(diào)用者之間是典型的client-server模式。調(diào)用者是client,service則是server端。service只有一個(gè),但綁定到service上面的client可以有一個(gè)或很多個(gè)。這里所提到的client指的是組件,比如某個(gè)Activity。

2.client可以通過(guò)IBinder接口獲取Service實(shí)例,從而實(shí)現(xiàn)在client端直接調(diào)用Service中的方法以實(shí)現(xiàn)靈活交互,這在通過(guò)startService()方法啟動(dòng)中是無(wú)法實(shí)現(xiàn)的。

3.bindService啟動(dòng)服務(wù)的生命周期與其綁定的client息息相關(guān)。當(dāng)client銷(xiāo)毀時(shí),client會(huì)自動(dòng)與Service解除綁定(client會(huì)有ServiceConnectionLeaked異常,但程序不會(huì)崩潰)。當(dāng)然,client也可以明確調(diào)用ContextunbindService()方法與Service解除綁定。當(dāng)沒(méi)有任何clientService綁定時(shí),Service會(huì)自行銷(xiāo)毀。

啟動(dòng)了之后,當(dāng)我們想停止服務(wù)的時(shí)候該怎么做呢?

停止Service

第一種方式:我們也是通過(guò)一個(gè)Intent對(duì)象,并調(diào)用stopService()方法來(lái)停止MyService

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

第二種方式:調(diào)用unbindService(conn)方法來(lái)停止MyService

unbindService(ServiceConnection conn)
Service和Activity通信

在上面我們高高興興的啟動(dòng)了Service了,但是細(xì)心的你可能發(fā)現(xiàn)了,貌似我們僅僅只是啟動(dòng)了而已,ActivityService并沒(méi)有多少"交流",下面我們就讓ActivityService交流一下。

public class MyService extends Service {

    public static final String TAG = "MyService";

    private MyBinder mBinder = new MyBinder();

    @Override
    public void onCreate() {
        super.onCreate();
        Log.d(TAG, "onCreate() executed");
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.d(TAG, "onStartCommand() executed");
        return super.onStartCommand(intent, flags, startId);
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        Log.d(TAG, "onDestroy() executed");
    }

    @Override
    public IBinder onBind(Intent intent) {
        return mBinder;
    }

    class MyBinder extends Binder {

        public void startDownload() {
            Log.d("TAG", "startDownload() executed");
            // 執(zhí)行具體的下載任務(wù)
        }

    }

}

接下來(lái)我們?cè)?b>MainActivity中通過(guò)Button來(lái)綁定Service和解除綁定

public class MainActivity extends Activity implements OnClickListener {
        
    private Button bindService;

    private Button unbindService;

    private MyService.MyBinder myBinder;

    private ServiceConnection connection = new ServiceConnection() {

        @Override
        public void onServiceDisconnected(ComponentName name) {
        }

        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            myBinder = (MyService.MyBinder) service;
            myBinder.startDownload();
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        bindService = (Button) findViewById(R.id.bind_service);
        unbindService = (Button) findViewById(R.id.unbind_service);
        bindService.setOnClickListener(this);
        unbindService.setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
        case R.id.bind_service:
            Intent bindIntent = new Intent(this, MyService.class);
            bindService(bindIntent, connection, BIND_AUTO_CREATE);
            break;
        case R.id.unbind_service:
            unbindService(connection);
            break;
        default:
            break;
        }
    }

}

可以看到,這里我們首先創(chuàng)建了一個(gè)ServiceConnection的匿名類(lèi),在里面重寫(xiě)了onServiceConnected()方法和onServiceDisconnected()方法,這兩個(gè)方法分別會(huì)在ActivityService建立關(guān)聯(lián)和解除關(guān)聯(lián)的時(shí)候調(diào)用。在onServiceConnected()方法中,我們又通過(guò) 向下轉(zhuǎn)型 得到了MyBinder的實(shí)例,有了這個(gè)實(shí)例,ActivityService之間的關(guān)系就變得非常緊密了。現(xiàn)在我們可以在Activity中根據(jù)具體的場(chǎng)景來(lái)調(diào)用MyBinder中的任何public方法,即實(shí)現(xiàn)了Activity指揮Service干什么Service就去干什么的功能。

當(dāng)然,現(xiàn)在ActivityService其實(shí)還沒(méi)關(guān)聯(lián)起來(lái)了呢,這個(gè)功能是在Bind Service按鈕的點(diǎn)擊事件里完成的??梢钥吹剑@里我們?nèi)匀皇菢?gòu)建出了一個(gè)Intent對(duì)象,然后調(diào)用bindService()方法將ActivityService進(jìn)行綁定。bindService()方法接收三個(gè)參數(shù),第一個(gè)參數(shù)就是剛剛構(gòu)建出的Intent對(duì)象,第二個(gè)參數(shù)是前面創(chuàng)建出的ServiceConnection的實(shí)例,第三個(gè)參數(shù)是一個(gè)標(biāo)志位,這里傳入BIND_AUTO_CREATE表示在ActivityService建立關(guān)聯(lián)后自動(dòng)創(chuàng)建Service,這會(huì)使得MyService中的onCreate()方法得到執(zhí)行,但onStartCommand()方法不會(huì)執(zhí)行(只有當(dāng)我們通過(guò) startService()方法請(qǐng)求啟動(dòng)服務(wù)時(shí),調(diào)用此方法)。

解除Activity和Service之間的關(guān)聯(lián),調(diào)用

unbindService(connection);  
關(guān)于銷(xiāo)毀Service說(shuō)明

MyService的內(nèi)部通過(guò)stopSelf()方法來(lái)銷(xiāo)毀的;

一個(gè)Service必須要在既沒(méi)有和任何Activity關(guān)聯(lián)又處理停止?fàn)顟B(tài)的時(shí)候才會(huì)被銷(xiāo)毀;

在Service的onDestroy()方法里去清理掉那些不再使用的資源,防止在Service被銷(xiāo)毀后還會(huì)有一些不再使用的對(duì)象仍占用著內(nèi)存;

7.IntentService

IntentService是Service的子類(lèi),在介紹IntentService之前,先來(lái)了解使用Service時(shí)需要注意的兩個(gè)問(wèn)題

Service 不會(huì)專(zhuān)門(mén)啟動(dòng)一個(gè)線(xiàn)程執(zhí)行耗時(shí)操作,所有的操作都是在主線(xiàn)程中進(jìn)行的,以至于容易出現(xiàn)ANR,所以需要手動(dòng)開(kāi)啟一個(gè)子線(xiàn)程;

Service 不會(huì)自動(dòng)停止,需要調(diào)用stopSelf()方法 或者 是stopService() 方法停止;

使用IntentService不會(huì)出現(xiàn)這兩個(gè)問(wèn)題,因?yàn)?b>IntentService在開(kāi)啟Service時(shí),會(huì)自動(dòng)開(kāi)啟一個(gè)新的線(xiàn)程來(lái)執(zhí)行它,另外,當(dāng)Service運(yùn)行結(jié)束后,會(huì)自動(dòng)停止。

8.如何保證服務(wù)不會(huì)被殺死

第一種方式,返回 START_STICKYSTART_REDELIVER_INTENT

當(dāng)Service因內(nèi)存不足而被系統(tǒng)kill后,一段時(shí)間后內(nèi)存再次空閑時(shí),系統(tǒng)將會(huì)嘗試重新創(chuàng)建此Service,一旦創(chuàng)建成功后將回調(diào)onStartCommand方法,但其中的Intent將是null,除非有掛起的Intent,如pendingintent,這個(gè)狀態(tài)下比較適用于不執(zhí)行命令、但無(wú)限期運(yùn)行并等待作業(yè)的媒體播放器或類(lèi)似的服務(wù)。

    /**
     * 返回 START_STICKY 或 START_REDELIVER_INTENT
     * @param intent
     * @param flags
     * @param startId
     * @return
     */
    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        //return super.onStartCommand(intent, flags, startId);
        return START_STICKY;
    }

第二種方式,提高service的優(yōu)先權(quán)

??
??????
??????????
??????
結(jié)語(yǔ)

Service作為Android的四大組件之一,并且項(xiàng)目開(kāi)發(fā)過(guò)程中一些場(chǎng)景下經(jīng)常被使用到,小伙伴們趕緊上手實(shí)操,把它靈活的運(yùn)用到項(xiàng)目中,結(jié)合上兩期的Activity和BroadcastReceiver實(shí)現(xiàn)有趣的交互吧。
PS:如果還有未看懂的小伙伴,歡迎加入我們的QQ技術(shù)交流群:892271582,里面有各種大神回答小伙伴們遇到的問(wèn)題哦~

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/76161.html

相關(guān)文章

  • Android四大組件Service

    摘要:我們這里就來(lái)解讀一下注釋上所描述的返回值的作用與效果相同,主要是為了兼容低版本,但是并不能保證每次都重啟成功。對(duì)方法返回不同的返回值導(dǎo)致服務(wù)被殺死的時(shí)候自動(dòng)重啟,這個(gè)重啟次數(shù)只能是一次。感謝方法詭異的返回值中類(lèi)中返回值介紹 showImg(https://segmentfault.com/img/remote/1460000018677403?w=2008&h=1028); 前言 Se...

    Tonny 評(píng)論0 收藏0
  • Android四大組件Service全解析

    摘要:四大組件都支持這個(gè)屬性。到目前為止,中總共有三種啟動(dòng)方式。返回值方法有一個(gè)的返回值,這個(gè)返回值標(biāo)識(shí)服務(wù)關(guān)閉后系統(tǒng)的后續(xù)操作。,啟動(dòng)后的服務(wù)被殺死,不能保證系統(tǒng)一定會(huì)重新創(chuàng)建。 1. 簡(jiǎn)介 這篇文章會(huì)從Service的一些小知識(shí)點(diǎn),延伸到Android中幾種常用進(jìn)程間通信方法。 2. 進(jìn)程 ? ? ? ?Service是一種不提供用戶(hù)交互頁(yè)面但是可以在后臺(tái)長(zhǎng)時(shí)間運(yùn)行的組件,可以通過(guò)在A(yíng)n...

    alaege 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<