Android自定义系统服务

作者: 飞飞飞_Android | 来源:发表于2017-06-01 19:32 被阅读0次

公司项目需要,自定义了一套服务以供多个配置软件的适配需求,这篇文章记录当初学习自定义服务时的代码和理解。

Aidl接口文件

位置:frameworks/base/core/java/android/os/IFeiService.aidl

package android.os;
// create by weiyuanfei
interface IFeiService {
    void setVal (String key , String val);
    String getVal (String val);
}    

接口很简单,定义了2个方法供后续使用,。
另外,需要在frameworks/base/Android.mk里加入IFeiService.aidl

LOCAL_SRC_FILES += \
core/java/android/os/IFeiService.aidl \ 

使用过aidl的都知道,编译后aidl文件会生成一个同名的java文件,这是aidl技术的核心代码,是binder技术java层的实现。

Aidl生成的java文件

位置:/out/target/common/obj/JAVA_LIBRARIES/framework_intermediates/src/core/java/android/os/IFeiService.java

/*
 * This file is auto-generated.  DO NOT MODIFY.
 * Original file: frameworks/base/core/java/android/os/IFeiService.aidl
 */
package android.os;
// create by weiyuanfei

public interface IFeiService extends android.os.IInterface {
    /**
     * Local-side IPC implementation stub class.
     */
    public static abstract class Stub extends android.os.Binder implements android.os.IFeiService {
        private static final java.lang.String DESCRIPTOR = "android.os.IFeiService";

        /**
         * Construct the stub at attach it to the interface.
         */
        public Stub() {
            this.attachInterface(this, DESCRIPTOR);
        }

        /**
         * Cast an IBinder object into an android.os.IFeiService interface,
         * generating a proxy if needed.
         */
        public static android.os.IFeiService asInterface(android.os.IBinder obj) {
            if ((obj == null)) {
                return null;
            }
            android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);
            if (((iin != null) && (iin instanceof android.os.IFeiService))) {
                return ((android.os.IFeiService) iin);
            }
            return new android.os.IFeiService.Stub.Proxy(obj);
        }

        @Override
        public android.os.IBinder asBinder() {
            return this;
        }

        @Override
        public boolean onTransact(int code, android.os.Parcel data, android.os.Parcel reply, int flags) throws android.os.RemoteException {
            switch (code) {
                case INTERFACE_TRANSACTION: {
                    reply.writeString(DESCRIPTOR);
                    return true;
                }
                case TRANSACTION_setVal: {
                    data.enforceInterface(DESCRIPTOR);
                    java.lang.String _arg0;
                    _arg0 = data.readString();
                    java.lang.String _arg1;
                    _arg1 = data.readString();
                    this.setVal(_arg0, _arg1);
                    reply.writeNoException();
                    return true;
                }
                case TRANSACTION_getVal: {
                    data.enforceInterface(DESCRIPTOR);
                    java.lang.String _arg0;
                    _arg0 = data.readString();
                    java.lang.String _result = this.getVal(_arg0);
                    reply.writeNoException();
                    reply.writeString(_result);
                    return true;
                }
            }
            return super.onTransact(code, data, reply, flags);
        }

        private static class Proxy implements android.os.IFeiService {
            private android.os.IBinder mRemote;

            Proxy(android.os.IBinder remote) {
                mRemote = remote;
            }

            @Override
            public android.os.IBinder asBinder() {
                return mRemote;
            }

            public java.lang.String getInterfaceDescriptor() {
                return DESCRIPTOR;
            }

            @Override
            public void setVal(java.lang.String key, java.lang.String val) throws android.os.RemoteException {
                android.os.Parcel _data = android.os.Parcel.obtain();
                android.os.Parcel _reply = android.os.Parcel.obtain();
                try {
                    _data.writeInterfaceToken(DESCRIPTOR);
                    _data.writeString(key);
                    _data.writeString(val);
                    mRemote.transact(Stub.TRANSACTION_setVal, _data, _reply, 0);
                    _reply.readException();
                } finally {
                    _reply.recycle();
                    _data.recycle();
                }
            }

