自己动手从零开始写一个完整的android Service

简介: 自己动手从零开始写一个完整的android Service             Android service对于从事android开发的人,不管是底层开发人员还是应用开发人员都不是一个陌生的对象。

自己动手从零开始写一个完整的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;
	
	@Override
	public 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产品服务!


 

目录
相关文章
|
4月前
|
XML Java Android开发
Android Studio App开发之服务Service的讲解及实战(包括启动和停止,绑定与解绑,推送服务到前台实现音乐播放器,附源码)
Android Studio App开发之服务Service的讲解及实战(包括启动和停止,绑定与解绑,推送服务到前台实现音乐播放器,附源码)
98 0
|
2月前
|
数据可视化 Android开发
[Android 四大组件] --- Service
[Android 四大组件] --- Service
24 0
|
8月前
|
Android开发
Android手写占位式插件化框架之Activity通信、Service通信和BroadcastReceiver通信(一)
Android手写占位式插件化框架之Activity通信、Service通信和BroadcastReceiver通信
68 0
|
8月前
|
Android开发
Android 四大组件之Service的详解
Android 四大组件之Service的详解
80 0
|
8月前
|
数据库 Android开发 开发者
Android 开发四大组件(Activity、Service、Broadcast Receiver、Content Provider)
Android 开发四大组件(Activity、Service、Broadcast Receiver、Content Provider)
104 0
|
10月前
|
XML 传感器 缓存
Android:四大组件之 Service
Service 是 Android 中实现程序后台运行的解决方案,它非常适合用于去执行那些不需要和用户交互而且还要求长期运行的任务。但不要被“后台”二字迷惑,Service 默认并不会运行在子线程中,它也不会运行在一个独立的进程中,它同样执行在 UI 线程中,因此,不要在 Service 中执行耗时的操作,除非你在 Service 中创建子线程来完成耗时操作。
93 0
Android:四大组件之 Service
|
Java 调度 Android开发
android Service中Thread.sleep不精确
android Service中Thread.sleep不精确
137 0
|
Android开发
深入剖析Android四大组件(二)——Service服务之启动与绑定(二)
深入剖析Android四大组件(二)——Service服务之启动与绑定(二)
214 1
深入剖析Android四大组件(二)——Service服务之启动与绑定(二)
|
Android开发
深入剖析Android四大组件(二)——Service服务之启动与绑定(一)
深入剖析Android四大组件(二)——Service服务之启动与绑定(一)
164 0
深入剖析Android四大组件(二)——Service服务之启动与绑定(一)
|
编解码 缓存 Android开发
深入剖析Android四大组件(五)——并行执行的Service
深入剖析Android四大组件(五)——并行执行的Service
84 0