1. 程式人生 > >Android framework層新增三方應用介面,及新增系統Service(轉)

Android framework層新增三方應用介面,及新增系統Service(轉)

親測可用Android原生程式碼新增系統服務

2017年01月12日 21:55:56

閱讀數:5492

在Android系統中,為我們提供了很多的系統服務,比如AMS,PMS等,今天參考系統裡其他服務的實現,在Android N原生程式碼中新增自己定製的服務,想想都滿激動的

準備工作

在正式開始之前,需要知道下面兩點以及滿足下面條件:

前提條件

Android原生程式碼,可以通過make全編通過,編譯完成之後,可以通過emulator命令啟動out目錄下生成的image檔案,需要注意在執行emulator命令之前,需要執行source build/envsetup.sh構建環境,以及lunch選擇產品

如何呼叫系統服務

// 比如WindowManagerService的使用
WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
  • 系統服務的註冊流程

其實跟著上面的context.getSystemService程式碼,就可以知道系統服務的註冊流程,實際上ContextImpl也是通過SystemServiceRegistry.getSystemService來獲取具體的服務,這些系統服務都是在SystemServiceRegistry的static靜態程式碼塊中進行註冊的

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

        registerService(Context.ACTIVITY_SERVICE, ActivityManager.class,
                new CachedServiceFetcher<ActivityManager>() {
            @Override
            public ActivityManager createService(ContextImpl ctx) {
                return new ActivityManager(ctx.getOuterContext(), ctx.mMainThread.getHandler());
            }});
.....
}

下面就是照葫蘆畫瓢的步驟

定義ISelfManager.aidl檔案

系統裡面很多的aidl檔案定義在/frameworks/base/core/java/android/os下,所以我們需要做的就是參考其他的aidl,照樣子寫一個簡單的ISelfManager.aidl

/frameworks/basecore/java/android/os/ISelfManager.aidl

package android.os;

interface ISelfManager {

    int selfAddNumber(int numberFirst, int numberSecond);
    String selfAddString(String originalStr);
}
  • 更新Android.mk檔案

在frameworks/base/Android.mk檔案的LOCAL_SRC_FILES中系統添加了很多aidl檔案,我們需要新增自己定義的ISelfManager.aidl檔案

LOCAL_SRC_FILES += \
    core/java/android/accessibilityservice/IAccessibilityServiceConnection.aidl \
    core/java/android/accessibilityservice/IAccessibilityServiceClient.aidl \
        .....
        core/java/android/os/ISelfManager.aidl \

然後使用mmm frameworks/base,此時會自動根據aidl檔案生成對應的stub介面,其實這裡沒有生成也沒有關係,我們可以自己將該檔案新增到Android studio中,讓ADT自動生成也可以,這裡主要是方便後面編寫實現類,沒有太多的實際意義。

新增遠端實現SelfManagerService.java

我們都知道像系統裡的服務都是放在frameworks/base/services/core/java/com/android/server目錄下的,比如:

  1. ActivityManagerService.java 
    frameworks/base/services/core/java/com/android/server/am

  2. WindowManagerService.java 
    frameworks/base/services/core/java/com/android/server/wm

這裡,我們沒有特殊的需求就放在frameworks/base/services/core/java/com/android/server裡

SelfManagerService.java

package com.android.server;
import android.util.Log;
import android.os.ISelfManager;

public class SelfManagerService extends ISelfManager.Stub {
    private static final String TAG = "SelfManagerService";


    public int selfAddNumber(int numberFirst, int numberSecond) {
        Log.d(TAG,"I WILL CALCULATE IT numberFirst is:"+numberFirst+"  numberSecond is :"+numberSecond);
    return numberFirst + numberSecond;
    }

    public String selfAddString(String originalStr) {
    Log.d(TAG,"I will add a string to originalStr previous....");
        return "previous lalala "+originalStr;
    }
}
  • 建立對應的SelfManager

/frameworks/base/core/java/android/app/SelfManager.java

package android.app;
import android.util.Log;
import android.os.ISelfManager;
import android.content.Context;
import android.os.RemoteException;

public class SelfManager {
    private static String TAG = "SelfManager";

    ISelfManager mSelfManager;

    public SelfManager(Context ctx,ISelfManager selfManager) {
        mSelfManager = selfManager;
    }

    public int selfAddNumber(int numberFirst, int numberSecond) throws RemoteException {
        Log.d(TAG,"SelfManager  selfAddNumber ......... ");
        return mSelfManager.selfAddNumber(numberFirst,numberSecond);
    }

