bindService的调用流程

这篇具有很好参考价值的文章主要介绍了bindService的调用流程。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

使用bindService去调用service,如果有多个客户端调用,onBind方法只会被调用一次,由于bindService嗲处理中,AMS是一个中间商,猜测这个处理也是AMS里进行的,这里我们再看看bindService的调用流程

bindService的调用流程,android

bindService的调用流程,android

 

public class ContextWrapper extends Context {

    Context mBase;

    public ContextWrapper(Context base) {

        mBase = base;

    }

    public boolean bindService(Intent service, ServiceConnection conn,

            int flags) {

        return mBase.bindService(service, conn, flags);

    }

ContextImpl.java

    // bindService

    @Override

    public boolean bindService(Intent service, ServiceConnection conn, int flags) {

        warnIfCallingFromSystemProcess();

        return bindServiceCommon(service, conn, flags, Process.myUserHandle());

    }

    // bindServiceCommon

    private boolean bindServiceCommon(Intent service, ServiceConnection conn, int flags, UserHandle user) {

        IServiceConnection sd;

        ...

//包装ServiceConnection

        sd = mPackageInfo.getServiceDispatcher(conn, getOuterContext(),

                mMainThread.getHandler(), flags);

        ...

        int res = ActivityManagerNative.getDefault().bindService(

                mMainThread.getApplicationThread(), getActivityToken(), service,

                service.resolveTypeIfNeeded(getContentResolver()),

                sd, flags, getOpPackageName(), user.getIdentifier());

        ...

    }

这里是通过binder和AMS进行通信,一次binder调用

ActivityManagerNative.java

    private static final Singleton<IActivityManager> gDefault = new Singleton<IActivityManager>() {

        protected IActivityManager create() {

            IBinder b = ServiceManager.getService("activity");

            if (false) {

                Log.v("ActivityManager", "default service binder = " + b);

            }

            IActivityManager am = asInterface(b);

            if (false) {

                Log.v("ActivityManager", "default service = " + am);

            }

            return am;

        }

    };

}

    static public IActivityManager asInterface(IBinder obj) {

        if (obj == null) {

            return null;

        }

        IActivityManager in =

            (IActivityManager)obj.queryLocalInterface(descriptor);

        if (in != null) {

            return in;

        }

        return new ActivityManagerProxy(obj);

    }

public abstract class Singleton<T> {

    private T mInstance;

    protected abstract T create();

    public final T get() {

        synchronized (this) {

            if (mInstance == null) {

                mInstance = create();

            }

            return mInstance;

        }

    }

}

即包装ServiceManager.getService("activity");

