千里马Android Framework实战开发-am命令怎么编译生成及native程序与java程序的binder通信实战

107 篇文章 12 订阅
23 篇文章 0 订阅

csdn在线学习课程,课程咨询答疑和新课信息:QQ交流群:422901085进行课程讨论

android跨进程通信实战视频课程(加群获取优惠)

千里马Android Framework实战开发-am命令怎么编译生成及native程序与java程序的binder通信实战

背景:

大家如果看到binder通信native和java,肯定以为java是apk,但本节课就非要带大家了解点android中其实除了apk这种java程序,还有一类jar的运行程序,这样让大家就可以收获更多的知识点。当然大家学习完了觉得还想去apk上实验当然没有问题,不过这里唯一要提醒大家就是可能apk直接与native binder通信可能会有selinux问题,所以,可以setenforce 0 来关闭selinux,或者自己去配对应selinux权限既可以

1、am命令的生成

首先得找到对应am的代码路径及mk
在这里插入图片描述
路径在:frameworks/base/cmds/am 其实其他的一些命令也在cmds路径下
看看它的mk

# Copyright 2008 The Android Open Source Project
#
LOCAL_PATH:= $(call my-dir)

#生成am.jar
include $(CLEAR_VARS)
#jar的源文件就是src
LOCAL_SRC_FILES := \
    $(call all-java-files-under, src) \
    $(call all-proto-files-under, proto)
LOCAL_MODULE := am
LOCAL_PROTOC_OPTIMIZE_TYPE := stream
include $(BUILD_JAVA_LIBRARY)

#生成am可执行文件
include $(CLEAR_VARS)
LOCAL_MODULE := am
#依赖一个am文件,这个am目录已经有了
LOCAL_SRC_FILES := am
LOCAL_MODULE_CLASS := EXECUTABLES #生成am可执行文件
LOCAL_MODULE_TAGS := optional
include $(BUILD_PREBUILT)


include $(CLEAR_VARS)
LOCAL_SRC_FILES := \
    $(call all-proto-files-under, proto)
LOCAL_MODULE := libinstrumentation
LOCAL_PROTOC_OPTIMIZE_TYPE := full
LOCAL_EXPORT_C_INCLUDE_DIRS := \
    $(call intermediates-dir-for,STATIC_LIBRARIES,libinstrumentation,HOST,,,)/proto/$(LOCAL_PATH)/proto
include $(BUILD_HOST_STATIC_LIBRARY)

am文件:


if [ "$1" != "instrument" ] ; then
    cmd activity "$@"
else
    base=/system
    export CLASSPATH=$base/framework/am.jar#指定CLASSPATH,不然没办法运行下面类
    exec app_process $base/bin com.android.commands.am.Am "$@"
fi

它主要有2个目标:一个生成am .jar,这个在system/framework/下面
一个生成am 的可执行文件 am在system/bin下面

2、课程的java程序这次也来使用类是am这种,通过命令来运行一个java程序

课程程序分为2个部分,一个c++写的server程序,另一个java写的client程序,当然你也可以反过来,不过就给你当作业啦。
c++的server具体程序就不给大家贴了,因为和上节课基本一样,课程中会有源码给大家,主要给大家贴一下java程序的部分,其实大部分都是参考am来写的
在这里插入图片描述
一样有一个Android.mk和ClinetDemo的shell脚本程序,这个基本完全参考am

src部分ClientDemo:


package com.test.frameworkBinder;

import android.os.IBinder;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.Parcel;
import android.util.Log;
public class ClientDemo {
  private static final java.lang.String DESCRIPTOR = "sample.hello";
  private static final int FUNC_CALLFUNCTION = 1;
  public static void main(String[] args) throws RemoteException {
    testService();
  }
  public static void testService(){
    Log.i("ClentDemo", "Client main ");
    Parcel _data = Parcel.obtain();
    Parcel _reply = Parcel.obtain();
    IBinder b = ServiceManager.getService(DESCRIPTOR);
    try {
      _data.writeInterfaceToken(DESCRIPTOR);
      b.transact(FUNC_CALLFUNCTION, _data, _reply, 0);
      _reply.readException();
      _reply.readInt();
    } catch (RemoteException e) {
      e.printStackTrace();
    } finally {
      _reply.recycle();
      _data.recycle();
    }
  }
}

这里基本和上节课的c++的client一样步骤 1、通过服务名字servicemanager获取IBinder对象
2、构造对应的Parcel,调用binder的transact方法
3、读取返回结果

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值