Android系统源码分析-进程间通信机制binder(三):从framework层到Native层

app安卓逆向之native层代码静态分析基础 app安卓逆向之Native层代码静态分析基础Native层代码静态分析1.背景分析2.概述3.开始3.1 ARM指令3.2 IDA基本使用方法3.3 Java层调用Native层方法原理3.4 Native层代码的修改3.5 So文件替换4.总结 Native层代码静态分析 1.背景分析 在安卓逆向的过程当中会遇到以下场景 经过上一阶段的Java层代码静态分析以及动态调试,发现加密参数的生成方法调用了Native层方法 经过对Native层代码分析后修改对应代码,替换原so文件发现app运行异常 针对 阅读详情

1.内容简介:

Android Binder机制既提供IPC通信,又具有RPC功能,这样,对应上层应用程序提供了非常友好的API调用接口。实际上,为了支持支撑这一机制,从Android Framework到Native再到Binder Driver,是一个非常复杂的业务支撑系统。本节主要介绍在这个过程中,Binder在框架层的相关组件。

 Binder源码分析系列文章:

Android系统源码分析-进程间通信机制binder(一):守护进程servicemanager

Android系统源码分析-进程间通信机制binder(二):binder内存映射

Android系统源码分析-进程间通信机制binder(三):从framework层到Native层

Android系统源码分析-进程间通信机制binder(四):从Native层到Driver层

2.Framework Binder架构:

 从进程的角度,先看一下简化的Framework Binder结构:

 说明:

Manager:属于Android Framework层,被用户App调用,它又调用Server的stub(通过代理proxy)。例如,ActivityManager,PackageManager...等。它运行在App所在的进程中。

Server:属于Android Framework层,向上提供服务,向下与servicemanager进行交互。

servicemanager:即服务管理,是一个守护进程。

Binder Driver:binder驱动。

Framework Binder相关组件:

为了支撑上述架构,Android提供了一系列的组件,如下图:

说明:

整个框架分为如下几层:

JAVA,JNI,C++,C层,这与Android系统框架是一致的;

1)JAVA层:

Service: 提供服务的组件,例如,ActivityManagerService,PackageMangerService。

Client:这里的client指的是Service的调用者,例如, ActivityManager,PackageManager。

SeiviceManager:提供service的管理,包括注册,获取service等;它的最大的特点是:它本身也是一个service,遵循C/S架构;同时,它又是其它service的管理类。用户要想访问到其它service,必须通过ServiceManager来实现。

parcel和Parcelable:用于Binder通信信息的数据结构;

IInterface:该接口是binder服务接口的父接口;

IBinder:Java层的IBinder类,提供了transact方法来调用远程服务;

Binder: 实现了IBinder接口,封装了JNI的实现。Java层Binder服务的基类;

IServiceManager:用于ServiceManager管理的基类;

2)JNI层:承上启下,进行各个组件的衔接(java层到Native层)。native即C/C++代码,jni使得程序员可以在C/C++端调用Java代码,也可以在Java端调用C/C++代码。下面这段代码展示了“如何进行java与native的衔接”:

以下代码截取自android_util_Binder.cpp:

static const JNINativeMethod gBinderMethods[] = {
     /* name, signature, funcPtr */
    { "getCallingPid", "()I", (void*)android_os_Binder_getCallingPid },
    { "getCallingUid", "()I", (void*)android_os_Binder_getCallingUid },
    { "getOrigCallingUidNative", "()I", (void*)android_os_Binder_getOrigCallingUid },
    { "clearCallingIdentity", "()J", (void*)android_os_Binder_clearCallingIdentity },
    { "restoreCallingIdentity", "(J)V", (void*)android_os_Binder_restoreCallingIdentity },
    { "setThreadStrictModePolicy", "(I)V", (void*)android_os_Binder_setThreadStrictModePolicy },
    { "getThreadStrictModePolicy", "()I", (void*)android_os_Binder_getThreadStrictModePolicy },
    { "flushPendingCommands", "()V", (void*)android_os_Binder_flushPendingCommands },
    { "init", "()V", (void*)android_os_Binder_init },
    { "destroy", "()V", (void*)android_os_Binder_destroy }
};

以下代码截取自android_os_Parcel.cpp注册的方法:

