Android从驱动层到应用程序层的通信

来源:互联网 发布:apache linux下载文件 编辑:程序博客网 时间:2024/05/01 00:14

研究一下Android从驱动层到应用层的通信机制是很有必要的,如新增加一个硬件并在应用层去控制硬件都需要用到,目的是知道需要增加哪些东西删改哪些东西而让系统依然工作正常。

总共需要增改的有四个东西,驱动、服务(jnijava)、应用apk

采用的方式是在驱动层写个字符型设备驱动其中内含一个定时器,每隔2秒发送一个uevent事件并改变sys下相关文件的内容,然后建立一个服务去读取文件并通过intent向上层广播,最后在应用程序层接收此事件并在TextView中显示出来

 

一、驱动层

kernel/drivers/char/uevent_test/test.c

Kconfig

Makefile

驱动层与服务层之间用到的通信机制是sys文件系统的uevent机制,涉及的函数有以下几个

 

sys文件系统下建立一个类

class_create(THIS_MODULE, "uevent_timer");

在类里建立一个设备

device_create(uevent_timer_class, NULL, UEVENT_TIMER_MAJOR,NULL, "uevent_timer_status");

在设备目录下建立一个文件

device_create(uevent_timer_class, NULL, UEVENT_TIMER_MAJOR,NULL, "uevent_timer_status");

在本项目中建立的目录文件是/sys/class/uevent_timer/uevent_timer_status/status

 

注意思在使用kobject_uevent函数发送uevent事件时需要建立一个工作队列来发送,否则会在发送过程中内核死掉。

INIT_WORK(&uevent_timer_dev->changed_work,timer_change_work);

通过schedule_work(&uevent_timer_dev->changed_work);来调用timer_change_work函数,在此函数中利用

kobject_uevent(&uevent_timer_dev->clsdev->kobj,KOBJ_CHANGE);

来发送uevent事件.

当上层读取file时会调用uevent_timer_show_attrs函数来更新及显示文件内容

当上层写入file时会调用 uevent_timer_store_attrs函数来更新及写入文件内容

 

二、服务层

新建以下两个文件

frameworks/base/services/jni/com_android_server_UeventTimerService.cppframeworks/base/services/jni/onload.cpp

frameworks/base/services/java/com/android/server/UeventTimerService.java

frameworks/base/services/java/com/android/server/SystemServer.java

         (1)JNI

                  JNIjava调用本地的接口,JNI主要工作是打开驱动所创建的file并将其值读出来,

         static intreadFromFile(const char* path, char* buf, size_t size)函数中读取值

        

 

 

使用

static JNINativeMethod sMethods[] = {

            /*name, signature, funcPtr */

             {"native_update","()V", (void*)android_server_UeventTimerService_update},   

};注册一个函数native_update以供服务的java层调用

修改onload.cpp,在其中加入

intregister_android_server_UeventTimerService(JNIEnv* env);JNI_OnLoad中加入

register_android_server_UeventTimerService(JNIEnv*env);在加载时启动此服务

 

2java

建立一个类

Class UeventTimerService extendsBinder{

         Privateint mUeventTimerStatus;

         PublicUeventTimerService(){/

mUEventObserver.startObserving("SUBSYSTEM=uevent_timer");

};//此函数中调用开始服务

private UEventObservermUEventObserver = new UEventObserver() {

         @Override

         public void onUEvent(UEventObserver.UEvent event) {

             update();

             sendIntent();

         }

 };建立一个服务并重写onUEvent函数

private native voidnative_update();

private synchronized finalvoid update() {

         native_update();//调用jni中注册的native_update()函数

}

private final voidsendIntent() {

         Intent intent = new Intent("uevent_timer_status");//启动广播

         intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);//建立一个发送

         intent.putExtra("status", mUeventTimerStatus);//发送变量

         ActivityManagerNative.broadcastStickyIntent(intent, null);//向上层广播

}

SystemServer.java中加入

UeventTimerServiceueventtimer = null;

try catch块中加入

ueventtimer = newUeventTimerService();

ServiceManager.addService("ueventtimer",ueventtimer);

三、应用层apk

         onResume(){

                   super.onResume();

                   IntentFilter filter = newIntentFilter();

 

        filter.addAction("uevent_timer_status");

        registerReceiver(mBroadcastReceiver,filter);

}

onPause(){

         super.onPause();

         unregisterReceiver(mBroadcastReceiver);

}

private BroadcastReceivermBroadcastReceiver = new BroadcastReceiver(){

       @Override

       public void onReceive(Context context, Intent intent) {

            String action = intent.getAction();

            if(action.equals("uevent_timer_status")) {

                int status =intent.getIntExtra("status", 0);

                String statusString ="";

               switch (status) {

                    case 0:

                        statusString ="counting";

                        break;

                    case 1:

                        statusString ="stop";

                        break;

                    default:

                        statusString ="unknown";

                }

               Log.i("=====My_application========",statusString);

                tv.setText(statusString);//改变textView的显示值

            }

       }

   };

AndroidManifest.xml中加入

<actionandroid:name="uevent_timer_status" />

打开监听

原创粉丝点击