導航:首頁 > 操作系統 > android中注冊service

android中注冊service

發布時間:2022-12-23 10:48:53

❶ 如何在android中添加系統服務

在android中添加系統服務,下面以SurfaceComposer這個service為例,
① 首先提供介面文件ISurfaceComposer.h
//frameworks\native\include\gui\ISurfaceComposer.h
//首先是介面,c++實現是虛函數
class ISurfaceComposer: public IInterface {
public:
DECLARE_META_INTERFACE(SurfaceComposer);
// flags for setTransactionState()
enum {
eSynchronous = 0x01,
eAnimation = 0x02,
};
enum {
eDisplayIdMain = 0,
};
/* create connection with surface flinger, requires
* ACCESS_SURFACE_FLINGER permission
*/
virtual sp<ISurfaceComposerClient> createConnection() = 0;
}
② 建立BnSurfaceComposer
建立BnSurfaceComposer,需要重寫BBinder的onTransact函數。
class BnSurfaceComposer: public BnInterface<ISurfaceComposer> {
public:
enum {
// Note: BOOT_FINISHED must remain this value, it is called from
// java by ActivityManagerService.
BOOT_FINISHED = IBinder::FIRST_CALL_TRANSACTION,
CREATE_CONNECTION,
CREATE_GRAPHIC_BUFFER_ALLOC,
CREATE_DISPLAY_EVENT_CONNECTION,
CREATE_DISPLAY,
DESTROY_DISPLAY,
GET_BUILT_IN_DISPLAY,
SET_TRANSACTION_STATE,
AUTHENTICATE_SURFACE,
BLANK,
UNBLANK,
GET_DISPLAY_INFO,
CONNECT_DISPLAY,
CAPTURE_SCREEN,
};
virtual status_t onTransact(uint32_t code, const Parcel& data,
Parcel* reply, uint32_t flags = 0);
};
③ Bpxxx的實現
frameworks\native\libs\gui\ISurfaceComposer.cpp中,
//Bp實現,代理端
class BpSurfaceComposer : public BpInterface<ISurfaceComposer>
{
public:
BpSurfaceComposer(const sp<IBinder>& impl)
: BpInterface<ISurfaceComposer>(impl)
{
}
//代理介面
virtual sp<ISurfaceComposerClient> createConnection()
{
uint32_t n;
Parcel data, reply;
data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
remote()->transact(BnSurfaceComposer::CREATE_CONNECTION, data, &reply);
return interface_cast<ISurfaceComposerClient>(reply.readStrongBinder());
}
}
④ Bnxxx的實現
//Bn端,即server端
status_t BnSurfaceComposer::onTransact(
uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
{
switch(code) {
case CREATE_CONNECTION: {
CHECK_INTERFACE(ISurfaceComposer, data, reply);
//createConnection就是server端的實現函數
sp<IBinder> b = createConnection()->asBinder();
reply->writeStrongBinder(b);
return NO_ERROR;
}
default: {
return BBinder::onTransact(code, data, reply, flags);
}
}
// should be unreachable
return NO_ERROR;
}
⑤ 注冊service
通過上面幾步已經完成了service的建立,我們需要將service注冊到service manager中。
class SurfaceFlinger : public BnSurfaceComposer,
//在frameworks\native\services\surfaceflinger\main_surfaceflinger.cpp中,
// publish surface flinger
sp<IServiceManager> sm(defaultServiceManager());
sm->addService(String16(SurfaceFlinger::getServiceName()), flinger, false);
⑥ 使用service
//首先獲取代理端BpSurfaceComposer
sp<ISurfaceComposer> composer(ComposerService::getComposerService());
//直接調用代理BpSurfaceComposer的介面
sp<IGraphicBufferAlloc> alloc(composer->createGraphicBufferAlloc());
其中getComposerService()的實現為,
/*static*/ sp<ISurfaceComposer> ComposerService::getComposerService() {
ComposerService& instance = ComposerService::getInstance();
Mutex::Autolock _l(instance.mLock);
if (instance.mComposerService == NULL) {
ComposerService::getInstance().connectLocked();
assert(instance.mComposerService != NULL);
ALOGD("ComposerService reconnected");
}
return instance.mComposerService;
}
void ComposerService::connectLocked() {
const String16 name("SurfaceFlinger");
//獲取service,返回的mComposerService是BpSurfaceComposer,有了Bp就能直接調用代理介面了
while (getService(name, &mComposerService) != NO_ERROR) {
usleep(250000);
}
assert(mComposerService != NULL);
// Create the death listener.
class DeathObserver : public IBinder::DeathRecipient {
ComposerService& mComposerService;
virtual void binderDied(const wp<IBinder>& who) {
ALOGW("ComposerService remote (surfaceflinger) died [%p]",
who.unsafe_get());
mComposerService.composerServiceDied();
}
public:
DeathObserver(ComposerService& mgr) : mComposerService(mgr) { }
};
mDeathObserver = new DeathObserver(*const_cast<ComposerService*>(this));
mComposerService->asBinder()->linkToDeath(mDeathObserver);
}
java添加service
Android為了方便開發人員,提供了AIDL工具,簡化了編寫service的難度。下面以添加TestService這個服務為例,
① 編寫AIDL文件
package android.app;
interface ITestService {
boolean enableWifi(boolean enabled);
}
TestService的AIDL文件提供了一個介面,enableWifi()。
② 創建TestService服務
TestService 服務需要繼承ITestService.Stub類,這個類就是通過AIDL工具對①中的AIDL文件處理後產生的,
class TestService extends ITestService.Stub {
//實現介面
public boolean enableWifi(boolean enabled)
{
......
}
}
③ Context.java中添加service名字字元串
// Context.java中添加service名字字元串
public static final String TEST_SERVICE = "my_test";
④ 向ServiceManager中注冊service
java中大部分的系統service都是在SystemServer中去向service manager注冊的,
//ServiceManager注冊service
// 在SystemServer.java中,模仿其他向ServiceManager添加service的方法
try {
TestService myService = new TestService(context);
ServiceManager.addService(Context.TEST_SERVICE, myService);
} catch (Throwable e) {
reportWtf("register my test service fail", e);
}
⑤創建服務對應的Manager
對於每一個service而言,通常會有一個相關的Manager。 Managers提供API給app使用,成為SDK的一部分,是apps和remote service的中間橋梁。Manager中的介面和Service中的介面必須一一對應。
public class TestServiceManager{
private final ITestService mService;
private final Context mContext;
//構造函數中傳入的service,其實就是BpTestService
TestServiceManager(Context context,ITestService service) {
mContext = context;
mService = service;
}
public boolean enableWifi(boolean enabled) {
try {
return mService.enableWifi(enabled);
} catch (RemoteException ex) {
}
return false;
}
}
到目前為止,我們只是完成了Service的注冊,但是還沒有使用,該如何使用?
⑥ contextImpl中注冊Manager
一旦我們實現了service和對應的Manager,需要有一種方法在app中調用他們。前面說過,Manager會成為SDK的一部分,供我們調用,那麼Manager和Service是如何聯系起來的?首先需要將我們的service和mangager注冊到execution context,即contextImpl中,
registerService(TEST_SERVICE, new ServiceFetcher() {
public Object createService(ContextImpl ctx) {
IBinder b = ServiceManager.getService(TEST_SERVICE);
//asInterface(BpBinder)後就是BpTestService
ITestService service = ITestService.Stub.asInterface(b);
//創建TestServiceManager,第二個參數為BpBpTestService
return new TestServiceManager(ctx.getOuterContext(), service);
}});
registerService的第二個參數是一個ServiceFetcher對象,這里直接在調用時,新建了一個ServiceFetcher類,重寫了createService方法。
ContextImpl.java中的registerService()方法,其核心就是把servicename和ServiceFetcher對象放到一個Hash的鍵值對中。
private static void registerService(String serviceName, ServiceFetcher fetcher) {
if (!(fetcher instanceof StaticServiceFetcher)) {
fetcher.mContextCacheIndex = ++;
}
SYSTEM_SERVICE_MAP.put(serviceName, fetcher);
}
app如何使用service
那麼app是如何調用的呢?
import android.app.TestServiceManager;
import android.content.Context;
TestServiceManager mTestServiceManager;
mTestServiceManager=(TestServiceManager)context.getSystemService(Context.TEST_SERVICE);
然後直接調用TestServiceManager中的方法即可,其中的奧秘需要分析下getSystemService函數。
ContextImpl.java中,
@Override
public Object getSystemService(String name) {
ServiceFetcher fetcher = SYSTEM_SERVICE_MAP.get(name);
//從ServiceFetcher 中獲取service
return fetcher == null ? null : fetcher.getService(this);
}
getService()函數的核心就是上面重寫的createService()函數,返回的就是TestServiceManager對象,所以通過context.getSystemService返回的是Manager對象。
public Object getService(ContextImpl ctx) {
ArrayList<Object> cache = ctx.mServiceCache;
Object service;
synchronized (cache) {
if (cache.size() == 0) {
// Initialize the cache vector on first access.
// At this point
// is the number of potential services that are
// cached per-Context.
for (int i = 0; i < ; i++) {
cache.add(null);
}
} else {
service = cache.get(mContextCacheIndex);
if (service != null) {
return service;
}
}
//調用重載的createService函數,返回的就是TestServiceManager對象
service = createService(ctx);
cache.set(mContextCacheIndex, service);
return service;
}
}

❷ Android中服務service

本文原文連接 https://blog.csdn.net/wen20102321/article/details/53155736

Service是Android中的四大組件之一,它的級別和Activity差不多。只不過Service沒有頁面顯示,只能後台運行,可以和其他組件進行交互。
Service的後台運行並不是子線程,是在主線程中進行的,只是它沒有界面顯示。如果Service進行了耗時操作同樣需要開啟子線程,否則會跟Activity一樣出現ANR問題(application not response–程序沒有響應)。
補充說明:
主線程的內容包括UI和後台,只要程序中的UI或者後台其中一個在跑,程序都算是在運行狀態。

1,創建一個自己的TestService繼承Service
2,必須實現重寫其中的onBind方法,可以在里邊做各種操作,也可以接收傳遞過來的Intent的數據。
(在Android Studio中可以直接新建一個Service)

服務的注冊是四大組件中最簡單的一個,一般只要設置name屬性就可以了。

1,startService()啟動
(1)啟動服務startService:onCerate(),onStart()
(2)停止服務stopService:onDestroy()
此方法啟動服務,服務如果未被創建,系統會先調用onCreate()方法,接著調用onStrat()方法。如果調用startService前服務已經被啟動,多次調用啟動方法,不會多次調用onCreate,但會導致多次調用onStrat。
2,bindService()啟動
(1)綁定bindService:onCreate(),onBind()
(2)解除綁定unbindService:onUnbind()
(3)正常停止程序服務的方法是先接觸綁定unbindService,在停止服務stopService
綁定後調用stopService方法,這時候是不能停止服務的,如果這時再調用解綁unbindService,程序會先解綁,後停止服務。
用此方法啟動服務,在服務未被創建時,會先調用onCreate(),接著調用onBind()方法,這時候調用者和服務綁定在一起,調用者退出,系統會先調用服務的onUnbind(),然後onDestroy()。如果調用bindService之前服務已經被綁定,多次調用bindService並不會導致onCreate()和onBind()方法被多次調用。如果調用者想與正在綁定的服務解除綁定,可以調用unbindService()。

(1),onCerate()服務第一次被創建
(2),onStartComand()服務開始工作
(3),onBind()服務已經綁定
(4),onUnBind()服務解綁
(5),onDestroy()服務已經停止

普通的Service進行耗時操作要創建一個線程去完成,因為service是在主線程運行的,並且這個子線程完成工作要手動停止 。IntentService是繼承了Service並處理起步請求的一個類,在IntentService內有一個工作線程,來處理耗時操作,啟動IntentService的方式和啟動傳統的Service是一樣,當任務執行完成後,IntentService會自動停止,而不需要我們去控制。
可以啟動多次IntentService,每一個耗時操作會以工作隊列的方式在IntentService的onHandleIntent回調方法中執行,並且每次只會執行一個工作線程,執行完第一個再執行第二個,以此類推,而且,所有請求都在一個單線程中,不會阻塞主線程,同一時間只處理一個請求。
IntentService優點
1,省去了在Service中開線程的麻煩
2,當操作完成時,不用手動停止Service。IntentService是Service,但是比Service更智能。

❸ Android 開機自啟動service實踐

Android 設備啟動的時候,會發送android.intent.action.BOOT_COMPLETED的廣播,監聽這個廣播來實現開機自啟動。

1) 創建需要的service和 BroadcastReceiver
2) 在AndroidManifest.xml 注冊service 和BroadcastReceiver