static const JNINativeMethod gParcelMethods[] = {
    {"nativeDataSize",            "(I)I", (void*)android_os_Parcel_dataSize},
    {"nativeDataAvail",           "(I)I", (void*)android_os_Parcel_dataAvail},
    {"nativeDataPosition",        "(I)I", (void*)android_os_Parcel_dataPosition},
    {"nativeDataCapacity",        "(I)I", (void*)android_os_Parcel_dataCapacity},
    {"nativeSetDataSize",         "(II)V", (void*)android_os_Parcel_setDataSize},
    {"nativeSetDataPosition",     "(II)V", (void*)android_os_Parcel_setDataPosition},
    {"nativeSetDataCapacity",     "(II)V", (void*)android_os_Parcel_setDataCapacity},

    {"nativePushAllowFds",        "(IZ)Z", (void*)android_os_Parcel_pushAllowFds},
    {"nativeRestoreAllowFds",     "(IZ)V", (void*)android_os_Parcel_restoreAllowFds},

    {"nativeWriteByteArray",      "(I[BII)V", (void*)android_os_Parcel_writeNative},
    {"nativeWriteInt",            "(II)V", (void*)android_os_Parcel_writeInt},
    {"nativeWriteLong",           "(IJ)V", (void*)android_os_Parcel_writeLong},
    {"nativeWriteFloat",          "(IF)V", (void*)android_os_Parcel_writeFloat},
    {"nativeWriteDouble",         "(ID)V", (void*)android_os_Parcel_writeDouble},
    {"nativeWriteString",         "(ILjava/lang/String;)V", (void*)android_os_Parcel_writeString},
    {"nativeWriteStrongBinder",   "(ILandroid/os/IBinder;)V", (void*)android_os_Parcel_writeStrongBinder},
    {"nativeWriteFileDescriptor", "(ILjava/io/FileDescriptor;)V", (void*)android_os_Parcel_writeFileDescriptor},

    {"nativeCreateByteArray",     "(I)[B", (void*)android_os_Parcel_createByteArray},
    {"nativeReadInt",             "(I)I", (void*)android_os_Parcel_readInt},
    {"nativeReadLong",            "(I)J", (void*)android_os_Parcel_readLong},
    {"nativeReadFloat",           "(I)F", (void*)android_os_Parcel_readFloat},
    {"nativeReadDouble",          "(I)D", (void*)android_os_Parcel_readDouble},
    {"nativeReadString",          "(I)Ljava/lang/String;", (void*)android_os_Parcel_readString},
    {"nativeReadStrongBinder",    "(I)Landroid/os/IBinder;", (void*)android_os_Parcel_readStrongBinder},
    {"nativeReadFileDescriptor",  "(I)Ljava/io/FileDescriptor;", (void*)android_os_Parcel_readFileDescriptor},

    {"openFileDescriptor",        "(Ljava/lang/String;I)Ljava/io/FileDescriptor;", (void*)android_os_Parcel_openFileDescriptor},
    {"dupFileDescriptor",         "(Ljava/io/FileDescriptor;)Ljava/io/FileDescriptor;", (void*)android_os_Parcel_dupFileDescriptor},
    {"closeFileDescriptor",       "(Ljava/io/FileDescriptor;)V", (void*)android_os_Parcel_closeFileDescriptor},
    {"clearFileDescriptor",       "(Ljava/io/FileDescriptor;)V", (void*)android_os_Parcel_clearFileDescriptor},

    {"nativeCreate",              "()I", (void*)android_os_Parcel_create},
    {"nativeFreeBuffer",          "(I)V", (void*)android_os_Parcel_freeBuffer},
    {"nativeDestroy",             "(I)V", (void*)android_os_Parcel_destroy},

    {"nativeMarshall",            "(I)[B", (void*)android_os_Parcel_marshall},
    {"nativeUnmarshall",          "(I[BII)V", (void*)android_os_Parcel_unmarshall},
    {"nativeAppendFrom",          "(IIII)V", (void*)android_os_Parcel_appendFrom},
    {"nativeHasFileDescriptors",  "(I)Z", (void*)android_os_Parcel_hasFileDescriptors},
    {"nativeWriteInterfaceToken", "(ILjava/lang/String;)V", (void*)android_os_Parcel_writeInterfaceToken},
    {"nativeEnforceInterface",    "(ILjava/lang/String;)V", (void*)android_os_Parcel_enforceInterface},
};

3)C++层(Native层):用于实现在java层定义的各个API,以及与下面的内核空间进行交互;

4)C层:这里主要指的是Android Binder Driver,相关内容,请参考前两节博文。

3. PackageManager Java层相关类图:

在App开始时,经常用到诸如ActivityManager,PackageManager...等组件(或者称为服务)。

本节以PackageManager来进行说明,各个组件的实现,相关类图如下:

相关代码:

frameworks/base/core/java/android/os/IBinder.java

frameworks/base/core/java/android/os/Binder.java

frameworks/base/core/java/android/os/IInterface.java