    public String selfAddString(String originalStr) throws RemoteException {
    Log.d(TAG,"SelfManager  selfAddString .........");
        return mSelfManager.selfAddString(originalStr);
    }
}
  • 管理和註冊SelfManagerService

在開始之前,已經分析系統Service的註冊流程,需要分別在SystemServer.java和SystemServiceRegistry.java中修改

  • 在SystemServer.java中將SelfManagerService新增到ServiceManager中管理,這裡我新增到了startOtherServices方法中
private void startOtherServices() {
    ....

    ServiceManager.addService("selfservice", new SelfManagerService());
    ....
}
  • 在SystemServiceRegistry.java中註冊我們的SelfManagerService服務
import android.os.ISelfManager;
static {
    ....
    registerService("selfservice", SelfManager.class,
                new CachedServiceFetcher<SelfManager>() {
                    @Override
                    public SelfManager createService(ContextImpl ctx) {
                        IBinder b = ServiceManager.getService("selfservice");
                        ISelfManager service = ISelfManager.Stub.asInterface(b);
                        return new SelfManager(ctx,service);
                }});
    ....
}
  • 這裡的”selfservice”,一般來說需要在Context.java中宣告,然後在這裡引用,比如系統中的其他服務呼叫時候的應用,都是在Context.java中定義的,比如 
    這裡寫圖片描述

這一步,別忘記引包就行.

更新sepolicy配置

另外還需要更新sepolicy的配置,否則即使編譯通過也是不會生效的。

更新service.te檔案

service.te主要用來定義我們自己服務的型別,在/system/sepolicy/service.te目錄下,不同廠商的定製可能導致該路徑不同在該檔案中已經定義了很多service型別,只需要照著畫就行了。

type wifi_service, app_api_service, system_server_service, service_manager_type;
// 參照 wifi_service的定義新增自己的定義就行了
type self_service, system_api_service, system_server_service, service_manager_type;
  • 更新service_contexts檔案
selfservice     u:object_r:self_service:s0

現在萬事已經具備了.全編就可以了,需要注意, 在全編之前,需要更新當前系統的API 
執行make update-api -j4,完成之後會生成自己新增的服務的API

/frameworks/base/api/current.txt

public class SelfManager {
    ctor public SelfManager(android.content.Context, android.os.ISelfManager);
    method public int selfAddNumber(int, int) throws android.os.RemoteException;
    method public java.lang.String selfAddString(java.lang.String) throws android.os.RemoteException;
}
  • 完成之後,執行make命令全編就可以了

驗證SelfManagerService

自己獨立編寫一個應用,然後參照packages/apps/中的其他模組實現Android.mk,或者基於系統已有的應用來測試,這裡我是在Mms中新增的

import android.app.SelfManager;
import android.os.RemoteException;

        try {
            SelfManager selfManager = (SelfManager) getSystemService("selfservice");
            int addResult = selfManager.selfAddNumber(3,4);
            Log.d("Servicehahatest","result is :"+addResult);
            String strResult = selfManager.selfAddString("HELLO WORLD...");
            Log.d("Servicehahatest","result is :"+strResult);
        } catch(RemoteException e) {
        Log.d("Servicehahatest","RemoteException happend .....e is :"+e.toString());
        }

此時執行效果如下: 
這裡寫圖片描述

OK,到此為止,在Android N中新增系統服務就完成了。

相關推薦

Android framework新增三方應用介面新增系統Service()

原 親測可用Android原生程式碼新增系統服務 2017年01月12日 21:55:56 閱讀數:5492 在Android系統中,為我們提供了很多的系統服務,比如AMS,PMS等,今天參考系統裡其他服務的實現,在Android N原生程式碼中新增自己定製的服務,

Android Framework C/C++程式碼中新增日誌

在對應目錄下的Android.mk檔案中新增一下內容 LOCAL_LDLIBS := -llog LOCAL_SHARED_LIBRARIES += \ libcutils \ libutils 在cpp檔案中定義: #define LOGD_TAG "S

android Framework新增資源方式

最近工作中,在移植輸入法去新的分支的時候,發現輸入法在彈出過程會強死,這是因為呼叫framework層的一個layout時查詢不到;於是找到這個資源,在framework層中添加了這個資源,但是發現編譯後輸入法仍然找不到這個資源。通過網路搜尋,找到了原因。在系統

怎樣從C++代碼直接訪問android framework的WifiService

-a namespace cpi 編譯 pla desc argc 封裝 conf 說究竟,Java層的service就是就C++層的binder的封裝。所以從原理上來講通過C++代碼直接訪問android framework層的service是全然可能的,這篇

交管系統介面UI新增刪除課程

