概述
進(jìn)程 :進(jìn)程是一個(gè)應(yīng)用程序運(yùn)行的載體。在Android中,進(jìn)程的底層是Linux管理的。Android中應(yīng)用啟動(dòng)的一般過(guò)程為:Linux系統(tǒng)創(chuàng)建一個(gè)進(jìn)程(pid),進(jìn)程里運(yùn)行dvm,dvm里運(yùn)行這個(gè)應(yīng)用
應(yīng)用程序 :
一個(gè)應(yīng)用程序可以對(duì)應(yīng)多個(gè)進(jìn)程,在Android中,一個(gè)任務(wù)棧里可以有多個(gè)Activity,而Android應(yīng)用程序推出后,Android會(huì)盡量將進(jìn)程保留。其目的時(shí)為了下一次啟動(dòng)應(yīng)用時(shí)提高啟動(dòng)速度。但這種做法容易引發(fā)內(nèi)存不足的缺陷。而當(dāng)內(nèi)存不足時(shí),Android會(huì)自動(dòng)回收部分進(jìn)程,其回收的順序?yàn)椋?/p>
- 空進(jìn)程 :沒(méi)有任何組件運(yùn)行,所有Activity和任務(wù)棧都已被關(guān)閉的進(jìn)程
- 后臺(tái)進(jìn)程 :應(yīng)用程序沒(méi)有服務(wù)處于運(yùn)行狀態(tài),并且應(yīng)用程序處于最小化的狀態(tài)。當(dāng)某個(gè)程序按home鍵返回,若該程序未啟動(dòng)任何服務(wù),那么,此時(shí)進(jìn)程屬于后臺(tái)進(jìn)程
- 服務(wù)進(jìn)程 :服務(wù)進(jìn)程是運(yùn)行于后臺(tái)的沒(méi)有界面顯示的進(jìn)程。Android回收內(nèi)存空間時(shí)會(huì)優(yōu)先回收后臺(tái)進(jìn)程,若內(nèi)存仍然不足時(shí)才回收服務(wù)進(jìn)程
- 可見(jiàn)進(jìn)程 :應(yīng)用UI可見(jiàn),但失去焦點(diǎn),不能操作。一般情況下這類進(jìn)程很少被回收
- 前臺(tái)進(jìn)程 :當(dāng)前正在操作的進(jìn)程,具有焦點(diǎn),可以響應(yīng)事件。一般情況下這類進(jìn)程是不會(huì)被回收的。
服務(wù)概念
服務(wù)的概念最先是由微軟引入。由上述回收機(jī)制可知,服務(wù)就是沒(méi)有界面但長(zhǎng)期運(yùn)行于后臺(tái)的進(jìn)程。服務(wù)被回收的情況較少發(fā)生,因此,當(dāng)某一應(yīng)用程序不需要前臺(tái)UI,但需要長(zhǎng)期運(yùn)行時(shí)可以使用服務(wù)。如音樂(lè)播放器、后臺(tái)下載等。
創(chuàng)建服務(wù)
- 寫(xiě)一個(gè)類集成Service
public class ServerDemo extends Service{
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public void onCreate() {
//TODO 此方法會(huì)在服務(wù)創(chuàng)建時(shí)調(diào)用。當(dāng)服務(wù)創(chuàng)建完成后,將不會(huì)再調(diào)用此方法。也就是說(shuō)此方法只會(huì)被調(diào)用一次
//具體代碼寫(xiě)在這里
super.onCreate();
}
@Override
public void onDestroy() {
// TODO 此方法會(huì)在服務(wù)銷毀時(shí)被調(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 當(dāng)服務(wù)被調(diào)用時(shí)執(zhí)行此方法,此方法與onStart()方法相同
return super.onStartCommand(intent, flags, startId);
}
}
- 然后再清單文件中application標(biāo)簽內(nèi)配置Service
<service android:name="com.asksky.ser.ServerDemo"></service>
- 開(kāi)啟服務(wù):服務(wù)不能自己運(yùn)行,需要發(fā)送Intent開(kāi)啟
Intent intent = new Intent(packageContext, cls);
startService(intent);
服務(wù)的生命周期
服務(wù)只會(huì)被創(chuàng)建一次,如果重復(fù)被創(chuàng)建不會(huì)重復(fù)執(zhí)行onCreate方法
服務(wù)只會(huì)被停止一次,如果服務(wù)已經(jīng)停止不會(huì)重復(fù)執(zhí)行onDestory方法
如果服務(wù)已經(jīng)開(kāi)啟,多次調(diào)用startService方法,服務(wù)只會(huì)執(zhí)行onstartCommand方法,onCreate方法不會(huì)執(zhí)行
綁定服務(wù)
在服務(wù)中,onCreate方法會(huì)在服務(wù)被創(chuàng)建時(shí)執(zhí)行,而onDestory方法會(huì)在服務(wù)銷毀時(shí)執(zhí)行.諸如此類方法都可以在一定的條件下就會(huì)被自動(dòng)執(zhí)行,改變某一條件就可以達(dá)到執(zhí)行這些方法的目的.但是,服務(wù)中有可能存在自定義的方法,這些方法需要被調(diào)用必須手動(dòng)new一個(gè)對(duì)象,但是,在Android中,四大組件一般是不會(huì)被手動(dòng)創(chuàng)建的,因?yàn)?這些組件由Android框架創(chuàng)建,在內(nèi)可以直接使用Context等對(duì)象,若手動(dòng)創(chuàng)建,這些對(duì)象就不能使用了.
為了解決四大組件不能創(chuàng)建對(duì)象,但須調(diào)用其中方法這一問(wèn)題,Android提供了綁定服務(wù)的機(jī)制。可以將Activity和服務(wù)綁定在一起,綁定過(guò)后就可以通過(guò)中間類來(lái)調(diào)用服務(wù)中的方法了。
綁定服務(wù)
bindService(intent, conn , BIND_AUTO_CREATE)
將當(dāng)前Activity和Service綁定起來(lái),用一個(gè)conn對(duì)象保持連接,在綁定時(shí)如果服務(wù)不存在則服務(wù)會(huì)被創(chuàng)建出來(lái),如果服務(wù)已經(jīng)存在則直接綁定.重復(fù)綁定無(wú)效果.
綁定服務(wù)將觸發(fā)服務(wù)中的onBind方法
conn對(duì)象可以保持Activity和Service之間的綁定,當(dāng)綁定狀態(tài)發(fā)生變化時(shí)其中的方法自動(dòng)被調(diào)用
移除綁定服務(wù)
unbindService(conn)
將當(dāng)前Activity和Serivce的綁定解除,如果服務(wù)不再被需要?jiǎng)t銷毀(如果服務(wù)最初是被綁定時(shí)由綁定的動(dòng)作而創(chuàng)建的則隨著移除綁定銷毀,如果不是則不銷毀).不可以在未綁定的情況下移除綁定.
移除綁定服務(wù)將觸發(fā)服務(wù)中的onUnBind方法
另外,Activity退出時(shí),綁定自動(dòng)解除了
具體實(shí)現(xiàn)
- 服務(wù)類
public class MyService extends Service {
/**
* 在Android中,四大組件一般不能手動(dòng)創(chuàng)建
* 當(dāng)需要調(diào)用以下自定義方法時(shí),需要使用服務(wù)綁定機(jī)制
* */
public void show(){
System.out.println("這是一個(gè)show()方法");
}
/**
* 寫(xiě)一個(gè)內(nèi)部類作為service服務(wù)類與Activity類之間調(diào)用方法的中間類
* 此類可以看做是服務(wù)類用于對(duì)外提供方法的基站
* 可以將所有有可能被調(diào)用到的方法寫(xiě)進(jìn)中間類,Activity類通過(guò)此類來(lái)調(diào)用具體方法
* */
class GetService extends Binder{
public void getShow(){
show();
}
public void otherMethod(){
Toast.makeText(MyService.this, "所有其它需要被調(diào)用的方法都可以寫(xiě)在此類中",0).show();
}
}
/**
* 綁定服務(wù)需要使用onBind方法,此方法用于將中間類返回
* */
@Override
public IBinder onBind(Intent intent) {
return new GetService();
}
@Override
public void onCreate() {
// TODO 創(chuàng)建服務(wù)時(shí)執(zhí)行此方法
super.onCreate();
}
}
- Activity類
public class MainActivity extends ActionBarActivity {
GetService ms = null;
/**
* 此時(shí),在Activity類中調(diào)用服務(wù)類中所需要的方法,就可以通過(guò)綁定服務(wù)的機(jī)制獲取指定方法了
* 服務(wù)方法中對(duì)外提供的獲取方法的中間類也可以被看做一個(gè)接口,使用此接口需要先獲取鏈接
* 創(chuàng)建一個(gè)類繼承ServiceConnection
* */
class MyServConn implements ServiceConnection{
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
/** 當(dāng)Service中有方法被調(diào)用時(shí),需要用到鏈接,此方法會(huì)執(zhí)行
* 注意必須有binder返回這個(gè)方法才有效
* 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)用,因?yàn)榇藭r(shí)的中間類對(duì)象為空.
}
public void show(View v){
ms.getShow();
ms.otherMethod();
}
}
代碼進(jìn)階
上述綁定服務(wù)機(jī)制存在一個(gè)小bug:中間類所有的方法都可以被調(diào)用者調(diào)用
解決方案:
- 寫(xiě)一個(gè)接口
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();
}
}
- 此時(shí),Activity類若直接調(diào)用中間類就會(huì)報(bào)錯(cuò),此時(shí)必須調(diào)用接口,然后通過(guò)接口調(diào)用中間類中的方法,這樣,只有接口中聲明過(guò)的方法才可以被調(diào)用
IService ms = (IService) service;
ms.otherMethod();//此時(shí)若是調(diào)用此方法就會(huì)報(bào)錯(cuò)
注意:在調(diào)用服務(wù)時(shí),若使用startService()可以啟動(dòng)服務(wù),且Activity退出后,service仍然可以后臺(tái)運(yùn)行
但在使用綁定服務(wù)機(jī)制時(shí),不能使用startService()方法,需要用bindService()方法來(lái)啟動(dòng)服務(wù).此時(shí),當(dāng)Activity退出后,Service也會(huì)跟著退出!
解決方案
先創(chuàng)建服務(wù):
Intent intent = new Intent(this, MyService.class);
創(chuàng)建完成后直接啟動(dòng),防止上述問(wèn)題發(fā)生
startService(intent);
當(dāng)需要用到綁定服務(wù)獲取方法時(shí),再使用bindService
bindService(intent, new MyServConn(), BIND_AUTO_CREATE);
這樣,問(wèn)題可以解決
相關(guān)鏈接:
遠(yuǎn)程服務(wù)(AIDL)
如以上內(nèi)容有任何錯(cuò)誤或補(bǔ)充,歡迎加QQ:1195211669 ,驗(yàn)證信息:簡(jiǎn)書(shū)