Client端:
frameworks/base/core/java/android/content/pm/PackageManager.java
frameworks/base/core/java/android/app/ApplicationPackageManager.java

Service端:
frameworks/base/core/java/android/content/pm/IPackageManager.aidl
out/target/common/obj/JAVA_LIBRARIES/framework_intermediates/src/core/java/android/content/pm/IPackageManager.java
frameworks/base/services/core/java/com/android/server/pm/PackageManagerService.java

 这里,重点介绍一下AIDL。

AIDL:AIDL是Android中IPC(Inter-Process Communication)方式中的一种,AIDL是Android Interface definition language的缩写,AIDL的作用是,通过AIDL,可以在自己的APP里绑定一个其他APP的service,从而实现一个APP可以访问另外一个APP提供的服务。

从源码的角度来看,AIDL是以aidl为后缀的文件;在进行编译的时候,系统会将aidl编译为java文件。

可以看到:IPackageManager.接口就被定义在了IPackageManager.aidl文件中。

原始的IPackageManager.aidl文件如下:

interface IPackageManager {
    PackageInfo getPackageInfo(String packageName, int flags, int userId);
    int getPackageUid(String packageName, int userId);
    int[] getPackageGids(String packageName);
    
    String[] currentToCanonicalPackageNames(in String[] names);
    String[] canonicalToCurrentPackageNames(in String[] names);

    PermissionInfo getPermissionInfo(String name, int flags);
    
    List<PermissionInfo> queryPermissionsByGroup(String group, int flags);
    
    PermissionGroupInfo getPermissionGroupInfo(String name, int flags);
......
}

经过编译后的对应的java文件:

public interface IPackageManager extends android.os.IInterface{
    //IPackageManager中定义的类Stub,Stub集成自Binder,并实现IPackageManager.aidl中定义的接口
    public static abstract class Stub extends android.os.Binder implements android.content.pm.IPackageManager{
    ...
    public static android.content.pm.IPackageManager asInterface(android.os.IBinder obj){
        if ((obj==null)) {
            return null;
        }
        android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);
        //如果是当前进程,返回的是IPackageManager本身
        if (((iin!=null)&&(iin instanceof android.content.pm.IPackageManager))) {
            return ((android.content.pm.IPackageManager)iin);
        }
        //不是当前进程,返回的是代理类
        return new android.content.pm.IPackageManager.Stub.Proxy(obj);
    }

    @Override 
    public boolean onTransact(int code, android.os.Parcel data, android.os.Parcel reply, int flags) throws android.os.RemoteException {
        ...
        switch (code) {
        case TRANSACTION_getPackageInfo:{
        data.enforceInterface(DESCRIPTOR);
        java.lang.String _arg0;
        _arg0 = data.readString();
        int _arg1;
        _arg1 = data.readInt();
        int _arg2;
        _arg2 = data.readInt();
        android.content.pm.PackageInfo _result = this.getPackageInfo(_arg0, _arg1, _arg2);
        reply.writeNoException();
        if ((_result!=null)) {
        reply.writeInt(1);
        _result.writeToParcel(reply, android.os.Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
        ...//类似的case方法很多,这里只举例case TRANSACTION_getPackageInfo,其他代码省略
        }
        ...
    }
    ...
    //类Stub中定义的代理类Proxy,Proxy中代理方法很多,这里同样只贴出了getPackageInfo方法
    private static class Proxy implements android.content.pm.IPackageManager {
        private android.os.IBinder mRemote;
        Proxy(android.os.IBinder remote) {
            mRemote = remote;
        }
        ...
        @Override 
        public android.content.pm.PackageInfo getPackageInfo(java.lang.String packageName, int flags, int userId) throws android.os.RemoteException{
            android.os.Parcel _data = android.os.Parcel.obtain();
            android.os.Parcel _reply = android.os.Parcel.obtain();
            android.content.pm.PackageInfo _result;
            try {
            _data.writeInterfaceToken(DESCRIPTOR);
            _data.writeString(packageName);
            _data.writeInt(flags);
            _data.writeInt(userId);
            mRemote.transact(Stub.TRANSACTION_getPackageInfo, _data, _reply, 0);
            _reply.readException();
            if ((0!=_reply.readInt())) {
                _result = android.content.pm.PackageInfo.CREATOR.createFromParcel(_reply);
            } else {
                _result = null;
            }
            }
            finally {
            _reply.recycle();
            _data.recycle();
            }
            return _result;
        }
        ...
        }
    ...
    //这里的函数就是Stub实现的接口implements android.content.pm.IPackageManager,只列出来三个,别的都省略,继承接口方法必须全部实现,否则会报错
    public void checkPackageStartable(java.lang.String packageName, int userId) throws android.os.RemoteException;
    public boolean isPackageAvailable(java.lang.String packageName, int userId) throws android.os.RemoteException;
    public android.content.pm.PackageInfo getPackageInfo(java.lang.String packageName, int flags, int userId) throws android.os.RemoteException;
    ...
}

分析:

1)IPackageManager 是继承自 android.os.IInterface的;

2)在IPackageManager中,提供了Stub抽象类。Stub类用于被外部的service来继承,这个类实现了IPackageManager.aidl中定义的接口;

3)在IPackageManager中,定义了私有静态类Proxy,Proxy类用于代理IPackageManager。外部的PackageManger调用的方法最终是由Proxy来实现的;

