Ahao's Technical Blog Ahao's Technical Blog
首页
  • 001.基础篇
  • 002.玩转AOSP篇
  • 003.学穿Binder篇
  • 004.基础组件篇
  • 005.系统启动过程分析
  • 006.Hal开发入门与实践
  • 007.显示系统
关于
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

阿豪讲Framework

不积跬步无以至千里
首页
  • 001.基础篇
  • 002.玩转AOSP篇
  • 003.学穿Binder篇
  • 004.基础组件篇
  • 005.系统启动过程分析
  • 006.Hal开发入门与实践
  • 007.显示系统
关于
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • 基础篇

  • 玩转AOSP篇

  • 学穿Binder篇

    • 000.Binder 专题导学 —— 如何深入掌握 Binder
    • 001.学习 Binder 的预备知识
    • 002.Binder 基本原理
    • 003.Binder 程序示例之 C 语言篇
    • 004.Binder 服务注册过程情景分析之 C 语言篇
    • 005.Binder 服务获取与使用过程情景分析之C语言篇
    • 006.Android Binder 驱动框架设计与分析
    • 007.Binder 驱动情景分析之 ServiceManager 启动过程
    • 008.Binder 驱动情景分析之服务注册过程
    • 009.Binder 驱动情景分析之服务获取与使用过程
    • 010.Binder 程序示例之 C++ 篇
    • 011.Binder C++ 程序分析之主要类解析
    • 012.Binder 服务注册过程情景分析之 C++ 篇
    • 013.Binder 服务获取与使用过程情景分析之C++篇
    • 014.Binder 程序示例之 aidl-cpp 篇
    • 015.添加 Android Native 系统服务
    • 016.添加 Native 系统服务回调
    • 017.Binder 程序示例之 Java 篇
    • 018.Binder Java 层初始化
    • 019.Binder Java 层服务注册过程分析
    • 020.Binder Java 层服务获取与使用过程分析
    • 021.添加 Java 系统服务
    • 022.Android Java 系统服务框架与第三方 App 使用自定义 Java 系统服务
    • 023.添加 Java 系统服务回调
    • 024.AIDL 数据类型详解之 Java 篇
    • 025.AIDL 数据类型详解之 C++ 篇
    • 026.Java 调用 Native 服务
    • 027.Native 调用 Java Binder 服务
    • 028.AIDL 关键字 in out inout oneway 解析
    • 029.Binder 驱动 Debug 入门指南
    • 030.Binder 匿名服务源码分析
    • 031.Binder 中的 Parcel 数据结构分析(C++)
    • 032.Binder 中的 Parcel 数据结构分析(Java)
    • 033.Binder 多线程情景分析
    • 034.Binder 线程池溢出问题
    • 035.Binder 代理对象泄露问题分析
    • 036.Binder 死亡通知情景分析
    • 037.Binder 异常处理机制
    • 038.Binder 系统源码演进
    • 039.Binder 面试题汇总
    • 补充——LocalService
  • 基础组件篇

  • 系统启动过程分析

  • Hal开发入门与实践

  • 显示系统

  • Framework
  • 学穿Binder篇
阿豪
2023-08-03

023.添加 Java 系统服务回调

本文在Binder 程序示例之 Java 篇 (opens new window) 的基础上修改,来显示如何添加 Java 系统服务回调,为了保证重点突出和过程简洁清晰,不会演示如何集成 Java 系统服务到系统中。这部分内容请参考添加 Java 系统服务 (opens new window)和Android Java 系统服务框架与第三方 App 使用自定义 Java 系统服务 (opens new window)。

首先我们在Binder 程序示例之 Java 篇 (opens new window)完成的源码的基础上添加 ICallback.aidl 文件,添加完成后整体文件结构如下:

BinderJavaDemo/
└── com 
    └── yuandaima
        ├── Android.bp
        ├── Client.java
        ├── HelloService.java
        ├── ICallback.aidl
        ├── IHelloService.aidl
        └── Server.java
1
2
3
4
5
6
7
8
9

其中 ICallback.aidl 内容如下:

package com.yuandaima;

interface ICallback {
    void onMessage(String message);
}
1
2
3
4
5

接着修改 IHelloService.aidl 添加服务注册接口:

package com.yuandaima;
import com.yuandaima.ICallback;

interface IHelloService
{
	void sayhello();
	int sayhello_to(String name);
	void registerCallback(int pid, ICallback callback);
}
1
2
3
4
5
6
7
8
9

接下里我们编译 aidl 文件:

# 系统源码目录下
source build/envsetup.sh
# 选择合适的 product
lunch rice14-eng

