為 Android添加底層核心服務

來源:互聯網
上載者:User

 

本文轉自:http://blog.csdn.net/belyxiong/archive/2010/09/10/5875993.aspx

 

1.     為什麼要寫底層核心服務呢?
         因為底層核心服務是 Android架構裡最接近 Linux/Driver的部分。為了充分發揮硬體裝置的差異化特性,核心服務是讓上層 Java應用程式來使用 Driver/HW Device 特色的重要管道。例如 Media、 Telephone等底層硬體。

       在開機過程中,就可以啟動核心服務(漢字IME服務等),讓眾多應用程式來共同使用。

由於共用,所以能有效降低 Java應用程式的大小( Size)。

2.     核心服務與 Java 層的 Service有何區別和關係?
       Android具有兩層服務

             --Java層 SDK-based Service

             --C++層的 Code Service

   

 

 

3. 編寫自己的核心服務( C++ 層)
1). 要點
      核心服務通常在獨立的進程( Process )裡執行。

      必須提供 IBinder 介面,讓應用程式可以進行跨進程的綁定( Binding )和調用。

      因為共用,所以必須確保多安全執行緒( Thread-safe )。

使用 C++ 來實現,並調用 IServiceManager::addService() 函數添加到系統的 Binder Driver 裡。

上層應用程式通過 ServiceManager 擷取該服務。

上層應用程式通過 IBinder::transact() 函數來與核心服進行資料互動。

2). 添加服務
下面詳細介紹如何添加一個底層服務到系統中,假設服務名為 AddService ,其用途是對傳入的參數加上 1000 ,並返回結果。

服務實現
      進入 android 源碼 的目錄 frameworks/base ,在該目錄下建立自己的目錄,假設為 addservice ,再在這個目錄中建立兩個子目錄 addserver 和 libaddservice , addserver 用於存放服務的開機檔案,其最終的產生為可執行檔,在系統啟動的時候運行, libaddservice 用於存放服務的實現檔案,最終會產生動態連結程式庫,有 addserver 調用。

 

首先,服務的實現檔案包括兩個檔案,   AddService.h 和 AddService.cpp ,

以下是 AddService.h :

#ifndef ANDROID_GUILH_ADD_SERVICE_H

#define ANDROID_GUILH_ADD_SERVICE_H

 

#include <utils/RefBase.h>

#include <binder/IInterface.h>

#include <binder/Parcel.h>

#include <utils/threads.h>

 

namespace android {

        class AddService : public BBinder{// 從 BBinder 派生,實現本地介面

        

                public:

                static int instantiate();

                AddService();

                virtual ~AddService();

                virtual status_t onTransact(uint32_t, const Parcel&, Parcel*, uint32_t);

        };

}; //namespace

#endif

然後是服務的實現檔案 AddService.cpp :

#include "AddService.h"

#include <binder/IServiceManager.h>

#include <binder/IPCThreadState.h>

namespace android {

      static struct sigaction oldact;

static pthread_key_t sigbuskey;

// 把自己註冊到系統中

int AddService::instantiate() {

LOGE("AddService instantiate");

int r = defaultServiceManager()->addService(

String16("guilh.add"), new AddService());// 這裡主要是把 //AddSerice 這個服務添加到 Binder Driver 中服務名為 guilh.add

LOGE("AddService r = %d/n", r);

return r;

}

// 建構函式

AddService::AddService()

{

LOGV("AddService created");

mNextConnId = 1;

pthread_key_create(&sigbuskey, NULL);

}

// 解構函式

AddService::~AddService()

{

pthread_key_delete(sigbuskey);

LOGV("AddService destroyed");

}

// 這個是服務具體的本地實現,功能實現都應該放在這裡面,通過傳入執行代碼( code ) // 的不同來執行不同的操作,上層隱射為不同的 api 。

status_t AddService::onTransact(

uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags){

switch(code) {

case 0: {// 根據 code 的不同執行不同的操作

pid_t pid = data.readInt32();

int num = data.readInt32();

num = num + 1000;

reply->writeInt32(num);

return NO_ERROR;

}

break;

default:

return BBinder::onTransact(code, data, reply, flags);

}

}}; //namespace

 

以下是編譯服務的 Android.mk ,和上面的 cpp 放在一起。