4)调用Proxy中的方法其实就是间接调用了Stub中的onTransact方法,在onTransact中最终调用了Stub实现的接口方法;

4. 服务注册:

我们所说的这些系统级服务,例如PackageMangerService,ActivityMangerService...等,是如何注册在servicemanager中的?本小节一起分析一下。

以PackageManagerService来看,

public static final IPackageManager main(Context context, boolean factoryTest,
            boolean onlyCore) {
        PackageManagerService m = new PackageManagerService(context, factoryTest, onlyCore);
        ServiceManager.addService("package", m);
        return m;
    }

可以看到,通过ServiceManager的addService来进行的注册。其中,第一个参数是要注册的服务的名称,这里是"package",第二个参数就是真正的服务的实例,即PackageManagerService。name和service是有对应关系的。这样,在后面使用service的时候,就可以通过name来找到具体的service了。

addService的代码:

/framework/base/core/java/android/os/ServiceManager.java

public static void addService(String name, IBinder service) {
        try {
            getIServiceManager().addService(name, service, false);
        } catch (RemoteException e) {
            Log.e(TAG, "error in addService", e);
        }
    }

分析:

1)getIServiceManager会获取到一个ServiceManager的实例,再通过这个实例去访问到ServiceManagerNative的对应的addService方法,最终调用到它的内部类ServiceManagerProxy的addService方法中。

ServiceManagerProxy的addService方法:

public void addService(String name, IBinder service, boolean allowIsolated)
            throws RemoteException {
        Parcel data = Parcel.obtain();
        Parcel reply = Parcel.obtain();
        data.writeInterfaceToken(IServiceManager.descriptor);
        data.writeString(name);
        data.writeStrongBinder(service);
        data.writeInt(allowIsolated ? 1 : 0);
        mRemote.transact(ADD_SERVICE_TRANSACTION, data, reply, 0);
        reply.recycle();
        data.recycle();
    }

通过mRemote.transact(ADD_SERVICE_TRANSACTION, data, reply, 0);去调用

ServiceManagerNative的onTransact方法。与远端的服务进行通信。

在这个方法中:

public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
    {
        try {
            switch (code) {
            case IServiceManager.GET_SERVICE_TRANSACTION: {
                data.enforceInterface(IServiceManager.descriptor);
                String name = data.readString();
                IBinder service = getService(name);
                reply.writeStrongBinder(service);
                return true;
            }
    
            case IServiceManager.CHECK_SERVICE_TRANSACTION: {
                data.enforceInterface(IServiceManager.descriptor);
                String name = data.readString();
                IBinder service = checkService(name);
                reply.writeStrongBinder(service);
                return true;
            }
    
            case IServiceManager.ADD_SERVICE_TRANSACTION: {
                data.enforceInterface(IServiceManager.descriptor);
                String name = data.readString();
                IBinder service = data.readStrongBinder();
                boolean allowIsolated = data.readInt() != 0;
                addService(name, service, allowIsolated);
                return true;
            }
    
            case IServiceManager.LIST_SERVICES_TRANSACTION: {
                data.enforceInterface(IServiceManager.descriptor);
                String[] list = listServices();
                reply.writeStringArray(list);
                return true;
            }
            
            case IServiceManager.SET_PERMISSION_CONTROLLER_TRANSACTION: {
                data.enforceInterface(IServiceManager.descriptor);
                IPermissionController controller
                        = IPermissionController.Stub.asInterface(
                                data.readStrongBinder());
                setPermissionController(controller);
                return true;
            }
            }
        } catch (RemoteException e) {
        }
        
        return false;
    }

    public IBinder asBinder()
    {
        return this;
    }
}

这里,只分析case IServiceManager.ADD_SERVICE_TRANSACTION的处理:

参数data的类型是Parcel,这个数据结构就是java与native进行数据交换的桥梁。

