『壹』 android service有什麼用
Service是Android中實現程序後台運行的解決方案,它非常適合執行那些不需要和用戶交互而
且還要求長期運行的任務。Service的運行不依賴於任何用戶界面,即使程序被切換到後台,或
者用戶打開了另外一個應用程序,Service仍然能夠保持正常運行。
所以你說service有什麼用
『貳』 Android中如何啟用Service,如何停用Service
• Context.startService()
• Context.bindService()
1. 在同一個應用任何地方調用 startService() 方法就能啟動 Service 了,然後系統會回調 Service 類的
onCreate() 以及 onStart() 方法。這樣啟動的 Service 會一直運行在後台,直到
Context.stopService() 或者 selfStop() 方法被調用。另外如果一個 Service 已經被啟動,其他代碼再試圖調用
startService() 方法,是不會執行 onCreate() 的,但會重新執行一次 onStart() 。
2. 另外一種 bindService() 方法的意思是,把這個 Service 和調用 Service
的客戶類綁起來,如果調用這個客戶類被銷毀,Service 也會被銷毀。用這個方法的一個好處是,bindService() 方法執行後
Service 會回調上邊提到的 onBind() 方發,你可以從這里返回一個實現了 IBind
介面的類,在客戶端操作這個類就能和這個服務通信了,比如得到 Service 運行的狀態或其他操作。如果 Service
還沒有運行,使用這個方法啟動 Service 就會 onCreate() 方法而不會調用 onStart()。
總結:
1.
startService()的目的是回調onStart()方法,onCreate()
方法是在Service不存在的時候調用的,如果Service存在(例如之前調用了bindService,那麼Service的onCreate方法
已經調用了)那麼startService()將跳過onCreate() 方法。
2.
bindService()目的是回調onBind()方法,它的作用是在Service和調用者之間建立一個橋梁,並不負責更多的工作(例如一個
Service需要連接伺服器的操作),一般使用bindService來綁定到一個現有的Service(即通過StartService啟動的服
務)。
由於Service 的onStart()方法只有在startService()啟動Service的情況下才調用,故使用onStart()的時候要注意這點。
『叄』 Android Service 為什麼要綁定服務 僅僅是因為要獲取服務中的方法嗎
Android中Service是運行在後台的東西,級別與activity一樣。
既然說service是運行在後台的服務,那麼它就是不可見的,沒有界面的東西。
你可以啟動一個服務Service來播放音樂,或者記錄你地理信息位置的改變,或者啟動一個服務來運行並一直監聽某種動作。
Service和其他組件一樣,都是運行在主線程中,因此不能用它來做耗時的請求或者動作。你可以在服務中開一一個線程,在線程中做耗時動作。
服務一般分為兩種:
1:本地服務,Local Service 用於應用程序內部。在Service可以調用Context.startService()啟動,調用Context.stopService()結束。在內部可以調用Service.stopSelf() 或 Service.stopSelfResult()來自己停止。無論調用了多少次startService(),都只需調用一次stopService()來停止。
2:遠程服務, Remote Service 用於android系統內部的應用程序之間。可以定義介面並把介面暴露出來,以便其他應用進行操作。客戶端建立到服務對象的連接,並通過那個連接來調用服務。調用Context.bindService()方法建立連接,並啟動,以調用 Context.unbindService()關閉連接。多個客戶端可以綁定至同一個服務。如果服務此時還沒有載入,bindService()會先載入它。
提供給可被其他應用復用,比如定義一個天氣預報服務,提供與其他應用調用即可。
3.Service的生命周期
context.startService() ->onCreate()- >onStart()->Service running--調用context.stopService() ->onDestroy()
context.bindService()->onCreate()->onBind()->Service running--調用>onUnbind() -> onDestroy()
從上訴可以知道分別對應本地的,,以及遠程的,也對應不同的方式啟動這個服務。
4.如果你Activity不綁定服務,那麼就無法與遠程服務進行通信
例如你要調用其它應用的服務(進程之間的通信)
有關更多的RPC通信建議查看android官網的API
『肆』 Android中怎麼啟動關閉Service及功能解釋
調用startService就是啟動service,調用stopService就是關閉service。
android中Service是運行在後台的東西,級別與activity差不多。既然說service是運行在後台的服務,那麼它就是不可見的,沒有界面的東西。可以啟動一個服務Service來播放音樂,或者記錄地理信息位置的改變,或者啟動一個服務來運行並一直監聽某種動作。Service和其他組件一樣,都是運行在主線程中,因此不能用它來做耗時的請求或者動作。
服務一般分為兩種:
1:本地服務, Local Service 用於應用程序內部。在Service可以調用Context.startService()啟動,調用Context.stopService()結束。在內部可以調用Service.stopSelf() 或 Service.stopSelfResult()來自己停止。無論調用了多少次startService(),都只需調用一次stopService()來停止。
2:遠程服務, Remote Service 用於android系統內部的應用程序之間。可以定義介面並把介面暴露出來,以便其他應用進行操作。客戶端建立到服務對象的連接,並通過那個連接來調用服務。調用Context.bindService()方法建立連接,並啟動,以調用 Context.unbindService()關閉連接。多個客戶端可以綁定至同一個服務。如果服務此時還沒有載入,bindService()會先載入它。
『伍』 android servicemanager 怎麼實現service管理
ServiceManager是android中比較重要的一個進程,它是在init進程啟動之後啟動,從名字上就可以看出來它是用來管理系統中的service。比如:InputMethodService、ActivityManagerService等。在ServiceManager中有兩個比較重要的方法:add_service、check_service。系統的service需要通過add_service把自己的信息注冊到ServiceManager中,當需要使用時,通過check_service檢查該service是否存在。
主函數(anrdroid4.0/frameworks/base/cmds/servicemanager/service_manager.c)
從它的主函數代碼開始:
int main(int argc, char **argv)
{
struct binder_state *bs;
void *svcmgr = BINDER_SERVICE_MANAGER;
bs = binder_open(128*1024);
if (binder_become_context_manager(bs)) {
LOGE("cannot become context manager (%s) ", strerror(errno));
return -1;
}
svcmgr_handle = svcmgr;
binder_loop(bs, svcmgr_handler);
return 0;
}
從main函數中可以看出,它主要做了三件事情:
打開/dev/binder設備,並在內存中映射128K的空間。
通知Binder設備,把自己變成context_manager
進入循環,不停的去讀Binder設備,看是否有對service的請求,如果有的話,就去調用svcmgr_handler函數回調處理請求。
服務注冊
再來看看ServiceManager中是怎麼樣去注冊服務的。先來看先,當有對service的請求時,調用的回調函數svcmgr_handler:
int svcmgr_handler(struct binder_state *bs,
struct binder_txn *txn,
struct binder_io *msg,
struct binder_io *reply)
{
struct svcinfo *si;
uint16_t *s;
unsigned len;
void *ptr;
uint32_t strict_policy;
// LOGI("target=%p code=%d pid=%d uid=%d ",
// txn->target, txn->code, txn->sender_pid, txn->sender_euid);
if (txn->target != svcmgr_handle)
return -1;
// Equivalent to Parcel::enforceInterface(), reading the RPC
// header with the strict mode policy mask and the interface name.
// Note that we ignore the strict_policy and don't propagate it
// further (since we do no outbound RPCs anyway).
strict_policy = bio_get_uint32(msg);
s = bio_get_string16(msg, &len);
if ((len != (sizeof(svcmgr_id) / 2)) ||
memcmp(svcmgr_id, s, sizeof(svcmgr_id))) {
fprintf(stderr,"invalid id %s ", str8(s));
return -1;
}
switch(txn->code) {
case SVC_MGR_GET_SERVICE:
case SVC_MGR_CHECK_SERVICE:
s = bio_get_string16(msg, &len);
ptr = do_find_service(bs, s, len);
if (!ptr)
break;
bio_put_ref(reply, ptr);
return 0;
case SVC_MGR_ADD_SERVICE:
s = bio_get_string16(msg, &len);
ptr = bio_get_ref(msg);
if (do_add_service(bs, s, len, ptr, txn->sender_euid))
return -1;
break;
case SVC_MGR_LIST_SERVICES: {
unsigned n = bio_get_uint32(msg);
si = svclist;
while ((n-- > 0) && si)
si = si->next;
if (si) {
bio_put_string16(reply, si->name);
return 0;
}
return -1;
}
default:
LOGE("unknown code %d ", txn->code);
return -1;
}
bio_put_uint32(reply, 0);
return 0;
}
在該回調函數中會判斷Service有什麼需要,如果是請求注冊service,那麼久執行:
case SVC_MGR_ADD_SERVICE:
s = bio_get_string16(msg, &len);
ptr = bio_get_ref(msg);
if (do_add_service(bs, s, len, ptr, txn->sender_euid))
return -1;
break;
我們再來看看do_add_service中做了什麼事情:
int do_add_service(struct binder_state *bs,
uint16_t *s, unsigned len,
void *ptr, unsigned uid)
{
struct svcinfo *si;
// LOGI("add_service('%s',%p) uid=%d ", str8(s), ptr, uid);
if (!ptr || (len == 0) || (len > 127))
return -1;
if (!svc_can_register(uid, s)) {
LOGE("add_service('%s',%p) uid=%d - PERMISSION DENIED ",
str8(s), ptr, uid);
return -1;
}
si = find_svc(s, len);
if (si) {
if (si->ptr) {
LOGE("add_service('%s',%p) uid=%d - ALREADY REGISTERED ",
str8(s), ptr, uid);
return -1;
}
si->ptr = ptr;
} else {
si = malloc(sizeof(*si) + (len + 1) * sizeof(uint16_t));
if (!si) {
LOGE("add_service('%s',%p) uid=%d - OUT OF MEMORY ",
str8(s), ptr, uid);
return -1;
}
si->ptr = ptr;
si->len = len;
memcpy(si->name, s, (len + 1) * sizeof(uint16_t));
si->name[len] = '