自定义Android系统服务
16lz
2021-01-26
一、概述
本文将讲述如何在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.aidlpackage android.os;import android.os.IAppLockCallback;// Declare any non-default types here with import statementsinterface 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对象的代理。
更多相关文章
- tcping测试服务器TCP端口
- Android(安卓)socket通信,读去中文汉字乱码问题解决。
- Android试题(二)
- 【Android】关于FLAG_ACTIVITY_NEW_TASK 和 taskAffinity
- Android里监视数据库的变化[转]
- Android--AIDL学习
- Android(安卓)Context完全解析
- Android(安卓)使用Socket进行网络通信
- Android之网络开发详解