frameworks中增加自定义服务使其也成为系统服务

前言

在Android开发framework层的时候,如果我们想增加自定义的功能,这个时候又不想改动系统原有的组件,那通常我们可以增加自己服务成为系统服务,用自己服务统一来进行管理。

Kernel: v4.4.126
Device: rk3399
Platform Version: Android 7.1

步骤

例如:

  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.");
     }
     }
    
  2. 创建frameworks/base/core/java/android/os/ICatManager.aidl

     package android.os;
     interface ICatManager {
     	void test();
     }
    
  3. 创建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) {
         
     	}
     }
     }
    
  4. 在frameworks/base/Android.mk原有的LOCAL_SRC_FILES中添加

     LOCAL_SRC_FILES += \
     core/java/android/os/ICatManager.aidl
    
  5. 在frameworks/base/core/java/android/content/Context.java中添加

     public static final String CAT_SERVICE = "cat_service";
    
  6. 在framework/base/core/java/android/app/SystemServiceRegistry.java中添加

     import android.os.ICatManager;
     import android.app.CatManager;
    
     //此类中有大量的服务注册,放在其他服务附近即可
     registerService(Context.CAT_SERVICE, CatManager.class,
             new CachedServiceFetcher() {
         @Override
         public CatManager createService(ContextImpl ctx) {
              IBinder b = ServiceManager.getService(Context.CAT_SERVICE);
              ICatManager service = ICatManager.Stub.asInterface(b);
              return new CatManager(ctx, service);
         }});
    
  7. 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,可以有二种选择:

  1. 将编译源码的时候out/target/common/obj/JAVA_LIBRARIES/framework_intermediates/classes.jar放进libs下面调整它的优先级比原本sdk优先级高,就编译过去了。详情请参考我的另一篇博客:AndroidStudio将导入jar包优先级调到比sdk中的高方法及遇到的问题
  2. 可以在工程目录下创建CatManager.java,包名、类名、方法要与在framework中定义的一模一样,方法可以提供空实现,也就是提供一个空壳,AndroidStuido会用这个空壳编译过去,然后运行的时候就会调用平台里的方法。
  3. 将在工程目录下创建CatManager.java做成jar包,这样其他的项目也可以使用。

转载请注明出处:http://www.wolfnx.com/2020/03/19/Add-Service-to-System

作者 : wolfnx
邮箱 : [email protected]
邮箱2 : [email protected]

你可能感兴趣的:(Android,Framework,rk3399,Android,Application,android,java,framework,移动开发)