自己动手从零开始写一个完整的android Service
来源:互联网 发布:江小白淘宝 编辑:程序博客网 时间:2024/05/23 01:15
自己动手从零开始写一个完整的android Service
Android service对于从事android开发的人,不管是底层开发人员还是应用开发人员都不是一个陌生的对象。笔者就是由于长期主要从事的都是底层开发,对framework下的service以前只是略知一二,知道上面有audio service、light service、power service等等service,这些service都是要通过层层调用call到驱动的,发挥着重要的作用。大家描写service是一头不知疲倦的牛。因此作为android驱动工程师,还是得深入了解一下service的运作。
以前很多时候,我们都是在现有的service基础上增加一下小功能,这不足以让我们完整的了解一个service的完整框架。笔者最近做的一个项目,需要增加一个功能模块,这个功能要在lanucher、setting等 apk应用中都要调用,而在现有的service上不大好去添加,因此决定从零开始自己动手写一个service,下面笔者就抛砖引玉大概描述一下过程。
/*****************************************************************************************************/
声明:本博内容均由http://blog.csdn.net/sundesheng125原创,转载请注明出处,谢谢!
/*****************************************************************************************************/
第一步:实现driver。Driver也就是service最终需要去控制的对象,这一步就不详细去说了,不管是写成字符型设备文件还块设备,或者是伪文件系统/proc的普通文件,只要能满足这种交互的目的就行。笔者那个字符型设备文件跟/proc普通文件的交互方法都做过,现在还是以字符型设备驱动为例吧。
第二步:android用户空间调用drvier。在android架构中,这个大任当然是hal层当仁不让的。在hal层就要按照hw_module_t的架构去写。代码如下:
static int open_my_driver_device (const struct hw_module_t * module, char const * name, struct hw_device_t ** device){struct mydriver_context_t * dev = (struct mydriver_context_t *)malloc(sizeof(struct mydriver_context_t));memset(dev, 0, sizeof(struct mydriver_context_t));int fd = open("/dev/my_driver", O_RDONLY);if (fd < 0) {LOGE("failed to open my driver device!");return -1;}dev->fd = fd;dev->device.common.tag = HARDWARE_DEVICE_TAG;dev->device.common.version = 0;dev->device.common.module = (struct hw_module *)module;dev->device.common.close = (int (*)(struct hw_device_t*))close_my_driver_device;dev->device.get_acc_state = (int (*)(struct mydriver_device_t *, int *))get_ my_driver _state;*device = (struct hw_device_t *)dev;return 0;}static struct hw_module_methods_t my_driver_module_methods = {.open = open_my_driver_device,};const struct hw_module_t HAL_MODULE_INFO_SYM = {.tag = HARDWARE_MODULE_TAG,.version_major = 1,.version_minor = 0,.id = MY_DRIVER_HARDWARE_MODULE_ID,.name = "edsam my driver Module",.author = "edsam.",.methods = &my_driver_module_methods,};
第三步:可以直接去写JNI了。当然如果不是第二步也能合在这里一起写,但是这样代码架构就没那么完整。 JNI怎么写就去查一下相关文档。JNI代码放置/frameworks/base/services/jni/下:
static jint init_native(JNIEnv * env, jobject clazz){int err;hw_module_t * module;struct my_driver_device_t * device;device = NULL;err = hw_get_module(MY_DRIVER_HARDWARE_MODULE_ID (hw_module_t const **)&module);if (err == 0) {hw_device_t * hw_device;err = module->methods->open(module, NULL, &hw_device);if (err != 0) {LOGE("module open fail!");return 0;} else {device = (struct my_driver_device_t *)hw_device;}}return (jint)device;}static jint get_my_driver_status_native (JNIEnv * env, jobject clazz, int ptr){struct my_driver_device_t * device = (struct my_driver_device_t *)ptr;int state = 0;if (device) {device->get_my_driver_status(device, &state);}return state;}static JNINativeMethod method_table[] = {{"init_native", "()I", (void *)init_native },{"finalize_native", "(I)V", (void *)finalize_native },{"get_earphones_status_native", "(I)I", (void *)get_my_driver_status_native },};int register_android_server_MyDriverService(JNIEnv * env) {return jniRegisterNativeMethods(env,"com/android/server/MyDriverService",method_table,NELEM(method_table));}
第四步:注册service。在/frameworks/base/services/jni/目录下有个onload.cpp的文件添加register_android_server_MyDriverService (env);调用。
第五步:java层添加service代码。在/frameworks/base/services/java/com/android/server/目录下添加。
package com.android.server;import android.os.RemoteException;import com.android.internal.os.IMyDriverService;public class MyDriverService extends IMyDriverService.Stub {private static final String TAG = "MyDriverService";private static final boolean DEBUG = false;@Overridepublic int getMyDriverState() throws RemoteException {return get_my_driver_status_native (mNativePointer);}public MyDriverService() {mNativePointer = init_native();}protected void finalize() throws Throwable {finalize_native(mNativePointer);super.finalize();}private static native int init_native();private static native void finalize_native(int ptr);private static native int getMyDriverState_native(int ptr);private int mNativePointer;}
第六步:增加AIDL定义。文件放置/frameworks/base/core/java/com/android/internal/os/下,增加IMydriverService.aldl内容如下:
package com.android.internal.os; interface IMyDriverService { int getMyDriverState ();}
上面的aidl文件编译添加到/frameworks/base/Android.mk中定义的LOCAL_SRC_FILES中。
第七步:在systemserver里注册。frameworks/base/services/java/com/android/server/SystemServer.java中的run方法里增加:
mydriverService = newMyDriverService();
ServiceManager.addService(Context.MY_DRIVER_SERVICE, mydriverService);
第八步:产生Manager对象。在/frameworks/base/core/java/android/app/下添加有个MyDriverManager.java,
package android.app;import android.content.Context;import android.os.RemoteException;import android.os.ServiceManager;import android.util.Slog;import com.android.internal.os.IMyDriverService;public class MyDriverManager {private static final String TAG = "MyDriverManager";private static final boolean DEBUG = false;private IMyDriverService mService = null;public MyDriverManager() {}private synchronized IMyDriverService getService() {if (mService == null) {mService = IMyDriverService.Stub.asInterface(ServiceManager.getService(Context.MY_DRIVER_SERVICE));if (mService == null) {Slog.w(TAG, "warning : no MyDriverService ");}}return mService;}public int getMyDriverStatus() {try {final IMyDriverService svc = getService();if (svc != null) {return svc. getMyDriverState();} else {Slog.e(TAG, "error : IMyDriverService not exist!");throw new RuntimeException("IMyDriverService not exist!");}} catch (RemoteException e) {Slog.e(TAG, "error : getEarPhonesStatus remote error!");throw new RuntimeException(e);}}}}
在/frameworks/base/core/java/android/content/Context中定义MY_DRIVER_SERVICE字符串,在/frameworks/base/core/java/android/app/ContextImpl.java中:
registerService(MY_DRIVER_SERVICE, new ServiceFetcher() { public Object getService(ContextImpl ctx) { return new MY_DRIVER_Manager(); } });
第九步:在编译的时候执行make update-api。就会把新的api加入到api/current.txt文件中去。
最后一步:当然是在需要的地方调用了。
MY_DRIVER_Manager mydriverService = (MY_DRIVER_Manager)getSystemService(Context. MY_DRIVER_Manager);if (mydriverService!= null) {mydriverService. getMyDriverStatus ();}}
通过以上步骤,完整编译一下系统,应该service能正常工作起来了。加一个service还是挺麻烦的,上层的互联关系比较多。
没有高深的理论介绍,只有简单的实践步骤,比较详细的介绍了一个service的来龙去脉,有兴趣就自己动手实践一下,相信会有收获的。Service在开发中用得非常广泛,号称四大组件之一,真的是名不虚传!征服它,驾驭它,为我所用,为做出好的android产品服务!
- 自己动手从零开始写一个完整的android Service
- 自己动手从零开始写一个完整的android Service
- 一个完整的android Service
- Android 6.0一个完整的native service
- 自己动手写一个android手机上的一键锁屏程序
- 自己动手写一个测试Android事件传递机制的demo
- 自己动手写一个轻量级的Android网络请求框架
- 自己动手写一个轻量级的Android网络请求框架
- 从零开始怎么写android native service?
- 从零开始怎么写android native service?
- 从零开始,自己动手写Java虚拟机
- 自己动手写一个Android Studio插件
- 自己动手写一个Android Studio插件
- 自己动手写一个RSS的阅读器
- 自己动手写一个简单的bootloader
- 自己动手写一个Makefile
- 自己动手写一个栈
- 自己动手写一个WIDGET
- 解锁system用户及修改密码
- 构造函数不能声明为虚函数,析构函数可以声明为虚函数,而且有时是必须声明为虚函数
- C/C++中printf和C++中cout的输出格式
- ##连接字符
- 自己写的php简单的mvc框架
- 自己动手从零开始写一个完整的android Service
- Android学习--第一个程序
- 如何去写 Android init.rc
- 包含动态分配成员的类 应提供拷贝构造函数,并重载"="赋值操作符
- 等着我吧
- icc和idbc的用法两点
- oracle 取出30%-60%的数据
- 软件测试的14种类
- mac环境下cmake命令行编译总结