LOCAL_PATH:= $(call my-dir)

include $(CLEAR_VARS)

LOCAL_SRC_FILES:= /

AddService.cpp

LOCAL_C_INCLUDES := /

$(JNI_H_INCLUDE)

LOCAL_SHARED_LIBRARIES :=     /

        libcutils             /

        libutils              /

        libbinder             /

        libandroid_runtime

LOCAL_PRELINK_MODULE := false

LOCAL_MODULE := libAdd

include $(BUILD_SHARED_LIBRARY)   #這一行表示編譯為動態庫

 

在命令列中退出到 android/目錄級 載入編譯環境 . build/envsetup.sh

然後 lunch。

然後在 cd  /android/frameworks/base/addservice/ libaddservice/ 目錄 輸入 mm

之後在 out 目錄產出 libAdd.so 檔案。

在此 完成核心服務第一步。

 

服務進程實現
                進入到 cd  /android/frameworks/base/addservice/addserver/ 目錄

增加一個檔案 addserver.cpp ,檔案內容如下:

 

#include <sys/types.h>

#include <unistd.h>

#include <grp.h>

#include <binder/IPCThreadState.h>

#include <binder/ProcessState.h>

#include <binder/IServiceManager.h>

#include <utils/Log.h>

#include <private/android_filesystem_config.h>

#include "../libaddservice/AddService.h"

//#include <libadd/AddService.h>

using namespace android;

int main(int argc, char** argv)

{

sp<ProcessState> proc(ProcessState::self());

sp<IServiceManager> sm = defaultServiceManager();//取得 ServiceManager

LOGI("ServiceManager: %p", sm.get());

AddService::instantiate();//把自己添加到 ServiceManager中

ProcessState::self()->startThreadPool();//啟動緩衝池

IPCThreadState::self()->joinThreadPool();//這裡是把服務添加到 Binder閉合迴圈進程中

}

以上為底層服務的標準操作。

下面是這個服務 makefile:

include $(CLEAR_VARS)

 

LOCAL_SRC_FILES:= /

        addserver.cpp

 

LOCAL_SHARED_LIBRARIES := /

        libAdd /

        libutils /

        libbinder

LOCAL_MODULE:= addserver

include $(BUILD_EXECUTABLE)//編譯為可執行檔

退出後目前的目錄執行 mm即可在 out目錄的 system/bin下產出 addserver可執行檔。

實現服務進程開機自動運行
進入到 /android/system/core/rootdir/目錄中有個 init.rc檔案

vi init.rc

在 service中添加

service addservice    /system/bin/addserver    //將 /system/bin/addserver作為一個服務啟動,服務的名稱為 addservice(這個不重要)。

 

最後退出到 android/目錄下執行全編譯:

輸入 . build/envsetup.sh

Lunch

Make

完成之後

Emulator開啟模擬器

開啟另一個 shell終端 輸入 adb shell    進入模擬器模式      如果 adbshell系統提示沒有發現該命令 就在 android/out/host/linux-x86/bin/中輸入   ./adb shell  

在輸入 ps  查看進程   找到是否有 addserver進程

如果有就成功一半。

 

測試我們的服務
 

隨便在 android/packages/apps 中 建立一個簡單的應用程式,

這裡可以直接在 eclipse 中建立好工程 拷貝到 android/packages/apps 中,然後為應用添加一個 Android.mk 檔案,可以從其他應用中拷貝來修改。

在應用程式中測試服務的代碼:

    private void test(){

                try{

                        IBinder binder = ServiceManager.getService("guilh.add");// 取得服務

                        Parcel data = Parcel.obtain();

                        Parcel reply = Parcel.obtain();

                        if(binder == null)

                                Log.d(TAG,"failed to get service");

                        data.writeInt(Process.myPid());// 固定操作

                        data.writeInt(100);// 傳入參數

                        binder.transact(0, data, reply, 0);// 執行遠程調用

                        Log.d(TAG,"result="+reply.readInt());// 驗證結果

                }catch(Exception e){

                         Log.d(TAG,e.toString());

                }

本文來自CSDN部落格,轉載請標明出處:http://blog.csdn.net/belyxiong/archive/2010/09/10/5875993.aspx

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.