Android应用层到Framework到HAL再到驱动层的整个流程分析 您所在的位置:网站首页 安卓5层 Android应用层到Framework到HAL再到驱动层的整个流程分析

Android应用层到Framework到HAL再到驱动层的整个流程分析

2024-07-02 20:12| 来源: 网络整理| 查看: 265

本篇参考老罗的实例进行总结。老罗写六篇,层层嵌套,他告诉了我们流程,但没有说编程思想,所以,即使知道怎么做也很快会忘调,因此打算总结下每层之间是怎么调用的,以加深印象。不对细节进行探讨。细节可以参见老罗的blog:http://blog.csdn.net/luoshengyang/article/details/6567257

老罗的分析是从驱动到应用层的,但我想从app开发者的角度去反思这个流程,我反过来说吧。

Tips:老罗这个例子,太多hello相关的函数和类了,要区分的话,目录是个好东西!要注意当前说的层在哪个目录!我会把它加粗。

Tips2:封装是理清各层关系的关键,除了驱动,上面的app/framework(JNI)/HAL层主要工作都是封装。

应用层->Framwork层->HAL层 问题一.作为app开发者,如果我想调用硬件驱动的一个功能,我要怎么做?

1.先按常规办法,做好UI界面。可以IDE中调试好。

2.在事件触发函数里,调用SystemService,获取底层的服务,并把它转化为aidl接口

[javascript] view plain copy import android.os.IHelloService;   public class Hello extends Activity implements OnClickListener {       private IHelloService helloService = null;       .....      public void onCreat(Bundle savedInstanceState){       .....          helloService = IHelloService.Stub.asInterface( ServiceManager.getService("hello"));        .....     }   }   3.在onClick函数里调用该接口,让service执行目标功能。 [cpp] view plain copy public void onClick(View v) {      .....     helloService.setVal(val);     .....   }   问题二.如果要在SDK源码里测试,有什么要注意?——Android.mk

1.在SDK里,aidl文件,会产生在out/target/common/obj目录下,自己去搜吧(参照http://blog.csdn.net/xzongyuan/article/details/38119551)

2.如果你在Eclipse上写aidl文件,会产生在apk源码目录的gen下。因此,如果要把源码复制到SDK,要把gen目录删掉,不然这个目录会生成aidl相关的java文件,会和第一步生成的产生冲突。

3.在源码目录新增加Android.mk,这样SDK编译的时候,才会把该源码编译进去。例如:可以把自己的测试代码放到:/package/experimental/hello 下,并在该目录新增Android.mk,这点可以查看兄弟目录的文件结构。

Android.mk的文件内容如下:

LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE_TAGS := optional LOCAL_SRC_FILES := $(call all-subdir-java-files) LOCAL_PACKAGE_NAME := Hello include $(BUILD_PACKAGE) 问题三.要怎样设计一个IHelloService供上层调用?

1.进入到frameworks/base/core/java/android/os目录,新增IHelloService.aidl接口定义文件:

      USER-NAME@MACHINE-NAME:~/Android$ cd frameworks/base/core/java/android/os

      USER-NAME@MACHINE-NAME:~/Android/frameworks/base/core/java/android/os$ vi IHelloService.aidl

      IHelloService.aidl定义了IHelloService接口:

[cpp] view plain copy package android.os;           interface IHelloService {         void setVal(int val);         int getVal();     }     2.为啥必须是os文件夹下呢?android下级目录还有很多其它目录,我猜测应该都可以放进去的。只需要你改下

/framework/base下的Android.mk,可见Android.mk在SDK里面是很重要的,它是个组织文件的Makefile。例子:

返回到frameworks/base目录,打开Android.mk文件,修改LOCAL_SRC_FILES变量的值,增加IHelloService.aidl源文件

[cpp] view plain copy LOCAL_SRC_FILES += /         ....................................................................         core/java/android/os/IVibratorService.aidl /         core/java/android/os/IHelloService.aidl /         core/java/android/service/urlrenderer/IUrlRendererService.aidl /         .....................................................................   编译后,会生成 IHelloService.java(就是上面提到的/out/target/common下的目录),这个文件的IHelloService接口,会实现一个Stub子接口,该子接口提供了一个函数, [cpp] view plain copy public static com.styleflying.AIDL.forActivity asInterface(android.os.IBinder obj)     {        if ((obj==null)) {        return null;     }    

这个函数就是前面提到的供Activity用的asInterface了。

activity里的使用方法如下,把具体的服务调出来了:

[cpp] view plain copy helloService = IHelloService.Stub.asInterface( ServiceManager.getService("hello"));    3.这个IHelloService对象应该放在哪里?

定一个类,继承它,并封装它的函数,最后把它注册到ServiceManager就行了

进入到frameworks/base/services/java/com/android/server目录,新增HelloService.java文件:

[cpp] view plain copy package com.android.server;     import android.content.Context;     import android.os.IHelloService;     import android.util.Slog;     public class HelloService extends IHelloService.Stub {         private static final String TAG = "HelloService";         /*封装IHelloService接口的函数*/       HelloService() {               init_native();         }         public void setVal(int val) {             setVal_native(val);         }            public int getVal() {             return getVal_native();         }                  private static native boolean init_native();         


【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有