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

Posted Android高级知识分享官

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了千里马Android Framework实战开发-am命令怎么编译生成及native程序与java程序的binder通信实战相关的知识,希望对你有一定的参考价值。

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、读取返回结果

以上是关于千里马Android Framework实战开发-am命令怎么编译生成及native程序与java程序的binder通信实战的主要内容,如果未能解决你的问题,请参考以下文章

千里马Android Framework实战开发-native程序之间binder通信实战案例分析

千里马Android Framework实战开发-native程序之间binder通信实战案例分析

千里马Android Framework实战开发-跨进程通信专题博客总结

千里马Android Framework实战开发-跨进程通信专题课表介绍

千里马android framework实战开发-binder驱动之oneway导致的transaction failed

千里马android framework实战开发-binder驱动之oneway导致的transaction failed