            @Override
            public java.lang.String getVal(java.lang.String val) throws android.os.RemoteException {
                android.os.Parcel _data = android.os.Parcel.obtain();
                android.os.Parcel _reply = android.os.Parcel.obtain();
                java.lang.String _result;
                try {
                    _data.writeInterfaceToken(DESCRIPTOR);
                    _data.writeString(val);
                    mRemote.transact(Stub.TRANSACTION_getVal, _data, _reply, 0);
                    _reply.readException();
                    _result = _reply.readString();
                } finally {
                    _reply.recycle();
                    _data.recycle();
                }
                return _result;
            }
        }

        static final int TRANSACTION_setVal = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0);
        static final int TRANSACTION_getVal = (android.os.IBinder.FIRST_CALL_TRANSACTION + 1);
    }

    public void setVal(java.lang.String key, java.lang.String val) throws android.os.RemoteException;

    public java.lang.String getVal(java.lang.String val) throws android.os.RemoteException;
}

服务的定义

位置:frameworks/base/services/core/java/com/android/server/FeiService.java

package com.android.server;

import android.content.Context;
import android.os.IFeiService;
import android.os.RemoteException;

import java.util.HashMap;

/**
 * Created by weiyuanfei on 17-5-27.
 */
public class FeiService extends IFeiService.Stub {

    private static HashMap<String, String> map = new HashMap<String, String>();

    public FeiService(Context context) {

    }

    @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);
    }

}

FeiService实现之前定义的两个方法,我们需要看到的是FeiService继承了IFeiService.Stub。

定义Service的封装接口Manager

package android.app;

import android.content.Context;
import android.os.IFeiService;
import android.util.Log;

/**
 * Created by weiyuanfei on 17-5-27.
 */
public class FeiManager {
    IFeiService mService;

    public FeiManager(Context ctx, IFeiService service){
        mService=service;
    }

    public void setVal(String key,String value){
        try{
            mService.setVal(key,value);
        }catch(Exception e){
            Log.e("FeiManager",e.toString());
            e.printStackTrace();
        }

    }
    public String getVal(String key){
        try{
            return mService.getVal(key);
        }catch(Exception e){
            Log.e("FeiManager",e.toString());
            e.printStackTrace();
        }
        return null;
    }
}

封装了之前在服务端实现的两个方法,注意到方法的调用者是IFeiService,实际上在后续注册服务的时候,我们可以看到并把它理解为服务的本地代理prox。

服务的注册

代码位置:/frameworks/base/services/java/com/android/server/SystemServer.java

 private void startOtherServices() {
           . .....
            FeiService mFeiService = null;
            .....
            traceBeginAndSlog("StartFeiService");
            mFeiService = new FeiService(context);
            ServiceManager.addService("fei",mFeiService);
            Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);

systemserver是启动各个系统服务的地方,系统服务会add到servicemanager,由其管理。

代码位置:frameworks/base/core/java/android/app/SystemServiceRegistry.java

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

定义了getsystemservice获得manager的位置

服务名字的定义

frameworks/base/core/java/android/content/Context.java

public static final String Fei_Service = "fei";

SELINUX权限添加

system/sepolicy/service.te

type fei_service, system_api_service, system_server_service, service_manager_type;

system/sepolicy/service_contexts

fei                                       u:object_r:fei_service:s0

需要添加的代码到这里就结束了,编译前需要先 make update-api,然后正常编译即可.

Case验证

    FeiManager feimanager;
    private static String TAG = "feifei";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        feimanager = (FeiManager) getSystemService("fei");
        feimanager.setVal("fan1","lizhi");
        feimanager.setVal("fan2","eason");
        String test = feimanager.getVal("fan2");
        Log.d(TAG, "test = " + test);
        
    }

简单定义了一个activity,调用系统服务FeiManager的setVal和getVal方法,成功的话可以看到打印正常的log.

参考链接:http://gityuan.com/2016/10/01/system_service_common/(两种系统服务的注册方式)

相关文章

网友评论

    本文标题:Android自定义系统服务

    本文链接:https://www.haomeiwen.com/subject/thqjfxtx.html