Service的知識(shí)點(diǎn)

Service的知識(shí)點(diǎn)

1、Service的基本概念

  • Service是android系統(tǒng)中的四大組件之一,它跟Activity的級(jí)別差不多,但不能自己運(yùn)行,只能在后臺(tái)運(yùn)行,并且可以和其他組件進(jìn)行交互,service可以在很多場合的應(yīng)用中使用
  • 比如播放多媒體的時(shí)候,用戶啟動(dòng)了其他activity,這個(gè)時(shí)候程序要在后臺(tái)繼續(xù)播放。
  • 比如檢測到SD卡上文件的變化
  • 在或者在后臺(tái)記錄你的地理位置的改變。
     A Service is an application component representing either an application's desire to perform a longer-running operation while not interacting with the user or to supply functionality for other applications to use. Each service class must have a corresponding <service> declaration in its package's AndroidManifest.xml. Services can be started with Context.startService() and Context.bindService().
  • 一定要在AndroidManifest.xml文件中注冊(cè)

2、如何實(shí)現(xiàn)一個(gè)Service

  • startService()
    • 服務(wù)同時(shí)只會(huì)被創(chuàng)建一次,可以通過外部調(diào)用stopService()或者this.stopSelf() //自己停止
    • 當(dāng)執(zhí)行一個(gè)已經(jīng)啟動(dòng)的服務(wù),會(huì)直接調(diào)用onStartCommand()方法來執(zhí)行業(yè)務(wù)
  • bindService()