# 进入到项目目录下
cd device/jelly/rice14/BinderJavaDemo/com/yuandaima
aidl ICallback.aidl
# -I 用于指定我们的在哪里查找 import
aidl -I .  IHelloService.aidl
1
2
3
4
5
6
7
8
9
10

编译完成后,项目整体目录如下:

BinderJavaDemo/
└── com
    └── yuandaima
        ├── Android.bp
        ├── Client.java
        ├── HelloService.java
        ├── ICallback.aidl
        ├── ICallback.java
        ├── IHelloService.aidl
        ├── IHelloService.java
        └── Server.java
1
2
3
4
5
6
7
8
9
10
11

接下来我们修改 Binder 服务端类,主要工作是添加注册回调函数:

//HelloService.java
package com.yuandaima;

import android.util.Log;

public class HelloService extends IHelloService.Stub {

    private ICallback mCallback;
    private static final String TAG = "HelloService";
    private int cnt1 = 0;
    private int cnt2 = 0;

    public void sayhello() throws android.os.RemoteException {
        cnt1++;
        Log.i(TAG, "sayhello : cnt = "+cnt1);
        //调用注册的回调接口
        if(mCallback != null) {
            mCallback.onMessage("message from server");
        }
    }
    
    public int sayhello_to(java.lang.String name) throws android.os.RemoteException {
        cnt2++;
        Log.i(TAG, "sayhello_to "+name+" : cnt = "+cnt2);
        return cnt2;
    }

    //添加注册回调函数
    public void registerCallback(int pid, ICallback callback) {
        Log.d(TAG, "register callback receive");
        mCallback = callback;
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33

接着修改客户端, 主要定义回调接口以及注册回调接口:

//Client.java
package com.yuandaima;

import android.util.Log;
import android.os.ServiceManager;

import android.os.RemoteException;

import android.os.IBinder;

public class Client {

    private static final String TAG = "BinderClient";

    public static void main(String args[])
    {
        
        /* 1. getService */
        IBinder binder = ServiceManager.getService("hello");
        
        if (binder == null)
        {
            Log.i(TAG, "can not get hello service");
            return;
        }

        IHelloService svr = IHelloService.Stub.asInterface(binder);
        
        ICallback callback = new ICallback.Stub() {

            @Override
            public void onMessage(String message) throws RemoteException {
                Log.d(TAG, "onMessage:" + message);
            }
        };
        try {
            svr.registerCallback(android.os.Process.myPid(), callback);
        } catch (RemoteException e) {
            Log.d(TAG, "register callback fail");
            e.printStackTrace();
        }
       

        try {
	        svr.sayhello();
	        Log.i(TAG, "call sayhello");
        } catch (Exception e) {

        }
           
        try {
	        int cnt = svr.sayhello_to("hello");
	    
	        Log.i(TAG, "call sayhello_to " + " : cnt = " + cnt);
        } catch (Exception e) {
            System.out.println("call sayhello_to , err :"+e);
            Log.i(TAG, "call sayhello_to , err : "+e);
        }
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60

然后修改 Android.bp:

java_library {
    name: "BinderClient",
    installable: true,
    srcs: [ "Client.java", 
            "HelloService.java", 
            "IHelloService.java",
            "ICallback.java" ],
}

java_library {
    name: "BinderServer",
    installable: true,
    srcs: [ "Server.java", 
            "HelloService.java", 
            "IHelloService.java",
            "ICallback.java" ],
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

最后我们就可以运行我们的程序了:

# 在项目目录下执行
mm
# 在源码目录下执行
# 将 jar 包 push 到虚拟机上
cd out/target/product/generic_x86_64/system/framework
adb push BinderClient.jar /data/local/tmp
adb push BinderServer.jar /data/local/tmp

# 进入模拟器 shell 环境
adb shell

# 执行 java 程序
export CLASSPATH=/data/local/tmp/BinderClient.jar:/data/local/tmp/BinderServer.jar
# 启动服务端
app_process /data/local/tmp  com.yuandaima.Server
# 启动客户端
app_process /data/local/tmp com.yuandaima.Client 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

查看 log:

logcat | grep BinderClient
1

可以看出我们的 Client 端已经收到回调消息了,证明我们的回调执行成功了。

022.Android Java 系统服务框架与第三方 App 使用自定义 Java 系统服务
024.AIDL 数据类型详解之 Java 篇

← 022.Android Java 系统服务框架与第三方 App 使用自定义 Java 系统服务 024.AIDL 数据类型详解之 Java 篇→

最近更新
01
如何调试 SurfaceFlinger
10-05
02
SurfaceFlinger 概述
10-05
03
HWC 接口分析
10-05
更多文章>
Theme by Vdoing | Copyright © 2020-2025 AHao Framework | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式