from selenium import webdriver import time import string, random import requests import pprint sele刪除課程 def Delete_Course(): driver = webdri

Androidfragment 巢狀時viewPager不顯示的問題

版權宣告:本文為博主原創文章,未經博主允許不得轉載。 https://blog.csdn.net/zkll200/article/details/73692518 先看一段錯誤程式碼,這段程式碼寫在一個 Fragment 中: private void initVi

Android framework自定義jni

framework新增自定jni    本文章適用於在原始碼環境下在framework新增自定的jni供上層Apk呼叫。 1 framework新增自定jni 新增自定義的jni檔案和Androidmk 新增系統編譯配置 新增自定義的jni檔案和Android.mk 首先在f

Android呼叫手機中的應用市場實現評分功能

需求很簡單,通過手機中的按鈕開啟手機中安裝的應用市場,給自己的app評分,實現程式碼如下: String packageName = getPackageName(); //開啟所有安裝的市場 Uri uri = Uri.parse("market://details?id="+ p

android 比較全的android 原始碼合集 + 企業級應用分享從業的積累

android開發一些體會 前言 不知不覺自己已經做了幾年開發了,由記得剛出來工作的時候感覺自己能牛逼,現在回想起來感覺好無知。懂的越多的時候你才會發現懂的越少。 如果你的知識是一個圓,當你的圓越大時,圓外面的世界也就越大。 最近看到很多And

Android Framework學習——Launcher啟動應用程式過程原始碼分析

        ActivityInfo aInfo = r.activityInfo;         if (r.packageInfo == null) {             r.packageInfo = getPackageInfo(aInfo.applicationInfo,      

【Python爬蟲】有道翻譯最新爬蟲教程帶GUI應用介面2018年3月18日實測可用

最新的有道翻譯爬蟲程式碼,包含應用程式介面,更新於20180318import urllib.request import urllib.parse import json import time import gzip import random import hashli

如何閱讀Android framework原始碼

閱讀Android Framework層的原始碼可能是Android 開發者深入學習的必經之路。但在我學習的過程中看到最多的是各路大神的原始碼分析,而很少有展示如何一步一步找到相關程式碼的。直到前不久看到老羅的視訊《Android原始碼情景分析法》,很有啟發。但

android framework是用於開發什麼

framework的開發比應用層就要煩的多啦。做應用在eclipse中就足夠了,用android系統中的控制元件等工具,或者是自己寫個類來實現特定的功能。而framework層的開發,需要往原始碼中新增程式碼、xml、圖片、id等等資料,這個id可是費了我好大的勁才搞定的。

Android呼叫微信原生分享介面進入微信分享介面返回不了!

今天測試員發現一個bug,分享停在微信介面,返回不了了,我擦!我就慢慢排除bug······首先圖片符合微信分享限制的大public static final int THUMB_LENGTH_L

Android FrameWork框架

Android的四層架構相比大家都很清楚,老生常談的說一下分別為:Linux2.6核心層,核心庫層,應用框架層,應用層。我今天重點

Zookeeper工作機制應用場景安裝

Zookeeper 檔案系統 = 儲存資料 通知機制 = 監聽 功能     1、儲存資料:儲存叢集中每臺機器都關心的資料     2、監聽 zookeeper工作機制     基於觀察者模式設計的

abap中選擇螢幕上新增按鈕按鈕上新增文字和圖片新增響應事件

**選擇螢幕SELECTION-SCREEN BEGIN OF BLOCK main WITH FRAME TITLE TEXT-001.PARAMETERS:p_matnr LIKE mara-matnr OBLIGATORY,           p_werks LIKE

mysql新增索引的方法max()函式的優化

我有已kills表,裡面有五十多萬條資料,記錄的是西遊群英打怪的時間和數量。 現在我想查單日打怪最多的記錄是多少。 我就寫一個 select max(kills) from kills 時間是多少呢? 掃描了五十多萬條記錄後,這個資料就出來了,歷時0.123S。 這只是一個

java 日期如何新增減少一天如何新增減少一月如何新增減少小時如何新增減少分鐘

java日期增加或減少天,當days為負數時為減少的天數,當days為正整數時為增加的天數public static Date addDays(Date date, int days) { Cal

android原始碼下加入替換鈴聲檔案設定預設鈴聲

系統鈴聲檔案的路徑在frameworks/base/data/sounds資料夾 有四個主要資料夾alarms ,notifications,ringtones,effects,分別對應系統的鬧鐘鈴聲,通知鈴聲,來電鈴聲,音效 如果需要新增鈴聲檔案,只需把鈴聲放入對應的資料