97干视频,99国产精品懂色,亚洲精品99久久久久中文字幕,伊人五月丁香综合AⅤ,国产精品成人免费999

  您的位置:華清遠(yuǎn)見教育科技集團(tuán) >> 新聞動(dòng)態(tài) >> Android資料 >> 詳解Android Service組件  
 
詳解Android Service組件
分享到:

上文我們介紹的是Android應(yīng)用組件Activity,Activity是與用戶直接交互UI組件,今天給大家介紹的服務(wù)(Services)組件則通常運(yùn)行在后臺(tái),對(duì)用戶而言不具有可視性,守護(hù)進(jìn)程和硬件服務(wù)、原生服務(wù)等多是服務(wù)組件。

與其他組件一樣,服務(wù)組件通常運(yùn)行在應(yīng)用的主線程中,如果服務(wù)組件對(duì)時(shí)間片等資源消耗較大,通常會(huì)將服務(wù)組件放置在一個(gè)單獨(dú)的線程中運(yùn)行,以防阻塞UI線程即主線程,影響用戶體驗(yàn)。

通過Context.startService()方法可以啟動(dòng)服務(wù),通過Context.bindService()方法可以綁定服務(wù)。通過Context.stopService()方法可以停止服務(wù)。另外服務(wù)本身也可以通過Context.stopSelf()方法自行終止。在實(shí)際實(shí)現(xiàn)中,為了綁定服務(wù),必須指定一個(gè)服務(wù)連接(ServiceConnection),具體如下:

public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        ……
        getApplicationContext().bindService(new Intent(this,PowerManagerService.class), mConnection, BIND_AUTO_CREATE);
        …….
    }

其中mConnection即是ServiceConnection的一個(gè)實(shí)例,BIND_AUTO_CREATE指明了連接的類型,表明如果服務(wù)沒有創(chuàng)建,自動(dòng)創(chuàng)建服務(wù)。默認(rèn)情況下,可以通過調(diào)用組件的上下文綁定或者解綁服務(wù),但是在同一個(gè)應(yīng)用中如果需多次綁定服務(wù)時(shí),需要整體通過應(yīng)用上下文(getApplicationContext())的方式實(shí)現(xiàn)。

在調(diào)用組件被銷毀時(shí),服務(wù)必須解綁,否則會(huì)造成引用計(jì)數(shù)上的錯(cuò)誤,造成服務(wù)泄漏,解綁服務(wù)的實(shí)現(xiàn)如下:

protected void onDestroy()
    {
        getApplicationContext().unbindService(mConnection);
        super.onDestroy();
    }

服務(wù)連接的實(shí)現(xiàn)如下:

private ServiceConnection mConnection = new ServiceConnection()
    {
        public void onServiceConnected(ComponentName name, IBinder service)
        {
            // TODO Auto-generated method stub
            Log.d(TAG, "===onServiceConnected==");
            mPowerManager = ((PowerManagerService.LocalBinder)service).getService();
            initLayout();
        }
        public void onServiceDisconnected(ComponentName name)
        {
            // TODO Auto-generated method stub
            mPowerManager = null;
        }
    };

需要說明的是,由于服務(wù)的連接是異構(gòu)的,必須保證服務(wù)的實(shí)例在服務(wù)綁定成功后使用。如果在bindService()執(zhí)行后立即使用,會(huì)引發(fā)NullPointerException異常。

通過在AndroidManifest.xml文件中聲明“service”元素,應(yīng)用程序可以全權(quán)接入相應(yīng)的服務(wù)。當(dāng)該服務(wù)允許被外部應(yīng)用調(diào)用時(shí),需要將服務(wù)的“android:exported”屬性設(shè)為“true”。其默認(rèn)值為“false”。如果希望在設(shè)置應(yīng)用中查看服務(wù)時(shí),多看到的服務(wù)圖標(biāo)與定義該服務(wù)的應(yīng)用圖標(biāo)有所區(qū)別,則應(yīng)設(shè)置服務(wù)的“android:icon”屬性。否則看到的服務(wù)圖標(biāo)即定義該服務(wù)的應(yīng)用圖標(biāo)。服務(wù)的聲明如下:

< service android:name=".MiscService"
        android:label="Playground Service"
        android:exported="true"
        android:process=":rpcperfservice" /> //運(yùn)行在不同的進(jìn)程中

