前言
在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);
如何调用?
调用很简单:
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