Android 源碼中增加自定義系統(tǒng)服務

本文以一個簡單的例子詳細介紹如何為Android 6.0 系統(tǒng)新增一個系統(tǒng)服務,以及如何使用自定義系統(tǒng)服務女轿。
目標:1.創(chuàng)建一個自定義服務CCCService
2.APP 開發(fā)過程中可以使用 getSystemService("ccc") 獲取 CCCManager 并且調(diào)用里面的函數(shù)。

** step1 創(chuàng)建aidl文件**
在源碼frameworks/base/core/java/android/os/ 下面新增 一個 ICCCService.aidl
假設我們定義了5個函數(shù)珍策,這些函數(shù)將會在SystemServer進程執(zhí)行蹭劈。
內(nèi)容如下

// ICCCService.aidl
package android.os;

// Declare any non-default types here with import statements

interface ICCCService {
    /**
     * Demonstrates some basic types that you can use as parameters
     * and return values in AIDL.
     */
   void setVal(String key,String value);
   String getVal(String key);
   void appendLog(String log);
   void clearLog();
   String readLog();
}

step2 創(chuàng)建Service文件 (CCCService)
在 frameworks/base/services/core/java/com/android/server/ 下面新增一個 CCCService.java 用來實現(xiàn)aidl文件定義的接口肺孵。
內(nèi)容如下

package com.android.server;

import java.io.InputStreamReader;
import java.io.LineNumberReader;
import java.lang.*;
import java.util.HashMap;
import android.os.RemoteException;
import android.os.ICCCService;


/**
 *
 * Created by zhuangqianliu on 2016/9/21.
 */

public class CCCService extends ICCCService.Stub {
    private static HashMap<String,String> map=new HashMap<>();
    private static String inner_log="";

    public CCCService() {

    }

    @Override
    public void setVal(String key, String value) throws RemoteException {
        map.put(key,value);
    }

    @Override
    public String getVal(String key) throws RemoteException {
        return map.get(key);
    }

    @Override
    public void appendLog(String log) throws RemoteException {
        inner_log+=log+"\n";
    }

    @Override
    public void clearLog() throws RemoteException {
        inner_log="";
    }

    @Override
    public String readLog() throws RemoteException {
        return inner_log;
    }

}

step3 將自定義Service 加入到SystemServer 啟動進程
**先在 frameworks/base/core/java/android/content/Context.java 中添加一行 **
public static final String CCC_SERVICE="ccc";
修改 frameworks/base/services/java/com/android/server/SystemServer.java
在 startOtherServices() 函數(shù) 的try模塊中增加以下代碼

 try {

                Slog.i(TAG, "CCC Service");

                ServiceManager.addService(Context.CCC_SERVICE, new CCCService());

            } catch (Throwable e) {

                Slog.e(TAG, "Failure starting CCC Service", e);

            }

最終效果如圖


step4 創(chuàng)建Manager凳怨,即CCCManager
在frameworks/base/core/java/android/app/ 下創(chuàng)建CCCManager.java 文件 內(nèi)容如下

package android.app;

/**
 * Created by liam on 16/10/2.
 */
import android.annotation.SdkConstant;
import android.annotation.SystemApi;
import android.content.Context;
import android.content.Intent;
import android.os.Build;
import android.os.Parcel;
import android.os.Parcelable;
import android.os.RemoteException;
import android.os.ICCCService;
import android.util.Log;

public class CCCManager {
    ICCCService mService;
    public CCCManager(Context ctx,ICCCService service){
        mService=service;
    }
    public void setVal(String key,String value){
        try{
            mService.setVal(key,value);
        }catch(Exception e){
            Log.e("CCCManager",e.toString());
            e.printStackTrace();
        }

    }
    public String getVal(String key){
        try{
            return mService.getVal(key);
        }catch(Exception e){
            Log.e("CCCManager",e.toString());
            e.printStackTrace();
        }
        return null;
    }
    public void appendLog(String log){
        try{
            mService.appendLog(log);
        }catch(Exception e){
            Log.e("CCCManager",e.toString());
            e.printStackTrace();
        }
    }
    public void clearLog(){
        try{
            mService.clearLog();
        }catch(Exception e){
            Log.e("CCCManager",e.toString());
            e.printStackTrace();
        }
    }
    public String readLog(){
        try{
            return mService.readLog();
        }catch(Exception e){
            Log.e("CCCManager",e.toString());
            e.printStackTrace();
        }
        return null;
    }
}

step5 注冊到SystemService
修改frameworks/base/core/java/android/app/SystemServiceRegistry.java
在靜態(tài)代碼塊中增加

registerService(Context.CCC_SERVICE, CCCManager.class,
                new CachedServiceFetcher<CCCManager>() {
                    @Override
                    public CCCManager createService(ContextImpl ctx) {
                        IBinder b = ServiceManager.getService(Context.CCC_SERVICE);
                        ICCCService service = ICCCService.Stub.asInterface(b);
                        return new CCCManager(ctx, service);
                    }});