為了接入對(duì)于被權(quán)限保護(hù)的服務(wù),通過在AndroidManifest.xml文件中聲明相應(yīng)服務(wù)的權(quán)限,才可以啟動(dòng)、終止、綁定相應(yīng)的服務(wù)。如為了改變網(wǎng)絡(luò)狀態(tài),需要聲明權(quán)限:

< uses-permission android:name="android.permission.CHANGE_NETWORK_STATE"/>

系統(tǒng)級(jí)的權(quán)限在frameworks/base/core/res/AndroidManifest.xml中定義。

后,在服務(wù)的創(chuàng)建、啟動(dòng)、銷毀階段,服務(wù)駐留的進(jìn)程會(huì)處于前臺(tái)進(jìn)程狀態(tài),以免服務(wù)出現(xiàn)不可預(yù)料的異常。需要說明的是,當(dāng)系統(tǒng)內(nèi)存嚴(yán)重緊張時(shí),系統(tǒng)可能會(huì)重啟甚至銷毀服務(wù)。

服務(wù)根據(jù)駐留的對(duì)象不同可以分為本地服務(wù)(Local Services)和遠(yuǎn)程服務(wù)(Romate Services)。就筆者而言,一般將遠(yuǎn)程服務(wù)分為應(yīng)用級(jí)遠(yuǎn)程服務(wù)和系統(tǒng)級(jí)遠(yuǎn)程服務(wù)兩種。系統(tǒng)級(jí)的服務(wù)實(shí)現(xiàn)頗為復(fù)雜。除了定義服務(wù)本身外,還需要定義被上層應(yīng)用調(diào)用的接口。一般通過AIDL調(diào)用。而應(yīng)用級(jí)遠(yuǎn)程服務(wù)除了AIDL外,Android還提供了較為簡(jiǎn)單的Message方式的調(diào)用。但如果實(shí)現(xiàn)的服務(wù)希望被其他應(yīng)用調(diào)用,則必須通過AIDL進(jìn)行。

在具體的實(shí)現(xiàn)中,為了調(diào)用駐留在其他應(yīng)用下的遠(yuǎn)程服務(wù),需要將該遠(yuǎn)程服務(wù)的I*.java接口拷貝到調(diào)用的工程中,如對(duì)于com.miaozl.test.TestService服務(wù),需要將com. miaozl.test.ITestService拷貝到調(diào)用遠(yuǎn)程服務(wù)的其他工程的“src”目錄下,綁定的方法為:

Intent serviceIntent = new Intent();
    serviceIntent.setComponent(new ComponentName("com.lingpan.test","com.lingpan.test.TestService"));
    bindService(serviceIntent, mConnection, Context.BIND_AUTO_CREATE);
    mConnection的實(shí)現(xiàn)如下:
    private ServiceConnection mConnection = new ServiceConnection()
    {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service)
        {
            // TODO Auto-generated method stub
            ITestService test = ITestService.Stub.asInterface(service);
            try {
                test.setTest(); //調(diào)用遠(yuǎn)程服務(wù)的方法
            } catch (RemoteException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        @Override
        public void onServiceDisconnected(ComponentName name)
        {
            // TODO Auto-generated method stub
        }
    };

至于本地服務(wù)和應(yīng)用級(jí)的遠(yuǎn)程服務(wù)的具體實(shí)現(xiàn),android的幫助文檔和示例代碼中已經(jīng)有明確的說明,在本文中就不再詳述。

至于系統(tǒng)級(jí)的遠(yuǎn)程服務(wù),對(duì)于應(yīng)用開發(fā)者而言,大可不必理會(huì),只有在擔(dān)任整個(gè)系統(tǒng)的架構(gòu)任務(wù)時(shí)才會(huì)涉及,服務(wù)的實(shí)現(xiàn)可以參考UiModeManagerService.java來進(jìn)行,服務(wù)對(duì)應(yīng)用層的接口的實(shí)現(xiàn)可以參考UiModeManager.java來進(jìn)行,為了通過getSystemService()方法調(diào)用自定義的方法,需要在ContextImpl.java中構(gòu)建系統(tǒng)服務(wù)對(duì)應(yīng)用層的接口的單子模式實(shí)例。

 更多相關(guān)文章

·Android應(yīng)用組件Activity
·Android RPC管道文件系統(tǒng)
·Android RPC遠(yuǎn)程調(diào)用
·SMSM狀態(tài)通信處理過程
·SMD 數(shù)據(jù)通信的實(shí)現(xiàn)