Android四大組件之Service

來源:互聯網
上載者:User

Android四大組件之Service
Android四大組件之Service服務的兩種開啟方式:startService();開啟服務.
開啟服務後 服務就會長期的後台運行,即使調用者退出了.服務仍然在後台繼續運行.服務和調用者沒有什麼關係, 調用者是不可以訪問服務裡面的方法. bindService();綁定服務.
服務開啟後,生命週期與調用者相關聯.調用者掛了,服務也會跟著掛掉.不求同時生,但求同時死.調用者和服務綁定在一起,調用者可以間接的調用到服務裡面的方法.AIDL

本地服務:服務代碼在本應用中
遠程服務:服務在另外一個應用裡面(另外一個進程裡面)
aidl: android interface defination language
IPC implementation : inter process communication

服務混合調用的生命週期

開啟服務後再去綁定服務然後再去停止服務,這時服務是無法停止了.必須先解除綁定服務然後再停止服務,在實際開發中會經常採用這種模式,開啟服務(保證服務長期後台運行) –> 綁定服務(調用服務的方法) –> 解除綁定服務(服務繼續在後台運行) –> 停止服務(服務停止),服務只會被開啟一次,如果已經開啟後再去執行開啟操作是沒有效果的。

綁定服務調用方法的原理定義一個介面,裡面定義一個方法
    public interface IService {        public void callMethodInService();//通過該類中提供一個方法,讓自定     義的類實現這個介面    }
在服務中自訂一個IBinder的實作類別,讓這個類繼承Binder(Binder是IBinder的預設適配器),由於這個自訂類是私人的,為了其他類中能拿到該類,我們要定義一個介面,提供一個方法,讓IBinder類去實現該介面,並在相應方法中調用自己要供別人調用的方法。
    public class TestService extends Service {        @Override        public IBinder onBind(Intent intent) {            System.out.println(onbind);            return new MyBinder();        }        private class MyBinder extends Binder implements IService{            public void callMethodInService(){                //實現該方法,去調用服務中的方法                methodInService();            }        }        //服務中的方法        public void methodInService(){            Toast.makeText(this, 我是服務裡面的春哥,巴拉布拉!, 0).show();        }    }
服務的調用類中將 onServiceConnected方法中的第二個參數強轉成介面
    public class DemoActivity extends Activity {        private Intent intent;        private Myconn conn;        private IService iService;        @Override        public void onCreate(Bundle savedInstanceState) {            super.onCreate(savedInstanceState);            intent = new Intent(this,TestService.class);            setContentView(R.layout.main);        }        public void start(View view) {            startService(intent);        }        public void stop(View view) {            stopService(intent);        }        public void bind(View view) {            conn = new Myconn();            //1.綁定服務 傳遞一個conn對象.這個conn就是一個回調介面            bindService(intent, conn, Context.BIND_AUTO_CREATE);        }www.bkjia.com        public void unbind(View view) {            unbindService(conn);        }        //調用服務中的方法        public void call(View view){            iService.callMethodInService();        }        private class Myconn implements ServiceConnection{            //當服務被成功綁定的時候調用的方法.            @Override            public void onServiceConnected(ComponentName name, IBinder service) {//第二個參數就是服務中的onBind方法的傳回值                iService = (IService) service;            }            @Override            public void onServiceDisconnected(ComponentName name) {            }        }    } 
遠程服務aidl

上面介紹了綁定服務調用服務中方法的原理,對於遠程服務的綁定也是這樣,
但是這個遠程服務是在另外一個程式中的,在另外一個程式中定 義的這個介面,
在另外一個程式中是拿不到的,就算是我們在自己的應用 中也定義一個一模一樣
的介面,但是由於兩個程式的報名不同,這兩個介面也是不一樣的,為瞭解決這個
問題,Google的工程師給提供了aidl,我們將定義的這個介面的.java改成 .aidl
然後將這個介面中的許可權修飾符去掉,在另一個程式中拷貝這個aidl文
件,然後放到同一個包名中,由於Android中通過包名來區分應用程式,這兩個
aidl的包名一樣,系統會認為兩個程式中的介面是同一個,這樣就能夠在另一
個程式中將參數強轉成這個介面,在使用aidl檔案拷貝到自己的工程之後會自動
產生一個介面類,這個介面類中有 一個內部類Stub該類繼承了Binder並實現了
這個介面,所以我們在自訂 IBinder的實作類別時只需讓自訂的類繼承Stub類
即可.

遠程服務中定義一個介面,改成 aidl
    package com.seal.test.service;    interface IService {         void callMethodInService();    }
遠程服務中定義一個 Ibinder的實作類別,讓這個實作類別繼承上面介面的 Stub類
並在 onBind方法中返回這個自訂類對象
    public class RemoteService extends Service {        @Override        public IBinder onBind(Intent intent) {            System.out.println(遠程服務被綁定);            return new MyBinder();        }        private class MyBinder extends IService.Stub{            @Override            public void callMethodInService() {                methodInService();            }        }        public void methodInService(){            System.out.println(我是遠程服務裡面的方法);        }    }
在其他程式中想要綁定這個服務並且調用這個服務中的方法的時候首先要拷貝
這個 aidl檔案到自己的工程,然後再 ServiceConnection的實作類別中將這個參數使
asInterface方法轉成介面,通過這樣來得到介面,從而調用介面中的方法
    public class CallRemoteActivity extends Activity {        private Intent service;        private IService iService;        @Override        public void onCreate(Bundle savedInstanceState) {            super.onCreate(savedInstanceState);            setContentView(R.layout.main);            service = new Intent();            service.setAction(com.itheima.xxxx);        }        public void bind(View veiw){            bindService(service, new MyConn(), BIND_AUTO_CREATE);        }        public void call(View view){            try {                iService.callMethodInService();            } catch (RemoteException e) {                e.printStackTrace();            }        }        private class MyConn implements ServiceConnection{            @Override            public void onServiceConnected(ComponentName name, IBinder service) {                iService = IService.Stub.asInterface(service);            }            @Override            public void onServiceDisconnected(ComponentName name) {                // TODO Auto-generated method stub            }        }    }

最後說一下IntentService:

IntentServiceService的子類,用來處理非同步請求。用戶端可以通過startService(Intent)方法將請求的Intent傳遞請求給IntentService
IntentService會將該Intent加入到隊列中,然後對每一個Intent開啟一個worker thread來進行處理,執行完所有的工作之後自動停止Service
每一個請求都會在一個單獨的worker thread中處理,不會阻塞應用程式的主線程。IntentService 實際上是LooperHandlerService 的集合體,他不僅有服務的功能,還有處理和迴圈訊息的功能.

Service:
A Service is not a separate process. The Service object itself does not imply it is running in its own process; unless otherwise specified, it runs in the same process as the application it is part of. A Service is not a thread. It is not a means itself to do work off of the main thread (to avoid Application Not Responding errors).
所以在 Service中進行耗時的操作時必須要新開一個線程。
至於為什麼要使用 Service而不是 Thread,這個主要的區別就是生命週期不同, Service是Android系統的一個組件,Android系統會盡量保持 Service的長期後台運行,
即使記憶體不足殺死了該服務(很少會出現記憶體不足殺死服務的情況)也會在記憶體可用的時候去複活該服務,而 Thread隨後都會被殺死 IntentService
IntentService is a base class for Services that handle asynchronous requests (expressed as Intents) on demand. Clients send requests throughstartService(Intent) calls;
the service is started as needed, handles each Intent in turn using a worker thread, and stops itself when it runs out of work. This “work queue processor” pattern is commonly used to offload tasks from an application’s main thread. The IntentService class exists to simplify this pattern and take care of the mechanics.
To use it, extend IntentService and implement onHandleIntent(Intent). IntentService will receive the Intents, launch a worker thread, and stop the service as appropriate. All requests are handled on a single worker thread – they may take as long as necessary (and will not block the application’s main loop), but only one request will be processed at a time. 

聯繫我們

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