step6 修改SePolicy的編譯驗證
修改 /external/sepolicy/service.te
在最后一行添加
type ccc_service, system_api_service, system_server_service, service_manager_type;
然后修改同目錄下 /external/sepolicy/service_contexts 文件
中間插入一行
ccc u:object_r:ccc_service:s0
如圖所示

step7 重新編譯源碼
別忘了先 make update-api瑰艘。

**Step8 測試 **


tip:
可以先創(chuàng)建一個java工程簡單寫一個CCCManager類,導出jar 在ide中使用provided 依賴肤舞。這樣開發(fā)過程中就不會報錯紫新。

java臨時工程如下使用 IDEA創(chuàng)建的java項目


Android studio 項目配置

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市李剖,隨后出現(xiàn)的幾起案子芒率,更是在濱河造成了極大的恐慌,老刑警劉巖篙顺,帶你破解...
    沈念sama閱讀 216,843評論 6 502
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件偶芍,死亡現(xiàn)場離奇詭異,居然都是意外死亡德玫,警方通過查閱死者的電腦和手機匪蟀,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,538評論 3 392
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來宰僧,“玉大人材彪,你說我怎么就攤上這事∏俣” “怎么了段化?”我有些...
    開封第一講書人閱讀 163,187評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長凤类。 經(jīng)常有香客問我穗泵,道長,這世上最難降的妖魔是什么谜疤? 我笑而不...
    開封第一講書人閱讀 58,264評論 1 292
  • 正文 為了忘掉前任佃延,我火速辦了婚禮现诀,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘履肃。我一直安慰自己仔沿,他們只是感情好,可當我...
    茶點故事閱讀 67,289評論 6 390
  • 文/花漫 我一把揭開白布尺棋。 她就那樣靜靜地躺著封锉,像睡著了一般。 火紅的嫁衣襯著肌膚如雪膘螟。 梳的紋絲不亂的頭發(fā)上成福,一...
    開封第一講書人閱讀 51,231評論 1 299
  • 那天,我揣著相機與錄音荆残,去河邊找鬼奴艾。 笑死,一個胖子當著我的面吹牛内斯,可吹牛的內(nèi)容都是我干的蕴潦。 我是一名探鬼主播,決...
    沈念sama閱讀 40,116評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼俘闯,長吁一口氣:“原來是場噩夢啊……” “哼潭苞!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起真朗,我...
    開封第一講書人閱讀 38,945評論 0 275
  • 序言:老撾萬榮一對情侶失蹤此疹,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后蜜猾,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體秀菱,經(jīng)...
    沈念sama閱讀 45,367評論 1 313
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,581評論 2 333
  • 正文 我和宋清朗相戀三年蹭睡,在試婚紗的時候發(fā)現(xiàn)自己被綠了衍菱。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,754評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡肩豁,死狀恐怖脊串,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情清钥,我是刑警寧澤琼锋,帶...
    沈念sama閱讀 35,458評論 5 344
  • 正文 年R本政府宣布,位于F島的核電站祟昭,受9級特大地震影響缕坎,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜篡悟,卻給世界環(huán)境...
    茶點故事閱讀 41,068評論 3 327
  • 文/蒙蒙 一谜叹、第九天 我趴在偏房一處隱蔽的房頂上張望匾寝。 院中可真熱鬧,春花似錦荷腊、人聲如沸艳悔。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,692評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽猜年。三九已至,卻和暖如春疾忍,著一層夾襖步出監(jiān)牢的瞬間乔外,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,842評論 1 269
  • 我被黑心中介騙來泰國打工一罩, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留袁稽,地道東北人。 一個月前我還...
    沈念sama閱讀 47,797評論 2 369
  • 正文 我出身青樓擒抛,卻偏偏與公主長得像,于是被迫代替她去往敵國和親补疑。 傳聞我的和親對象是個殘疾皇子歧沪,可洞房花燭夜當晚...
    茶點故事閱讀 44,654評論 2 354

推薦閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,085評論 25 707
  • 1:InputChannel提供函數(shù)創(chuàng)建底層的Pipe對象 2: 1)客戶端需要新建窗口 2)new ViewRo...
    自由人是工程師閱讀 5,301評論 0 18
  • 此文主要介紹Android啟動后,從Init進程到Home界面的過程莲组,首先上時序圖: 我將從時序圖上的序號開始一一...
    foxleezh閱讀 1,910評論 1 7
  • 人情冷暖什么時候感悟得最深刻锹杈?被刺傷之后撵孤。那我們之前知不知道這個道理呢?其實是知道的竭望,只不過我們心底仍然有一絲的...
    遺失在圍城閱讀 241評論 0 0
  • 任何一種新嘗試邪码,剛開始時,總是歡欣鼓舞新鮮有趣咬清;但真相是真正的成功總是躲在大山后面闭专,我們卻不知道。 在這條道路上旧烧,...
    大胡子逸舟閱讀 288評論 0 0