當前位置:首頁 » 安卓系統 » android中service的實現方法

android中service的實現方法

發布時間: 2022-01-09 01:49:44

⑴ android中如何自定義一個Service

在編寫Android應用程序時,我們一般將一些計算型的邏輯放在一個獨立的進程來處理,這樣主進程仍然可以流暢地響應界面事件,提高用戶體驗。Android系統為我們提供了一個Service類,我們可以實現一個以Service為基類的服務子類,在裡面實現自己的計算型邏輯,然後在主進程通過startService函數來啟動這個服務。在本文中,將詳細分析主進程是如何通過startService函數來在新進程中啟動自定義服務的。

⑵ android程序設計基礎中service的基本原理是什麼

1. 說明
android的後台運行在很多service,它們在系統啟動時被SystemServer開啟,支持系統的正常工作,比如MountService監聽是否有SD卡安裝及移除,ClipboardService提供剪切板功能,PackageManagerService提供軟體包的安裝移除及查看等等,應用程序可以通過系統提供的Manager介面來訪問這些Service提供的數據,以下將說明他們的工具流程
2. 舉例說明基本流程
以android系統支持sensor(感測器)實例來說明框架層的service和manager是如何配合工作的
1) 什麼是sensor
sensor是感測器, 比如控制橫豎屏切換利用的就是重力感測器(gsensor), 還有accelerator sensor可取得x, y, z三個軸上的加速度(應用如平衡球, 小猴吃香蕉等)
2) 應用程序調用(以下為關鍵代碼)
sensorManager=(SensorManager)getSystemService(context.SENSOR_SERVICE);
lightSensor = sensorManager.getDefaultSensor(Sensor.TYPE_LIGHT);
sensorManager.registerListener(sensorListener, lightSensor, SensorManager.SENSOR_DELAY_NORMAL);
3) Manager層
a) 提供給應用程序調用的介面,同實與Service交互,實現功能
frameworks/base/core/java/android/hardware/SensorManager.java
4) Service層
a) 開機時就運行的管理Sensor的後台服務
frameworks/base/services/java/com/android/server/SensorService.java
b) snesor後台服務需要的JNI,通過它與系統級交互
frameworks/base/services/jni/com_android_server_SensorService.cpp
5) 系統層
a) 感測器的頭文件,硬體提供商按此文件的定義實現其功能
hardware/libhardware/include/hardware/sensors.h
b) 感測器的系統層實現,與內核交互,此處通常是硬體提供商提供的
hareware/libsensors
6) 內核及硬體層
內核訪問硬體,同時以設備文件等方式提供給上層控制介面和感測器數據
3. 系統層實現
1) frameworks/base/core/java/android/*Manager.java 對應用的介面
2) frameworks/base/core/jni/ 對應用的介面的JNI
3) frameworks/base/services/java/com/android/server/ 後台服務
4) frameworks/base/services/jni/ JNI與系統層介面
5) hardware/libhardware/include/ 系統層頭文件
6) hardware/libxxx 系統庫支持
7) 內核支持
4. 應用程序如何使用
1) 查看系統提供哪些服務
find frameworks/base/core/java/android/ -name *Manager.java
此處可以看到調用系統提供服務的入口
2) 一般register listener,事件發生時都收到回調
5. 新建一個service(以froyo為例)
1) 介面:介面供應用調用
frameworks/base/core/java/android/app/ContextImpl.java 加服務名與Manager對應
frameworks/base/core/java/android/content/Context.java 加服務名定義
2) Manager:提供服務對應的調用介面
frameworks/base/core/java/android/app/StartXXXXManager.java 實現調用介面
frameworks/base/core/java/android/app/IXXXXManager.aidl 定義調用介面
frameworks/base/Android.mk 加入aidl的編譯
3) service:提供後台服務支持
frameworks/base/services/java/com/android/server/XXXXService.java 服務實現
frameworks/base/services/java/com/android/server/SystemServer.java 啟動服務

⑶ android中怎麼啟動service

1、 Service不是分離開的進程,除非其他特殊情況,它不會運行在自己的進程,而是作為啟動運行它的進程的一部分。 2、 Service不是線程,這意味著它將在主線程里勞作。 啟動service有兩種方法: 1、 Context.startService() 調用者與服務之間沒有關聯,即使調用者退出,服務仍可運行 2、 Context.bindService() 調用者與服務綁定在一起,調用者一旦退出,服務也就終止 Service的生命周期 如果使用startService()啟動service,系統將通過傳入的Intent在底層搜索相關符合Intent裡面信息的service。如果 服務沒有啟動則先運行onCreate,然後運行onStartCommand (可在裡面處理啟動時傳過來的Intent和其他參數),直到明顯調用stopService或者stopSelf才將停止Service。無論運行 startService多少次,只要調用一次stopService或者stopSelf,Service都會停止。使用stopSelf(int)方 法可以保證在處理好intent後再停止。 控制service運行的主要方式有兩種,主要是根據onStartCommand方法返回的數值。方法: 1、START_STICKY 2、START_NOT_STICKY or START_REDELIVER_INTENT 這里主要解釋這三個變數的意義: 1、 START_STICKY 在運行onStartCommand後service進程被kill後,那將保留在開始狀態,但是不保留那些傳入的intent。不久後service就 會再次嘗試重新創建,因為保留在開始狀態,在創建 service後將保證調用onstartCommand。如果沒有傳遞任何開始命令給service,那將獲取到null的intent 2、 START_NOT_STICKY 在運行onStartCommand後service進程被kill後,並且沒有新的intent傳遞給它。Service將移出開始狀態,並且直到新的 明顯的方法(startService)調用才重新創建。因為如果沒有傳遞任何未決定的intent那麼service是不會啟動,也就是期間 onstartCommand不會接收到任何null的intent。 3、 START_REDELIVER_INTENT 在運行onStartCommand後service進程被kill後,系統將會再次啟動service,並傳入最後一個intent給 onstartCommand。直到調用stopSelf(int)才停止傳遞intent。如果在被kill後還有未處理好的intent,那被 kill後服務還是會自動啟動。因此onstartCommand不會接收到任何null的intent。 客戶端也可以使用bindService來保持跟service持久關聯。謹記:如果使用這種方法,那麼將不會調用onstartCommand(跟 startService不一樣,下面例子注釋也有解析,大家可試試)。客戶端將會在onBind回調中接收到IBinder介面返回的對象。通常 IBinder作為一個復雜的介面通常是返回aidl數據。 Service也可以混合start和bind一起使用。 許可權 要運行service,首先必須在AndroidManifest.xml里申明<service>標簽。 Service能夠保護個人的IPC調用,所以在執行實現該調用時前先使用checkCallingPermission(String) 方法檢查是否有這個許可權。

⑷ Android開發,怎麼在service中實現 oncreat方法創建子線程,onstart里實現子線程邏輯

創建線程後,在run, while(true){ xxx()} xxx(){ if(?)xxxx ?=false} ,onstart(){? = true}
這樣能否行.. 要不然你就每次都重新創建線程發送socket..

⑸ Android Service啟動方式

1.startService
①.定義一個類繼承service
②.在manifest.xml文件中配置該service
③.使用context的startService(intent)啟動該service
④.不再使用時,調用stopService(Intent)停止該服務
2.bindService
①.創建bindService服務段,繼承自service並在類中,創建一個實現binder介面的實例對象並提供公共方法給客戶端調用
②.從onbind()回調方法返回此binder實例
③.在客戶端中,從onserviceconnected()回調方法接收binder,並使用提供的方法調用綁定服務

⑹ android中service的實現方法是

非同步執行
android中,activity、service都是在主線程,service與activity的主要區別就是service沒有前台界面,不能直接與用戶交互,另外可以相對保證不會被系統隨便的kill掉。所以service適用於一些無需交互的後台操作,但如果你直接在service中進行耗時操作的話,因為在主線程所以依然會出現和activity主線程一樣的超時的問題,所以好的方式是在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()的時候要注意這點。

⑻ 安卓怎麼獲取service的方法

onBind里不是要返回一個IBinder 你在IBinder里寫一個get方法, return Service.this即可啊, 通常情況下不會這么說, 與service通信只需要用這個binder即可 , 雙向通信都可以用這個binder進行的.
追問: 我在其他頁面怎麼調用這個onBind方法啊?
追答: 只能在綁定這個sevice的地方調用噢
追問: 那其他界面沒綁定這個service的話,就要綁定了才可以調用?
追答: 那肯定的啊, 你這種設計就有問題, 多個activity為什麼要去調用這個service呢
追問: 是這樣,我現在要開發一個藍牙連接列印機的APP,然後手機控制列印機列印東西,我在這個界面去連接好列印機後,在其他頁面去設置列印的東西,比如在A界面列印超市小票,B界面列印二維碼圖片什麼的,所以就需要在A界面調用連接列印機的這個service去發送數據給列印機,在B界面也可以調用。那我現在就是哪裡需要發送數據給列印機,哪裡就要綁定一下那個service?
追答: 每個界面都要綁定

⑼ 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] = '';

si->death.func = svcinfo_death;

si->death.ptr = si;

si->next = svclist;

svclist = si;

}

binder_acquire(bs, ptr);

binder_link_to_death(bs, ptr, &si->death);

return 0;

}

在該函數中,首先會去檢查是否有許可權注冊service,如果沒有許可權就直接返回,不能注冊。


if (!svc_can_register(uid, s)) {

LOGE("add_service('%s',%p) uid=%d - PERMISSION DENIED ",

str8(s), ptr, uid);

return -1;

}

然後會去檢查該service是否已經注冊過了,如果已經注冊過,那麼就不能再注冊了:


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;

}

再判斷內存是否足夠:


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;

}

如果都沒什麼問題,會注冊該service,加入到svcList中來。注意,在ServiceManager中維護service信息的地方就是svclist。裡面存了service的name和handler。


服務獲取


通過以上幾個步驟,service就算注冊成功了。那麼當要獲得該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;


如果是獲取service,那麼執行SVC_MGR_CHECK_SERVICE,並把返回的數據寫入reply,返回給客戶端。


do_find_service函數中主要執行service的查找。


void *do_find_service(struct binder_state *bs, uint16_t *s, unsigned len)

{

struct svcinfo *si;

si = find_svc(s, len);

// LOGI("check_service('%s') ptr = %p ", str8(s), si ? si->ptr : 0);

if (si && si->ptr) {

return si->ptr;

} else {

return 0;

}

}

這樣在ServiceManager中就完成了服務的注冊和查找。來看下ServiceManager的功能圖:

轉載

⑽ android 啟動service的兩種方式有什麼不同

Service的生命周期Service的生命周期方法比Activity少一
些,只有onCreate,onStart,onDestroy
我們有兩種方式啟動一個Service,他們對Service生命周期
的影響是不一樣的。
1;通過startService:
Service會經歷onCreate->onStart,
stopService的時候直接onDestroy如果是調用者(TestServiceHolder)自己直接退出而沒有調用stopService的話,Service會一直在後台運行。下次TestServiceHolder再起來可以stopService。
2:通過bindService:
Service只會運行onCreate,這個時候TestServiceHolder和TestService綁定在一起
TestServiceHolder退出了,Srevice就會調用onUnbind->onDestroyed所謂綁定在一起就共存亡了。
那有同學問了,要是這幾個方法交織在一起的話,會出現什麼情況呢?
一個原則是Service的onCreate的方法只會被調用一次,就是你無論多少次的
startService又bindService,Service只被創建一次。如果先是bind了,那麼start的時候就直接運行Service的onStart方法,如果先是start,那麼bind的時候就直接運行onBind方法。如果你先bind上了,就
stop不掉了,對啊,就是stopService不好使了,只能先UnbindService,再StopService,
所以是先start還是先bind行為是有區別的。

熱點內容
聊天軟體編程 發布:2024-09-17 03:00:07 瀏覽:725
linuxoracle安裝路徑 發布:2024-09-17 01:57:29 瀏覽:688
兩個安卓手機照片怎麼同步 發布:2024-09-17 01:51:53 瀏覽:207
cf編譯後沒有黑框跳出來 發布:2024-09-17 01:46:54 瀏覽:249
安卓怎麼禁用應用讀取列表 發布:2024-09-17 01:46:45 瀏覽:524
win10設密碼在哪裡 發布:2024-09-17 01:33:32 瀏覽:662
情逢敵手迅雷下載ftp 發布:2024-09-17 01:32:35 瀏覽:337
安卓如何讓軟體按照步驟自動運行 發布:2024-09-17 01:28:27 瀏覽:197
Z包解壓命令 發布:2024-09-17 01:27:51 瀏覽:221
吉林ipfs存儲伺服器雲主機 發布:2024-09-17 01:27:38 瀏覽:685