自定义Android系统服务

一、概述
本文将讲述如何在Framework层增加系统服务,提供给其他进程访问。在讲述之前,读者应该了解所有的系统服务运行在SystemServer进程中,并将对应的IBinder对象注册在ServiceManger进程中。

二、编码思路
1、在framework/base/core/android/os/下定义AppLockServiceTest.aidl接口
2、在framework/base/service定义AppLockServiceTest.java
3、修改framework/base/Android.mk文件
4、在SystemService中启动服务,并注册在ServiceManager中。

1、AppLockServiceTest.aidl类

// IAppLockService.aidl
package android.os;
import android.os.IAppLockCallback;

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

interface IAppLockServiceTest {
    /**
     * Demonstrates some basic types that you can use as parameters
     * and return values in AIDL.
     */
    //给应用上锁或解锁
    void setLocked(String pkg,boolean isLocked);

    //判断应用是否上锁
    boolean isLocked(String pkg);
}

2、创建AppLockServiceTest服务

package com.android.server;

import android.app.Activity;
import android.app.ActivityManager;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.os.IAppLockServiceTest;
import android.os.IBinder;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.util.Log;
import android.util.Slog;
import android.widget.Toast;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class AppLockServiceTest extends SystemService {

    private Map map = new HashMap();
    private Object object = new Object();
    private Context mContext;

    public AppLockServiceTest(Context context) {
        super(context);
        mContext = context;

    }
    private final IBinder mService = new IAppLockServiceTest.Stub() {

        @Override
        public boolean isLocked(String pkg) throws RemoteException {

            synchronized (object) {
                return isAppLocked(pkg);
            }
        }

        @Override
        public void setLocked(String pkg, boolean isLocked) throws RemoteException {
            synchronized (object) {
                setAppLocked(pkg, isLocked);
            }
        }


    };

    @Override
    public void onStart() {
        ServiceManager.addService(Context.APP_LOCK_SERVICE_TEST, mService);
    }

    /**
     * 设置锁状态
     *
     * @param pkg
     * @param isLocked
     */
    private void setAppLocked(String pkg, boolean isLocked) {
        //判断包名是否为空
        checkNull(pkg);
        Log.d("应用锁服务:", "修改的应用包名 : " + pkg + "是否被锁 " + isLocked);
        if (map.get(pkg) != null) {
            map.remove(pkg);
            map.put(pkg, isLocked);
        }


    }
    private boolean isAppLocked(String pkg) {
        checkNull(pkg);

        Log.d("应用锁服务:", "修改的应用包名 : " + pkg);

        if (map.get(pkg)) {
            return true;
        } else {
            return false;
        }
    }

    private void checkNull(String pkg) {
        if (pkg == null || "".equals(pkg)) {
            throw new IllegalArgumentException("Illegal package name");
        }
    }
}
在此类中,我们需要实现aidl的服务端,并创建对应的Binder对象注册在ServiceManager中,其中ServiceManager.java也是一个binder类,这个类中处理了Service的Binder对象的缓存,并与ServiceManager进程通信。注意在Context中定义一个代表我们服务的字符串标志。
 //start, add by zl topwise for app_lock
    public static final String APP_LOCK_SERVICE_TEST = "app_lock_service_test";
    //end, add by zl topwise for app_lock

3、修改Android.mk文件

 core/java/android/os/IPowerManager.aidl \
 core/java/android/os/IAppLockService.aidl \
 core/java/android/os/IAppLockServiceTest.aidl \
 core/java/android/os/IAppLockCallback.aidl \
 core/java/android/os/IStudentModeManageService.aidl\
 把定义好的aidl文件加入到里面

4、在SystemService进程中启动该服务

 //start, add by zl topwise for app Protect
        if (android.os.TopwiseConfig.SUPPORT_PRIVATE_PROTECT) {
            try {
                mSystemServiceManager.startService(AppLockService.class);
                mSystemServiceManager.startService(AppLockServiceTest.class);
            } catch (Throwable e) {
                reportWtf("starting PrivateProtect Service", e);
            }
        }
        //end, start, add by zl topwise for app Protect
到此我们服务端已经定义完了,可用模块编译下framework/base 和 framework/base/service/这俩个模块。

5、客户端获取服务

客户端获取服务只需要通过ServiceManger.getSerivce()方法获取到对应服务的IBinder对象转化成接口类型的对象就可以访问到服务端的所有方法了。

例:IAppLockServiceTest.Stub.asInterface(ServiceManager.getService(Context.APP_LOCK_SERVICE_TEST));

其中通过context.getSystemService("")的方法获取对应的ServiceManager对象也是在SystemServiceRegistry类中缓存了对应Binder对象的代理。

你可能感兴趣的:(android基础)