概述
進程 :進程是一個應(yīng)用程序運行的載體句狼。在Android中呐粘,進程的底層是Linux管理的岗宣。Android中應(yīng)用啟動的一般過程為:Linux系統(tǒng)創(chuàng)建一個進程(pid)蚂会,進程里運行dvm,dvm里運行這個應(yīng)用
應(yīng)用程序 :
一個應(yīng)用程序可以對應(yīng)多個進程耗式,在Android中胁住,一個任務(wù)棧里可以有多個Activity,而Android應(yīng)用程序推出后刊咳,Android會盡量將進程保留彪见。其目的時為了下一次啟動應(yīng)用時提高啟動速度。但這種做法容易引發(fā)內(nèi)存不足的缺陷娱挨。而當內(nèi)存不足時余指,Android會自動回收部分進程,其回收的順序為:
- 空進程 :沒有任何組件運行跷坝,所有Activity和任務(wù)棧都已被關(guān)閉的進程
- 后臺進程 :應(yīng)用程序沒有服務(wù)處于運行狀態(tài)酵镜,并且應(yīng)用程序處于最小化的狀態(tài)。當某個程序按home鍵返回柴钻,若該程序未啟動任何服務(wù)淮韭,那么,此時進程屬于后臺進程
- 服務(wù)進程 :服務(wù)進程是運行于后臺的沒有界面顯示的進程顿颅。Android回收內(nèi)存空間時會優(yōu)先回收后臺進程缸濒,若內(nèi)存仍然不足時才回收服務(wù)進程
- 可見進程 :應(yīng)用UI可見,但失去焦點粱腻,不能操作庇配。一般情況下這類進程很少被回收
- 前臺進程 :當前正在操作的進程,具有焦點绍些,可以響應(yīng)事件捞慌。一般情況下這類進程是不會被回收的。
服務(wù)概念
服務(wù)的概念最先是由微軟引入柬批。由上述回收機制可知啸澡,服務(wù)就是沒有界面但長期運行于后臺的進程。服務(wù)被回收的情況較少發(fā)生氮帐,因此嗅虏,當某一應(yīng)用程序不需要前臺UI,但需要長期運行時可以使用服務(wù)上沐。如音樂播放器皮服、后臺下載等。
創(chuàng)建服務(wù)
- 寫一個類集成Service
public class ServerDemo extends Service{
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public void onCreate() {
//TODO 此方法會在服務(wù)創(chuàng)建時調(diào)用。當服務(wù)創(chuàng)建完成后龄广,將不會再調(diào)用此方法硫眯。也就是說此方法只會被調(diào)用一次
//具體代碼寫在這里
super.onCreate();
}
@Override
public void onDestroy() {
// TODO 此方法會在服務(wù)銷毀時被調(diào)用
super.onDestroy();
//service繼承了ContextWrapper類,因此择同,具有許多與Activity相同的方法两入,因此參數(shù)Context值可以是this
//Intent intent = new Intent(this,ServerDemo.class);
//startService(intent);
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
// TODO 當服務(wù)被調(diào)用時執(zhí)行此方法,此方法與onStart()方法相同
return super.onStartCommand(intent, flags, startId);
}
}
- 然后再清單文件中application標簽內(nèi)配置Service
<service android:name="com.asksky.ser.ServerDemo"></service>
- 開啟服務(wù):服務(wù)不能自己運行,需要發(fā)送Intent開啟
Intent intent = new Intent(packageContext, cls);
startService(intent);
服務(wù)的生命周期
服務(wù)只會被創(chuàng)建一次,如果重復(fù)被創(chuàng)建不會重復(fù)執(zhí)行onCreate方法
服務(wù)只會被停止一次,如果服務(wù)已經(jīng)停止不會重復(fù)執(zhí)行onDestory方法
如果服務(wù)已經(jīng)開啟,多次調(diào)用startService方法,服務(wù)只會執(zhí)行onstartCommand方法,onCreate方法不會執(zhí)行
綁定服務(wù)
在服務(wù)中,onCreate方法會在服務(wù)被創(chuàng)建時執(zhí)行,而onDestory方法會在服務(wù)銷毀時執(zhí)行.諸如此類方法都可以在一定的條件下就會被自動執(zhí)行,改變某一條件就可以達到執(zhí)行這些方法的目的.但是,服務(wù)中有可能存在自定義的方法,這些方法需要被調(diào)用必須手動new一個對象,但是,在Android中,四大組件一般是不會被手動創(chuàng)建的,因為,這些組件由Android框架創(chuàng)建,在內(nèi)可以直接使用Context等對象,若手動創(chuàng)建,這些對象就不能使用了.
為了解決四大組件不能創(chuàng)建對象敲才,但須調(diào)用其中方法這一問題裹纳,Android提供了綁定服務(wù)的機制」榻铮可以將Activity和服務(wù)綁定在一起,綁定過后就可以通過中間類來調(diào)用服務(wù)中的方法了痊夭。
綁定服務(wù)
bindService(intent, conn , BIND_AUTO_CREATE)
將當前Activity和Service綁定起來,用一個conn對象保持連接,在綁定時如果服務(wù)不存在則服務(wù)會被創(chuàng)建出來,如果服務(wù)已經(jīng)存在則直接綁定.重復(fù)綁定無效果.
綁定服務(wù)將觸發(fā)服務(wù)中的onBind方法
conn對象可以保持Activity和Service之間的綁定,當綁定狀態(tài)發(fā)生變化時其中的方法自動被調(diào)用
移除綁定服務(wù)
unbindService(conn)
將當前Activity和Serivce的綁定解除,如果服務(wù)不再被需要則銷毀(如果服務(wù)最初是被綁定時由綁定的動作而創(chuàng)建的則隨著移除綁定銷毀,如果不是則不銷毀).不可以在未綁定的情況下移除綁定.
移除綁定服務(wù)將觸發(fā)服務(wù)中的onUnBind方法
另外,Activity退出時,綁定自動解除了
具體實現(xiàn)
- 服務(wù)類
public class MyService extends Service {
/**
* 在Android中,四大組件一般不能手動創(chuàng)建
* 當需要調(diào)用以下自定義方法時,需要使用服務(wù)綁定機制
* */
public void show(){
System.out.println("這是一個show()方法");
}
/**
* 寫一個內(nèi)部類作為service服務(wù)類與Activity類之間調(diào)用方法的中間類
* 此類可以看做是服務(wù)類用于對外提供方法的基站
* 可以將所有有可能被調(diào)用到的方法寫進中間類,Activity類通過此類來調(diào)用具體方法
* */
class GetService extends Binder{
public void getShow(){
show();
}
public void otherMethod(){
Toast.makeText(MyService.this, "所有其它需要被調(diào)用的方法都可以寫在此類中",0).show();
}
}
/**
* 綁定服務(wù)需要使用onBind方法,此方法用于將中間類返回
* */
@Override
public IBinder onBind(Intent intent) {
return new GetService();
}
@Override
public void onCreate() {
// TODO 創(chuàng)建服務(wù)時執(zhí)行此方法
super.onCreate();
}
}
- Activity類
public class MainActivity extends ActionBarActivity {
GetService ms = null;
/**
* 此時,在Activity類中調(diào)用服務(wù)類中所需要的方法,就可以通過綁定服務(wù)的機制獲取指定方法了
* 服務(wù)方法中對外提供的獲取方法的中間類也可以被看做一個接口,使用此接口需要先獲取鏈接
* 創(chuàng)建一個類繼承ServiceConnection
* */
class MyServConn implements ServiceConnection{
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
/** 當Service中有方法被調(diào)用時,需要用到鏈接,此方法會執(zhí)行
* 注意必須有binder返回這個方法才有效
* IBinder service 就是服務(wù)類中public IBinder onBind(Intent intent)方法返回的中間類
* ComponentName name 貌似是被代理類的包名/全路徑名
*/
ms = (GetService) service;
System.out.println(name.toString());
}
@Override
public void onServiceDisconnected(ComponentName name) {
}
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Intent intent = new Intent(this, MyService.class);
bindService(intent, new MyServConn(), BIND_AUTO_CREATE);
//ms.getShow();此處不能在onCreate方法中調(diào)用,因為此時的中間類對象為空.
}
public void show(View v){
ms.getShow();
ms.otherMethod();
}
}
代碼進階
上述綁定服務(wù)機制存在一個小bug:中間類所有的方法都可以被調(diào)用者調(diào)用
解決方案:
- 寫一個接口
public interface IService {
public void show();
}
- 將中間類私有化,并繼承此接口
private class GetService extends Binder implements IService{
public void getShow(){
show();
}
public void otherMethod(){
Toast.makeText(MyService.this, "所有其它需要被調(diào)用的方法都可以卸載此類中",0).show();
}
}
- 此時,Activity類若直接調(diào)用中間類就會報錯,此時必須調(diào)用接口,然后通過接口調(diào)用中間類中的方法,這樣,只有接口中聲明過的方法才可以被調(diào)用
IService ms = (IService) service;
ms.otherMethod();//此時若是調(diào)用此方法就會報錯
注意:在調(diào)用服務(wù)時,若使用startService()可以啟動服務(wù),且Activity退出后,service仍然可以后臺運行
但在使用綁定服務(wù)機制時,不能使用startService()方法,需要用bindService()方法來啟動服務(wù).此時,當Activity退出后,Service也會跟著退出!
解決方案
先創(chuàng)建服務(wù):
Intent intent = new Intent(this, MyService.class);
創(chuàng)建完成后直接啟動,防止上述問題發(fā)生
startService(intent);
當需要用到綁定服務(wù)獲取方法時,再使用bindService
bindService(intent, new MyServConn(), BIND_AUTO_CREATE);
這樣,問題可以解決
相關(guān)鏈接:
遠程服務(wù)(AIDL)
如以上內(nèi)容有任何錯誤或補充,歡迎加QQ:1195211669 脏里,驗證信息:簡書