继续查看bindServiceCommon方法

    private boolean bindServiceCommon(Intent service, ServiceConnection conn, int flags, Handler

            handler, UserHandle user) {

        IServiceConnection sd;

        if (conn == null) {

            throw new IllegalArgumentException("connection is null");

        }

        if (mPackageInfo != null) {

            sd = mPackageInfo.getServiceDispatcher(conn, getOuterContext(), handler, flags);

        } else {

            throw new RuntimeException("Not supported in system context");

        }

        validateServiceIntent(service);

        try {

            IBinder token = getActivityToken();

            if (token == null && (flags&BIND_AUTO_CREATE) == 0 && mPackageInfo != null

                    && mPackageInfo.getApplicationInfo().targetSdkVersion

                    < android.os.Build.VERSION_CODES.ICE_CREAM_SANDWICH) {

                flags |= BIND_WAIVE_PRIORITY;

            }

            service.prepareToLeaveProcess(this);

            int res = ActivityManagerNative.getDefault().bindService(

                mMainThread.getApplicationThread(), getActivityToken(), service,

                service.resolveTypeIfNeeded(getContentResolver()),

                sd, flags, getOpPackageName(), user.getIdentifier());

这个sd是怎么来的呢

ServiceDispatcher用来包装ServiceConnection

创建binder实体对象,用来响应回调

LoadedApk.java

    public final IServiceConnection getServiceDispatcher(ServiceConnection c,

            Context context, Handler handler, int flags) {

        synchronized (mServices) {

            LoadedApk.ServiceDispatcher sd = null;

            ArrayMap<ServiceConnection, LoadedApk.ServiceDispatcher> map = mServices.get(context);

            if (map != null) {

                sd = map.get(c);

            }

            if (sd == null) {

                sd = new ServiceDispatcher(c, context, handler, flags);

                if (map == null) {

                    map = new ArrayMap<ServiceConnection, LoadedApk.ServiceDispatcher>();

                    mServices.put(context, map);

                }

                map.put(c, sd);

            } else {

                sd.validate(context, handler);

            }

            return sd.getIServiceConnection();

        }

    }

        ServiceDispatcher(ServiceConnection conn,

                Context context, Handler activityThread, int flags) {

            mIServiceConnection = new InnerConnection(this);

            mConnection = conn;

            mContext = context;

            mActivityThread = activityThread;

            mLocation = new ServiceConnectionLeaked(null);

            mLocation.fillInStackTrace();

            mFlags = flags;

        }

InnerConnection用来进行binder通信

        private static class InnerConnection extends IServiceConnection.Stub {

            final WeakReference<LoadedApk.ServiceDispatcher> mDispatcher;

            InnerConnection(LoadedApk.ServiceDispatcher sd) {

                mDispatcher = new WeakReference<LoadedApk.ServiceDispatcher>(sd);

            }

            public void connected(ComponentName name, IBinder service) throws RemoteException {

                LoadedApk.ServiceDispatcher sd = mDispatcher.get();

                if (sd != null) {

                    sd.connected(name, service);

                }

            }

        }

 

bindService的调用流程,android 

AMS端作为Proxy进行调用connected方法

IServiceConnection.Stub的定义

vi out/target/common/obj/JAVA_LIBRARIES/framework_intermediates/src/core/java/android/app/IServiceConnection.java

/*

 * This file is auto-generated.  DO NOT MODIFY.

 * Original file: frameworks/base/core/java/android/app/IServiceConnection.aidl

 */

package android.app;

/** @hide */

public interface IServiceConnection extends android.os.IInterface

{

/** Local-side IPC implementation stub class. */

public static abstract class Stub extends android.os.Binder implements android.app.IServiceConnection

{

@Override public boolean onTransact(int code, android.os.Parcel data, android.os.Parcel reply, int flags) throws android.os.RemoteException

{

switch (code)

{

case INTERFACE_TRANSACTION:

{

reply.writeString(DESCRIPTOR);

return true;

}

case TRANSACTION_connected:

{

data.enforceInterface(DESCRIPTOR);

android.content.ComponentName _arg0;

if ((0!=data.readInt())) {

_arg0 = android.content.ComponentName.CREATOR.createFromParcel(data);

}

else {

_arg0 = null;

}

android.os.IBinder _arg1;

_arg1 = data.readStrongBinder();

this.connected(_arg0, _arg1);

return true;

}

}

return super.onTransact(code, data, reply, flags);

}

private static class Proxy implements android.app.IServiceConnection

{

private android.os.IBinder mRemote;

Proxy(android.os.IBinder remote)

AMS通过调用传入的proxy来和client端进行交互

ActivityManagerService中有方法

    public void publishService(IBinder token, Intent intent, IBinder service) {

        // Refuse possible leaked file descriptors

        if (intent != null && intent.hasFileDescriptors() == true) {

            throw new IllegalArgumentException("File descriptors passed in Intent");

        }

        synchronized(this) {

            if (!(token instanceof ServiceRecord)) {

                throw new IllegalArgumentException("Invalid service token");

            }

            mServices.publishServiceLocked((ServiceRecord)token, intent, service);

        }

    }

ActiveServices.java

    void publishServiceLocked(ServiceRecord r, Intent intent, IBinder service) {

                ...

                    for (int conni=r.connections.size()-1; conni>=0; conni--) {

                        ArrayList<ConnectionRecord> clist = r.connections.valueAt(conni);

                        for (int i=0; i<clist.size(); i++) {

                            ConnectionRecord c = clist.get(i);

                            ...

                            try {

//binder调用,AMS调用client的方法,把service的binder传过去

                                c.conn.connected(r.name, service);

                            } catch (Exception e) {

                                Slog.w(TAG, "Failure sending service " + r.name +

                                      " to connection " + c.conn.asBinder() +

                                      " (in " + c.binding.client.processName + ")", e);

                            }

                        }

                    }

               ...

    }

ConnectionRecord.java

final class ConnectionRecord {

    final AppBindRecord binding;    // The application/service binding.

    final ActivityRecord activity;  // If non-null, the owning activity.

    final IServiceConnection conn;  // The client connection.

AMS中

    public int bindService(IApplicationThread caller, IBinder token, Intent service,

            String resolvedType, IServiceConnection connection, int flags, String callingPackage,

            int userId) throws TransactionTooLargeException {

        enforceNotIsolatedCaller("bindService");

        // Refuse possible leaked file descriptors

        if (service != null && service.hasFileDescriptors() == true) {

            throw new IllegalArgumentException("File descriptors passed in Intent");

        }

        if (callingPackage == null) {

            throw new IllegalArgumentException("callingPackage cannot be null");

        }

        synchronized(this) {

            return mServices.bindServiceLocked(caller, token, service,

                    resolvedType, connection, flags, callingPackage, userId);

        }

    }

在ActivityManagerService.java中有定义

    final ActiveServices mServices;

ActiveServices.java中

bindServiceLocked

bringUpServiceLocked

public final class ActiveServices {

    private final void realStartServiceLocked(ServiceRecord r,

            ProcessRecord app, boolean execInFg) throws RemoteException {

      ...

        r.app = app;

       ...

            app.thread.scheduleCreateService(r, r.serviceInfo,

                    mAm.compatibilityInfoForPackageLocked(r.serviceInfo.applicationInfo),

                    app.repProcState);

            r.postNotification();

     ...

     //

        requestServiceBindingsLocked(r, execInFg);

        updateServiceClientActivitiesLocked(app, null, true);

     ...

    }

private final boolean requestServiceBindingLocked(ServiceRecord r, IntentBindRecord i,

            boolean execInFg, boolean rebind) throws TransactionTooLargeException {

        if (r.app == null || r.app.thread == null) {

            // If service is not currently running, can't yet bind.

            return false;

        }

        if ((!i.requested || rebind) && i.apps.size() > 0) {

            try {

                bumpServiceExecutingLocked(r, execInFg, "bind");

                r.app.forceProcessStateUpTo(ActivityManager.PROCESS_STATE_SERVICE);

                r.app.thread.scheduleBindService(r, i.intent.getIntent(), rebind,

                        r.app.repProcState);

                if (!rebind) {

                    i.requested = true;

                }

                i.hasBound = true;

                i.doRebind = false;

            } catch (TransactionTooLargeException e) {

… …

            }

        }

        return true;

    }

final class ProcessRecord {

    IApplicationThread thread;

这里是binder调用

在启动应用的过程中,通过对AMS的binder调用,传给了AMS一个ApplicationThread的proxy对象。

public abstract class ApplicationThreadNative extends Binder

        implements IApplicationThread {

    /**

ActivityThread.java中有内部类

    private class ApplicationThread extends ApplicationThreadNative {

        private static final String DB_INFO_FORMAT = "  %8s %8s %14s %14s  %s";

调用到ApplicationThread的

        public final void scheduleBindService(IBinder token, Intent intent,

                boolean rebind, int processState) {

            updateProcessState(processState, false);

            BindServiceData s = new BindServiceData();

            s.token = token;

            s.intent = intent;

            s.rebind = rebind;

            sendMessage(H.BIND_SERVICE, s);

        }

处理该消息时调用ActivityThread的

    private void handleBindService(BindServiceData data) {

        Service s = mServices.get(data.token);

        if (s != null) {

            try {

                data.intent.setExtrasClassLoader(s.getClassLoader());

                data.intent.prepareToEnterProcess();

                try {

                    if (!data.rebind) {

                        IBinder binder = s.onBind(data.intent);

                        ActivityManagerNative.getDefault().publishService(

                                data.token, data.intent, binder);

                    } else {

                        s.onRebind(data.intent);

                        ActivityManagerNative.getDefault().serviceDoneExecuting(

                                data.token, SERVICE_DONE_EXECUTING_ANON, 0, 0);

                    }

                    ensureJitEnabled();

                } catch (RemoteException ex) {

                    throw ex.rethrowFromSystemServer();

                }

            } catch (Exception e) {

            }

        }

    }

在server进程中,通过调用AMS服务publishService把binder对象传给AMS文章来源地址https://www.toymoban.com/news/detail-676603.html

到了这里,关于bindService的调用流程的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Android Studio基础工作流程-xml布局文件如何调用显示

    说起安卓开发,很多小伙伴在刚开始入门的时候会有些云里雾里,觉得很混乱,这很正常,大多数是因为不太清楚安卓开发的基本流程,以及各个文件之间是怎样去相互作用的。我会在这篇文章里面向你介绍一下Android studio工作的基本流程,很基础很基础的那种。 一个完整的

    2024年02月03日
    浏览(30)
  • ARM64函数调用流程分析

    ARM64 程序调用标准 下图是介绍一个简单函数调用的示例,在该示例中简单介绍了栈的使用。 2.1.1 main的C代码实现 2.1.2 main函数对应汇编及其分析 0000000000000114 main: main函数的入口 114: a9be7bfd stp x29, x30, [sp, #-32]! 将sp = sp - 32,为main函数开一个32Byte的栈空间,然后将x29(FP),X30(LR)寄

    2024年02月11日
    浏览(32)
  • QT调用glog日志流程

    glog日志库是Google开源的轻量级的日志库,平时在开发过程中经常要使用到日志,本篇记录Qt项目使用glog日志库的记录。 1.首先下载cmake,Download | CMake 安装设置环境变量,检查安装情况 2.下载glog源码 github网站比较慢,而且容易断线,可以用国内的境像 git clone https://gitee.com/

    2024年02月12日
    浏览(36)
  • OpenAI的GPT接口的调用流程

    要调用OpenAI的GPT接口,您需要获得API密钥,并使用HTTP请求发送请求。以下是一般的步骤,希望对大家有所帮助。北京木奇移动技术有限公司,专业的软件外包开发公司,欢迎交流合作。 1.获取OpenAI API密钥: 在使用OpenAI GPT接口之前,您需要在OpenAI官方网站上注册并获取API密钥

    2024年01月23日
    浏览(48)
  • 【FPGA-DSP】第五期:FFT调用流程

    目录 1. matlab输入信号编写 2. Simulink开发 2.1 模块搭建 2.2 Simulink运行 2.3 matlab信号处理  拓:输入信号位数改变 本章节主要说明如何在system generator中使用fft模块,话不多说,看操作: 参考教程第5期 - FFT调用流程 - 基于FPGA的数字信号处理系统开发笔记_哔哩哔哩_bilibili 参考我之

    2023年04月11日
    浏览(30)
  • Spring MVC简介及核心组件和调用流程理解

    Spring Web MVC是基于Servlet API构建的原始Web框架,从一开始就包含在Spring Framework中。正式名称“Spring Web MVC”来自其源模块的名称( spring-webmvc ),但它通常被称为“Spring MVC”。 在控制层框架历经Strust、WebWork、Strust2等诸多产品的历代更迭之后,目前业界普遍选择了SpringMVC作为

    2024年03月16日
    浏览(46)
  • 【SpringCloud】Eureka基于Ribbon负载均衡的调用链路流程分析

    微服务间相互调用的基础上,服务间的调用更多是以调用某多实例服务下的某个实例的形式。而这就需要用到负载均衡技术。对于开发者而言,只要通过@LoadBalance注解就开启了负载均衡。如此简单的操作底层究竟是什么样的,我想你也很想知道。 在《SpringCloud集成Eureka并实现

    2024年02月05日
    浏览(26)
  • Android调用相机拍照,调用图库,上传图片

    Android调用相机进行拍照,调用图库获取图片,可进行裁剪,显示图片,并将图片上传

    2024年02月11日
    浏览(43)
  • EasyCVR平台基于萤石云SDK接入的设备播放流程及接口调用

    EasyCVR视频融合云服务支持海量视频汇聚与管理、处理与分发、智能分析等视频能力,在功能上,可支持视频监控直播、云端录像、云存储、录像检索与回看、智能告警、平台级联、服务器集群等。EasyCVR平台可支持多类型设备、多协议方式接入,包括:国标GB28181协议、RTMP、

    2024年02月13日
    浏览(29)
  • Tensorflow实现训练数据的加载—模型搭建训练保存—模型调用和加载全流程

     将tensorflow的训练数据数组(矩阵)保存为.npy的数据格式。为后续的模型训练提供便捷的方法。例如如下:   加载.npy训练数据和测试数组(矩阵),加载后需要调整数据的形状以满足设计模型的输入输出需求,不然无法训练模型。 这里可以采用自定义层和tensorflow的API搭建

    2024年02月05日
    浏览(28)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包