下面这些方法,最终都对应到native方法,这个对应关系是由android_os_Parcel.cpp完成的。如下表:

Parcel.javaandroid_os_Parcel.cpp
data.enforceInterface(IServiceManager.descriptor);
{"nativeEnforceInterface",    "(ILjava/lang/String;)V", (void*)android_os_Parcel_enforceInterface},
data.readString();
{"nativeReadString",          "(I)Ljava/lang/String;", (void*)android_os_Parcel_readString},
data.readStrongBinder();
{"nativeReadStrongBinder",    "(I)Landroid/os/IBinder;", (void*)android_os_Parcel_readStrongBinder},
data.readInt() 
{"nativeReadInt",             "(I)I", (void*)android_os_Parcel_readInt}

最终,调用到native的Parcel.cpp中对应的函数中。

例如,Parcel::enforceInterface函数的实现:

bool Parcel::enforceInterface(const String16& interface,
                              IPCThreadState* threadState) const
{
    int32_t strictPolicy = readInt32();
    if (threadState == NULL) {
        threadState = IPCThreadState::self();
    }
    if ((threadState->getLastTransactionBinderFlags() &
         IBinder::FLAG_ONEWAY) != 0) {
      // For one-way calls, the callee is running entirely
      // disconnected from the caller, so disable StrictMode entirely.
      // Not only does disk/network usage not impact the caller, but
      // there's no way to commuicate back any violations anyway.
      threadState->setStrictModePolicy(0);
    } else {
      threadState->setStrictModePolicy(strictPolicy);
    }
    const String16 str(readString16());
    if (str == interface) {
        return true;
    } else {
        ALOGW("**** enforceInterface() expected '%s' but read '%s'\n",
                String8(interface).string(), String8(str).string());
        return false;
    }
}

可见,最终是通过IPCThreadState来实现,这就涉及到native层的具体binder的实现流程了。

下一节,分析native层相关代码。

5. PackageManagerService的初始化: 

那么,PackageManagerService的main方法是什么时候被调用的呢?

答案就在system_server进程中。

system_server进程:在android系统初始化过程中,会有zygote孵化出system_server进程。可以用ps命令看到这个进程的父进程就是zygote。

在system_server中,初始化了Android Framework层的许多服务,其中,就包含PackageManagerService服务。

代码如下:

SystemServer.java的代码:

system_server初始化流程:

1)main -> call

System.loadLibrary("android_servers");
init1(args);
native public static void init1(String[] args);

2)init1 -> 通过native再调用到java层的init2

init2

3)init2:

public static final void init2() {
        Slog.i(TAG, "Entered the Android system server!");
        Thread thr = new ServerThread();
        thr.setName("android.server.ServerThread");
        thr.start();
    }

4)ServerThread中,对各个组件进行初始化:

class ServerThread extends Thread {
    @Override
    public void run() {
        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_SYSTEM_RUN,
            SystemClock.uptimeMillis());

        Looper.prepare();

        ......

        IPackageManager pm = null;
        Context context = null;
        WindowManagerService wm = null;
        BluetoothService bluetooth = null;

        ......

        try {
            Slog.i(TAG, "Entropy Mixer");
            ServiceManager.addService("entropy", new EntropyMixer());

            Slog.i(TAG, "Power Manager");
            power = new PowerManagerService();
            ServiceManager.addService(Context.POWER_SERVICE, power);

            Slog.i(TAG, "Activity Manager");
            context = ActivityManagerService.main(factoryTest);

            ......

            pm = PackageManagerService.main(context,
                    factoryTest != SystemServer.FACTORY_TEST_OFF,
                    onlyCore);
        }


    }
    ......
}

这样,PackageManagerService就初始化完成了。

6. 总结: 

PackageManager的addService的代码调用流程:

SystemServer.init1/init2->PackageManagerService.main()

->ServiceManager.addService()->IServiceManager().addService

->ServiceManagerNative.addService()->ServiceManagerProxy.addService()

->Binder.onTransact()->ServiceManagerNative.onTransact() //

