前言
在Android开发framework层的时候,如果我们想增加自定义的功能,这个时候又不想改动系统原有的组件,那通常我们可以增加自己服务成为系统服务,用自己服务统一来进行管理。
Kernel: v4.4.126
Device: rk3399
Platform Version: Android 7.1
步骤
例如:
-
在frameworks/base/services/core/java/com/android/server下创建自定义文件夹,例如cat,然后在cat文件夹下创建CatManagerService.java。
package com.android.server.cat; import android.content.Context; import android.util.Log; import com.android.server.SystemService; public final class CatManagerService extends SystemService { private static final String TAG = "CatManagerService"; final CatManagerServiceImpl mImpl; public CatManagerService(Context context) { super(context); mImpl = new CatManagerServiceImpl(context); } @Override public void onStart() { Log.i(TAG, "Registering service " + Context.CAT_SERVICE); publishBinderService(Context.CAT_SERVICE, mImpl); } @Override public void onBootPhase(int phase) { if (phase == SystemService.PHASE_SYSTEM_SERVICES_READY) { } } }
创建CatManagerServiceImpl.java
package com.android.server.cat; import android.util.Log; import android.os.ICatManager; import android.content.Context; import android.os.HandlerThread; import android.content.Intent; import android.os.RemoteException; //上面导入的import android.os.ICatManager;现在还没有,在下面创建 public class CatManagerServiceImpl extends ICatManager.Stub { private static final String TAG = "CatManagerServiceImpl"; public CatManagerServiceImpl(Context context) { Log.d(TAG,"ICatManagerService is create"); } public void test() { Log.d(TAG, "test."); } }
-
创建frameworks/base/core/java/android/os/ICatManager.aidl
package android.os; interface ICatManager { void test(); }
-
创建frameworks/base/core/java/android/app/CatManager.java
package android.app; import android.util.Log; import android.os.ICatManager; import android.content.Context; import android.os.RemoteException; import android.os.Build; public final class CatManager { private static String TAG = "CatManager"; ICatManager mService; private Context context; public CatManager(Context ctx, ICatManager service) { mService = service; context = ctx; } public void test() { try { mService.test(); } catch (RemoteException e) { } } }
-
在frameworks/base/Android.mk原有的LOCAL_SRC_FILES中添加
LOCAL_SRC_FILES += \ core/java/android/os/ICatManager.aidl
-
在frameworks/base/core/java/android/content/Context.java中添加
public static final String CAT_SERVICE = "cat_service";
-
在framework/base/core/java/android/app/SystemServiceRegistry.java中添加
import android.os.ICatManager; import android.app.CatManager; //此类中有大量的服务注册,放在其他服务附近即可 registerService(Context.CAT_SERVICE, CatManager.class, new CachedServiceFetcher<CatManager>() { @Override public CatManager createService(ContextImpl ctx) { IBinder b = ServiceManager.getService(Context.CAT_SERVICE); ICatManager service = ICatManager.Stub.asInterface(b); return new CatManager(ctx, service); }});
-
frameworks/base/services/java/com/android/server/SystemServer.java
private static final String CAT_SERVICE_CLASS = "com.android.server.cat.CatManagerService"; //放在其他服务附近就可以 mSystemServiceManager.startService(CAT_SERVICE_CLASS);
编译报错?
需要:make update-api
如何调用?
调用很简单:
CatManager catManager = (CatManager) getSystemService("cat_service");
if(catManager != null)
catManager.test();
else
Log.e(TAG, "catManager is null.");
AndroidStudio中编译不过?找不到CatManager?
那是因为AndroidStudio使用的sdk中没有你定义的CatManger,可以有二种选择:
- 将编译源码的时候out/target/common/obj/JAVA_LIBRARIES/framework_intermediates/classes.jar放进libs下面调整它的优先级比原本sdk优先级高,就编译过去了。详情请参考我的另一篇博客:AndroidStudio将导入jar包优先级调到比sdk中的高方法及遇到的问题
- 可以在工程目录下创建CatManager.java,包名、类名、方法要与在framework中定义的一模一样,方法可以提供空实现,也就是提供一个空壳,AndroidStuido会用这个空壳编译过去,然后运行的时候就会调用平台里的方法。
- 将在工程目录下创建CatManager.java做成jar包,这样其他的项目也可以使用。
转载请注明出处:http://www.wolfnx.com/2020/03/19/Add-Service-to-System
作者 : wolfnx
邮箱 : wolfnx@outlook.com
邮箱2 : lostnx@gmail.com