首页 > 编程知识 正文

AndroidQ 打通应用层到HAL层应用层实现,打通基础研究到应用

时间:2023-05-05 01:09:44 阅读:261630 作者:1132

前几篇文章陆陆续续实现了HAL,HIDL,JNI,AIDL服务,现在只差最后一步,应用层的实现我们就可以打通应用层到HAL的整个调用流程了,话不多说,上代码

应用层的实现相对比较简单,在Android Studio中进行开发,写完之后拷贝到源码packages/apps下进行编译就行了,在packages/apps下创建HelloDemo目录,将开发好的文件拷贝过来,看看目录结构:

很简单的一个应用,把主要文件源码贴出来一下:

MainActivity.java package com.android.hello;import android.app.Activity;import android.os.Bundle;import android.util.Log;import android.view.View;import android.widget.Button;import android.widget.EditText;import android.os.IBinder;import android.app.IHelloService;import android.os.ServiceManager;import android.os.RemoteException;import android.view.Window;public class MainActivity extends Activity implements View.OnClickListener { private Button button; private EditText editText1; private EditText editText2; private EditText editText3; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); requestWindowFeature(Window.FEATURE_NO_TITLE); setContentView(R.layout.activity_main); button = findViewById(R.id.button); editText1 = findViewById(R.id.edit_text1); editText2 = findViewById(R.id.edit_text2); editText3 = findViewById(R.id.edit_text3); button.setOnClickListener(this); } @Override public void onClick(View v) { IHelloService helloService = getHelloService(); if(helloService == null){ Log.d("dongjiao","onClick...faile to get helloService..."); return; } Log.d("dongjiao","onClick...success to get helloService..."); int a = Integer.parseInt(editText1.getText().toString()); int b = Integer.parseInt(editText2.getText().toString()); try{ int total = helloService.add(a,b); editText3.setText(total+""); Toast.makeText(this,"total = :"+total,Toast.LENGTH_LONG).show(); }catch(RemoteException e){ Log.d("dongjiao","RemoteException = :"+e); } } private IHelloService getHelloService(){ IBinder b = ServiceManager.getService("helloService"); IHelloService helloService = IHelloService.Stub.asInterface(b); return helloService; }} activity_main.xml <?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical" tools:context=".MainActivity"> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal"> <EditText android:id="@+id/edit_text1" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:hint="请输入" android:inputType="number" /> <EditText android:id="@+id/edit_text2" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:hint="请输入" android:inputType="number" /> <EditText android:id="@+id/edit_text3" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:hint="0" /> </LinearLayout> <Button android:id="@+id/button" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="click" /></LinearLayout> AndroidManifest.xml <?xml version="1.0" encoding="utf-8"?><manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.android.hello"> <application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="HelloDemo" android:roundIcon="@drawable/ic_launcher" android:supportsRtl="true" android:theme="@android:style/Theme.Material.Light"> <activity android:name=".MainActivity"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application></manifest> Android.bp android_app { name: "HelloDemo", srcs: ["src/**/*.java"], platform_apis: true,}

这个应用功能就是点击Button时,获取前一篇文章实现的HelloService服务,然后调用HelloService的add方法,这个方法会通过JNI到HIDL服务中

接着进行编译,mmm packages/apps/HelloDemo


编译成功后将这个APK push到手机中
adb push out/target/product/TOKYO_TF_arm64/system/app/HelloDemo/HelloDemo.apk /system/app/HelloDemo
重启手机,这个APK界面就这样:

功能很简单,三个EditText和一个Button,前两个EditText用来接收两个加数,后一个EditText接收它们的和,通过Button调用HelloService的add方法,HelloService的add方法通过JNI到native层再到HIDL调用addition_hidl函数,最终到HAL中调用additionTest函数实现两个数相加,然后返回给APP,
我们最终目的就是如此

我在HAL,HIDL,JNI,AIDL,APP各层都添加了log,来测试一下:

关闭SELinux权限,adb shell setenforce 0启动HIDL service
杀掉system_server让AIDL服务HelloService重新启动,HelloService启动的同时会通过JNI获取HIDL服务,HIDL服务中又会获取HAL

如下是AIDL服务HelloService启动的log输出

log中HAL,HIDL,JNI,AIDL每层都已经成功输出log,说明我们在SystemService中启动HelloService之后到HAL的流程已经打通了(HAL,HIDL,JNI,AIDL可参考前几篇文章实现),再测试一下APP的功能,输入两个数,点击CLICK按钮


没有报错,成功计算出total值,看看log输出:

log也很清晰,从APP的click开始,到AIDL,JNI,HIDL,HAL
功能虽简单,麻雀虽小,五脏俱全,到这里我们这个系列的文章已经结束,从应用层到HAL的整体流程已经了解,其实Android系统的整体流程就是这样的,只不过它每一层包含复杂的逻辑,但是架构都类似,上层到底层,层层调用,一个APP就可以简单操纵硬件,一层一层提供接口

了解系统调用流程对我们理解Android系统的帮助是非常大的

这几篇文章的源码已经上传github,执行如下命令即可获取:
git clone https://github.com/tdj520/-HAL.git

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。