3)申明許可權
```
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>

}

❹ Android基礎:Service —— 默默為你服務

Service有兩種啟動方式,分別為 context.startService() context.bindService() 。這里要提到Service的生命周期,兩種不同的啟動方式有不同的生命周期:

Tips:

首先創建自己的Service類,重寫其生命周期,並在mainfest.xml中進行注冊。

必須注冊Service,不然不會調用。簡單注冊:

補充下Service在manifest中的屬性以及作用:

接下來,我們就可以用下面的兩個方法來啟動和停止服務。

首先在我們的Activity中創建Service連接對象,重寫連接和斷開的方法。創建自定義的Binder對象,在 onServiceConnected() 中賦值然後可以調用自定義Binder中的方法。使用下方的bind()方法來綁定服務,使用 unBind() 來解綁服務。

這里會用到Service的 onBind() onUnbind() 的生命周期,我們在TestService中重寫之。這里要注意的是,使用bindService()方法啟動的Service,不會調用 onStartCommand() 的生命周期。此外,創建自定義Binder類和對象。

這樣,當我們使用Activity中的bind()方法來綁定服務,會自動啟動服務,而我們又重寫了 onServiceConnected() 方法並使用myBinder來調用方法。這樣我們就可以用它來Activity和Service來進行通信。

特別Tips:
如果先使用 startService() 來開啟服務和 bindService() 來綁定服務,當使用 unbindService() 解綁時,Service並不會被銷毀。而是使用 stopService() 才能銷毀服務。

前台服務和後台服務的區別:

在Service中進行操作,將服務類型以前台的方式運行顯示在通知欄。

運行效果:

暫時引用吧,有空再實現一個:

參考資料:

❺ android 中 service 如果作為 內部類 的話怎麼在配置文件中被注冊啊

內部類不可以

Service 是android的一種機制,當它運行的時候如果是Local Service,那麼對應的 Service 是運行在主進程的 main 線程上的。如:onCreate,onStart 這些函數在被系統調用的時候都是在主進程的 main 線程上運行的。如果是Remote Service,那麼對應的 Service 則是運行在獨立進程的 main 線程上。

閱讀全文

與android中注冊service相關的資料

熱點內容
松餅pdf 瀏覽:667
萌新如何獲得命令 瀏覽:138
java設計模式及代碼 瀏覽:7
命令恢復資料庫 瀏覽:192
linuxoracle11gr2 瀏覽:972
攜程APP簽到在哪裡 瀏覽:389
dwg解壓方法 瀏覽:422
雲伺服器數據溝通 瀏覽:849
android地圖定位源碼 瀏覽:632
鴻蒙系統如何解除app安裝限制 瀏覽:497
阿里雲伺服器應用鏡像選哪個 瀏覽:343
win7策略更新命令 瀏覽:299
android源碼分析之設計模式 瀏覽:294
qq郵箱上的文件怎麼解壓在電腦上 瀏覽:504
業余學python是如何掙錢的 瀏覽:416
方舟伺服器連接超時顯示什麼 瀏覽:226
php繪制emoji 瀏覽:35
安卓桌面工具怎麼刪除 瀏覽:54
外六角螺絲套頭演算法 瀏覽:838
程序員特殊招數是什麼意思 瀏覽:352