case IServiceManager.ADD_SERVICE_TRANSACTION: {

->Parcel.enforceInterface()

->android_os_Parcel.cpp  //JNI

->Parcel::enforceInterface() //Parcel.cpp Native

以上,就是Binder在JAVA层相关的组件以及其在整个系统中的调用流程的基本介绍。


Android 图形架构 之二—— SurfaceFlinger 启动和连接 上一篇文章从全局来分析了Android 图形架构,本篇文章来分析SurfaceFlinger,surface的创建、图像的处理,管理设备的帧缓冲区等等,它是图像流的消费者,是本系列文章的核心 SurfaceFlinger的启动过程 启动概述 SurfaceFlinger服务是一个独立进程。 关于硬件方面的服务都在 frameworks/native/services/ 文件夹下,例如:audiomanager、powermanager、inputflinger、sensorservice、surfacefl 阅读详情

相关推荐

阿里云javasdk源码-android-native-debug:调试Android框架原生代码教程

阿里云java sdk源码 如何调试Android Native Framework 半年前写了一篇文章,介绍 ,但是只提到了Framework中Java代码的调试办法,但实际上有很多代码都是用C++实现的;无奈当时并并没有趁手的native调试工具,无法做到像Java调试那样简单直观(gdb+eclipse/ida之流虽然可以但是不完美),于是就搁置下了。 Android Studio 2.2版本带来了全新的对Android Native代码的开发以及调试支持,另外LLDB的Android调试插件也日渐成熟,我终于可以把这篇文章继续下去了!本文将带来Android Framework中native代码的调试方法。 在正式介绍如何调试之前,必须先说明一些基本的概念。调试器在调试一个可执行文件的时候,必须知道一些调试信息才能进行调试,这个调试信息可多可少(也可以没有)。最直观的比如行号信息,如果调试器知道行号信息,那么在进行调试的时候就能知道当前执行到了源代码的哪一行,如果调试器还知道对应代码的源文件在哪,那么现代IDE的调试器一般就能顺着源码带你飞了,这就是所谓的源码调试。相反,如果没

Android系统框架组成

记录了Android系统的框架组成和基本概念

qq_43160049的博客 1733

Ansys-结构动力学分析-圆柱斜齿轮模态分析学习心得

模态分析的步骤基本一直,不同点在于选择什么单元类型,模型,节点约束等 圆柱斜齿轮模态分析的难点在于圆柱斜齿轮的模型建立,和所要约束的节点的选择。 用命令流方法建立齿轮模型效率较高,当然,在ansys里建立复杂的模型实在不敢恭维,对于自下而上建模,需要知道每个关键点的坐标位置。下图是创建圆柱斜齿轮模型的命令流方式。 模型不同使用的数据也就不同了。 对于施加约束的问题这就必须要熟悉select e...

weixin_45385183的博客 1831

android 动态注册,Android studio实现动态注册Native方法

说到动态就有静态,但是静态的注册在上一篇文章中已经包含了,这里就不在赘述了,直接说动态实现。这里我们分步走。1.创建android工程选择普通工程项目命名不出意外,项目一会就建立完成。2.关联NDK打开项目配置选择NDK安装位置选择好了之后,点击OK即可。这里说一下,然后如果没有配置NDK环境变量的,需要给系统配置一下环境变量,我的是mac直接运行命令行:vim ./.bash_profile打开...

weixin_29695991的博客 459

【星火】海思HI3516C开发板实战:基于LVGL与MPP库的行车记录仪/电子显微镜方案

本文详细介绍了基于海思HI3516CV500开发板,结合LVGL图形库与海思MPP媒体处理平台,实现行车记录仪与电子显微镜方案的完整实战过程。内容涵盖从系统环境搭建、驱动配置到应用开发的全流程,重点解析了MPP视频流处理管道与LVGUI界面协同工作的核心机制,为嵌入式音视频开发提供了可复用的参考方案。

weixin_42126677的博客 160

汽车软件工程师必看:ASPICE流程实战指南(附完整产物清单)

本文为汽车软件工程师提供ASPICE流程实战指南,详细解析如何搭建合规开发环境、各阶段文档产出清单及工具链整合策略。通过实战案例和模板资源,帮助团队高效实施ASPICE标准,提升软件开发质量与效率。

weixin_29230805的博客 470

Android基础进阶 - 消息机制 之Native层分析

目录 基础知识简介 Linux eventfd事件等待/响应机制 Linux IO多路复用epoll Android消息机制Native层分析 nativeInit流程 nativePollOnce流程 nativeWake流程 资料 收获 上一篇中关于ThreadLocal的使用,遗漏了一个点:ThreadLocal的回收,使用不当会操作内存泄漏。通过上一篇的分析我们知道了ThreadLocalMap.Entry中的key时ThreadLocal的弱引用,而value需要在

yabin的专栏 921

机器学习西瓜书期末复习(2022HENU)

期末复习之机器学习 文章目录期末复习之机器学习第一章 绪论 第一章 绪论 机器学习的定义 机器学习致力于研究如何通过计算的手段,利用经验来改善系统自身的性能。 根据训练数据是否拥有标记信息,将学习任务分为监督学习和无监督学习。 监督学习 :分类和回归 线性回归、对数几率回归、决策树、支持向量机、贝叶斯分类器、神经网络 无监督学习:聚类 聚类算法: 原型聚类:(k均值,学习向量量化,高斯混合聚类);密度聚类(DBSVAN);层次聚类(AGNES)。降维。话题分析。图分

qq_46561559的博客 2万+

Android Binder框架实现之Framework层Binder服务注册过程源码分析

  Android Binder框架实现之framework层服务注册过程源码分析

IT先森 4135

Cass三角网法土方计算优化技巧:如何根据地形特点调整边界采样间距

本文深入探讨了Cass软件中三角网法(DTM法)土方计算的优化技巧,核心在于如何根据地形的复杂程度动态调整边界采样间距。针对平坦、复杂及人工构造物等不同地形特征,提供了具体的间距调整策略与精度验证方法,旨在帮助工程师在计算精度与效率间找到最佳平衡,实现精细化土方计算。

weixin_29294975的博客 523

STM32F407与AD7766实战:如何用SPI+DMA实现高速ADC数据采集(附完整代码)

本文详细介绍了如何利用STM32F407的SPI接口与DMA控制器,高效稳定地驱动24位高精度ADC芯片AD7766,实现高速连续数据采集。通过对比传统中断方式的瓶颈,阐述了SPI+DMA方案如何大幅降低CPU负载,并提供了从硬件设计、CubeMX配置到核心驱动代码的完整实战指南,帮助工程师解决高速ADC数据采集中的性能难题。

weixin_29281941的博客 187

Android Binder框架实现之Java层Binder整体框架设计

 Android Binder框架实现之Framework层Binder整体框架设计 前言   本文是Android Binder框架实现之Framework层Binder整体框架设计的起始篇,本文会重点讲述Android Binder框架Framework层整体设计思路,本系列的文章列表如下: Android Binder框架实现之Binder的设计和框架 Android Binder框架实现之Binder中的数据结构 Android Binder框架实现之Binder相关的接口和类 Android

IT先森 2897

《大数据最全面试题-Offer直通车》目录

做好这些不用担心试用期不通过:程序员入职新公司如何快速上手项目本人遇到大数据面试题和参考答案(超过1万字精华版)大数据面试英文自我介绍参考(万字长文)大数据运维应用场景面试题汇总及参考答案(持续更新)万字数据仓库面试题及参考答案数据仓库数据质量监控和处理方法最佳实践数据仓库建模方法万字详解Doris的3种数据模型详解和数据仓库每一层的模型选用大数据面试临阵磨枪不知看什么?看这份心理就有底了-大数据常用技术栈常见面试100道题最全Hive面试题2024年(2万字详解)Elasticsearch 面试题及参考答

大模型大数据攻城狮的专栏 2642

架构设计分析(三)Binder机制

来点前奏说明 当你打开这个文档的时候,你已经做好准备了,话不多说开搞。 本文以Android 9.0 版本进行分析,我是下载过源码,当然你也可以在线看源码 在线源码查看 kernel_3.18 在线源码 Android源码下载编译 9.0源码下载链接 提取码:d0ks 在此特别说明,这篇文档参考了很多文章和视频,主要自己记录一下,有些我也不明白。 产生Binder原因: ...

张彬的博客 323

UWB芯片DW3000之PDOA测向实现源码

本文详细介绍如何基于UWB芯片DW3000之PDOA测向的源码实现。

DT程序员的博客 2615

霍尼韦尔SoftMaster使用说明

霍尼韦尔SoftMaster使用说明

BInder源码分析

什么叫Binder,从不角度理解有不同含义: 从IPC层:binder是安卓跨进程通信的方式。 从安卓driver层:binder是虚拟的无聊设备。 从安卓native层:binder是创建 service manager 以及BpBinder和BBinder模型,搭建binder驱动层的桥梁。 从安卓framework层: binder是activitymanager,windmanag...

qq_36237165的博客 500

最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版

Part-E1-SDIO-Specification-Ver4.00-Final-120220.pdf:最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版,包括SDIO 接口的外设,SDIO 接口官方协议等。

王学岗移动架构(三)————Binder机制详解以及手写的实现

(一)Binder核心原理 1,先看一张图,这张图是我从网上下载下来的 从图中可以看出,上层的Binder通信是依赖于底层的。服务端提供了一个Binder对象,这个Binder对象是需要我们自定义的 。我们自定义的Binder指向的是native层的 BBinder。指向BBinder的时候需要在Service Manager中注册服务。然后调用ioctl进行数据方面的操作。这是服务端。 再看下客户端,客户端提供了一个BinderProxy。通过ioctl进行数据的交互 2,Binder是什么? 从IPC

qczg_wxg的博客 1052

IMSL CNL 7.0.0 (x86-64)Crack

IMSL CNL 7.0.0 (x86-64)Crack intel的算法库破解文件,这是C++版本的破解文件

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

Binder通讯机制,大纲和学习计划

前言 Binder,作为Android中重要的通讯机制,虽然我们可以在不理解的情况下使用,但如果能理解透彻,在以后的开发中我们将受益良多。理解Binder,完全可以看作我们在修年内功,特别是Binder机制中牵扯到Driver,Hative层,Framework层的内容,如果我们对整个流程熟悉,那么我们不仅对Android的通讯机制,而且还有整个Android框架的了解将会上一个台阶。 B

iefswang的专栏 912

安卓系统SystemServer启动源码分析

主线支线。

2601_95605400的博客 229

2022最新【Android Framework开发解密】腾讯技术团队出品,必属精品

Android Framework 开发虽然比较偏底层,圈子窄,但是能掌握一些原理的东西,可以触类旁通,往应用层发展也可以,接下来我们看看Framework知识有多重要。举几个栗子,你或许就能清楚了。 像掉帧监控,函数插装,慢函数检测,ANR 监控,启动监控,都需要对 Framework 有比较深入的了解,才能知道怎么去做监控,利用什么机制去监控,函数插桩插到哪里,反射调用该反射哪个类哪个方法哪个属性…… 目前大公司的app开发都要基于模块化、层次化、组件化、控件化的思路来设计架构,而这一切的基础都建立

Android23333的博客 361

Binder系列—开篇

一、概述 Android系统中,每个应用程序是由Android的Activity,Service,Broadcast,ContentProvider这四剑客的中一个或多个组合而成,这四剑客所涉及的多进程间的通信底层都是依赖于Binder IPC机制。例如当进程A中的Activity要向进程B中的Service通信,这便需要依赖于Binder IPC。不仅于此,整个Android系统架构中,大量采...

darling757267的专栏 250

Android 架构 JAVA API,android6.0源码分析之Camera API1.0框架简介

1、架构简介由于最近项目涉及到Camera,所以对Camera源码进行了研究,本文将分享Camera框架的基本知识。anroid6.0与5.0相比,Camera框架未曾改变,依然提供了两种API,即API1和API2,依然采用C/S的架构,而client和server两个线程间的通信依然使用IPC binder进程间通信的机制。camera架构图如下: 由图可知:在framework层中,Java...

weixin_39842029的博客 186

Android 源码分析之旅2 2 应用程序与Android System Service的进程间通信

###前言 有了上篇文章对AIDL、Binder IPC的基本认识以后,接下来将讨论一下应用程序是如何跟Android Framework进行进程间通信的。理解这一点十分重要,有助于我们深入分析源码的实现。 ###回顾 以AIDL为例子,一个完整Binder IPC上层架构需要包括: 一个Proxy,用于向服务端写数据,在Android Framework也存在用“Bp”字样来代替 一个Stub...

weixin_33720452的博客 183

Android面试6家一线大厂,这个问题是必问

年后面了六家大厂,每家都会问的一个问题就是Android的消息机制!可见Android的消息机制是多么重要! 消息机制之所以这么重要是因为Android应用程序是通过消息来驱动的,Android某种意义上也可以说成是一个以消息驱动的系统,UI、事件、生命周期都和消息处理机制息息相关,并且消息处理机制在整个Android知识体系中也是尤其重要,在太多的源码分析的文章讲得比较繁琐,很多人对整个消息处理机制依然是懵懵懂懂。 这篇文章通过一些问答的模式结合Android主线程(UI线程)的工作原理来讲解,源码注释.

Android23333的博客 416

Android Framework学习(五)之应用进程启动流程

在之前的博客中我们学习了Launcher的启动流程,在SystemServer进程执行完成,各种系统服务启动完成之后,会调用ActivityManagerService中的systemReady()方法,在systemReady()方法中会执行Launcher启动的相关逻辑,本篇博客,我们将一起学习应用程序进程的启动流程,注意:这里是“应用程序进程启动过程”,而不是应用程序启动过程应用进程概述每一个android应用默认都是在他自己的linux进程中运行。

Android23333的博客 348
上一篇: Android系统源码分析-进程间通信机制binder(二):binder内存映射
下一篇: Android系统源码分析-进程间通信机制binder(四):从Native层到Driver层
liranke
博客等级 码龄20年 4939粉丝 594原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

liranke

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值