3、IntentService

  • IntentService是繼承于Service并處理異步請(qǐng)求的一個(gè)類,在IntentService內(nèi)有一個(gè)工作線程來處理耗時(shí)操作,啟動(dòng)IntentService的方式和啟動(dòng)Service的方式一樣,同時(shí),當(dāng)任務(wù)執(zhí)行完后,IntentService會(huì)自動(dòng)停止,而不需要我們?nèi)ナ謩?dòng)的控制,另外,可以啟動(dòng)一個(gè)IntentService多次,而每一個(gè)耗時(shí)的操作會(huì)以工作隊(duì)列的方式在IntentService的onHandlerIntent回調(diào)的方法中執(zhí)行,并且,每次只會(huì)執(zhí)行一個(gè)工作線程,執(zhí)行完第一個(gè)在去執(zhí)行第二個(gè)
            @Override
                protected void onHandleIntent(Intent intent) {
                    Log.d("MyIntentService", intent.getStringExtra("info"));
            
                    for (int i = 0; i < 50; i++) {
            
                        try {
                            Thread.sleep(500);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        Log.d("MyIntentService", "onHandlerIntent-" + i + "-" + Thread.currentThread().getName());
                    }
                }
                

4、Bind Service

  • 應(yīng)用程序組件,通過調(diào)用bindService()方法能夠綁定服務(wù),然后Android系統(tǒng)會(huì)調(diào)用服務(wù)的onBind()回調(diào)方法,這個(gè)方法會(huì)返回一個(gè)跟服務(wù)端交互的IBinder對(duì)象,這個(gè)綁定必須是異步的。bindService()方法立即返回,并且不給客戶端返回IBinder對(duì)象,要接受IBinder對(duì)象,客戶端必須創(chuàng)建一個(gè)ServiceConnection類的實(shí)例,并且把這個(gè)實(shí)例傳遞給bindService()方法,ServiceConnection對(duì)象包含了一個(gè)系統(tǒng)調(diào)用的傳遞IBinder對(duì)象的回調(diào)方法
  • 注意:只有Activity、Service、和內(nèi)容提供器(Content Provider)能偶綁定服務(wù)--->對(duì)于廣播接收者不能綁定服務(wù)
  • 第一步:創(chuàng)建Service
        package com.example.servicedemo;
        
        import android.app.Service;
        import android.content.Intent;
        import android.os.IBinder;
        
        public class MyService extends Service {
            public MyService() {
            }
        
            @Override
            public IBinder onBind(Intent intent) {
              return new CatImpl();
        
            }
        
            @Override
            public boolean onUnbind(Intent intent) {
                return super.onUnbind(intent);
            }
        
            @Override
            public void onDestroy() {
                super.onDestroy();
            }
        }
  • 第二步:創(chuàng)建AIDL(在包名--右鍵--aidl文件---名字---finish)
        // ICat.aidl
        package com.example.servicedemo;
        
        // Declare any non-default types here with import statements
        
        interface ICat {

        void setName(String name);
    
        String desc();
    
        /**
         * Demonstrates some basic types that you can use as parameters
         * and return values in AIDL.
         */
        void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat,
                double aDouble, String aString);
        }
  • 第三步:創(chuàng)建一個(gè)接口用來實(shí)現(xiàn)aidl
        package com.example.servicedemo;
        
        import android.os.RemoteException;
        import android.provider.MediaStore;
        
        /**
         * Created by 若蘭 on 2016/2/13.
         * 一個(gè)懂得了編程樂趣的小白,希望自己
         * 能夠在這個(gè)道路上走的很遠(yuǎn),也希望自己學(xué)習(xí)到的
         * 知識(shí)可以幫助更多的人,分享就是學(xué)習(xí)的一種樂趣
         * QQ:1069584784
         * csdn:http://blog.csdn.net/wuyinlei
         */
        public class CatImpl extends ICat.Stub {
        
            private String name;
        
            @Override
            public void setName(String name) throws RemoteException {
                this.name = name;
            }
        
            @Override
            public String desc() throws RemoteException {
                return "hello , my name is " + name;
            }
        
            @Override
            public void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat, double aDouble, String aString) throws RemoteException {
        
            }
        }
  • 第四步:綁定和解除服務(wù)
            //解除綁定
            private void unBoundClick() {
                if (mBound) {
                    unbindService(conn);
                }
            }
        
            //綁定一個(gè)服務(wù)
            private void boundClick() {
                //異步的操作
                bindService(new Intent(this, MyService.class), conn, Context.BIND_AUTO_CREATE);
            }
        
        
        
            //綁定服務(wù)的連接回調(diào)接口
            private ServiceConnection conn = new ServiceConnection() {
                @Override
                public void onServiceConnected(ComponentName name, IBinder service) {
                    //綁定成功后回調(diào)的方法
                    mICat = ICat.Stub.asInterface(service);
        
                    mBound = true;
        
                }
        
                @Override
                public void onServiceDisconnected(ComponentName name) {
                    //服務(wù)異常終止的時(shí)候調(diào)用
                    mBound = false;
                }
            };
        /**
         * 綁定服務(wù)
         * 通過綁定服務(wù)來實(shí)現(xiàn)功能的步驟
         * 1、客戶端通過bindService方法來綁定一個(gè)服務(wù)對(duì)象,會(huì)回調(diào)用ServiceConnection接口方法onServiceConnected
         * 2、通過Service這個(gè)組件來暴漏這業(yè)務(wù)接口
         * 3、服務(wù)端通過創(chuàng)建一個(gè)*。aidl來定義個(gè)可以被客戶端調(diào)用的業(yè)務(wù)接口
         *    一個(gè)aidl文件:
         *    (1)不能有修飾符   類似接口的寫法
         *    (2)支持類型  8中基本數(shù)據(jù)類型   String CharSequence List<List>  Map,自定義類型
         * 4、服務(wù)端需要提供一個(gè)業(yè)務(wù)接口的實(shí)現(xiàn)類   通常繼承Stub這個(gè)類
         * 5、通過Service的onBind方法,返回這個(gè)業(yè)務(wù)接口的實(shí)現(xiàn)類(被綁定的業(yè)務(wù)對(duì)象)
         * 6、客戶端如果綁定成功,就可以調(diào)用自己的方法一樣調(diào)用遠(yuǎn)程的業(yè)務(wù)對(duì)象
         */

5、Messenger

  • 實(shí)現(xiàn)IPC通信,底層也是使用了AIDL方式,和AIDL方式不同的是,Messenger方式是利用Handler形式處理,因此,他是線程安全的,這也表示他不支持并發(fā)處理,而AIDL方式是非線程安全的,支持并發(fā)處理,因此我們使用AIDL方式時(shí)候需要保證代碼的線程安全
  • 大部分情況下,我們應(yīng)用中不需要處理并發(fā)處理,因此我們通常只需要使用Messenger方式
  • 思想:
    • 在進(jìn)程A中創(chuàng)建一個(gè)Message,將這個(gè)Message對(duì)象通過Messenger.send(message)方法傳遞到線程B(當(dāng)然,Message對(duì)象本身是無法被傳遞到進(jìn)程B的,send(message))方法會(huì)使用一個(gè)Parcel對(duì)象對(duì)Message對(duì)象編輯,在將Parcel對(duì)象傳遞到進(jìn)程B中,然后解編集,得到一個(gè)和進(jìn)程A中Message對(duì)象內(nèi)容一樣的對(duì)象),在把Message對(duì)象加入到進(jìn)程B的消息隊(duì)列里面,Handler回去處理它。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容