自动填充服务AutoFillService的QA

1.AutoFillService 是在什么时候开始被绑定的

View获得焦点的时候,开始获取相关服务,经过一系列调用,最终bindAutoFillService

  • 焦点获取时,onFocusChanged被调用
less 复制代码
protected void onFocusChanged(boolean gainFocus, @FocusDirection int direction,
        @Nullable Rect previouslyFocusedRect) {
    ........
    ........
    ........
    notifyEnterOrExitForAutoFillIfNeeded(gainFocus);
  
}
  • notifyEnterOrExitForAutoFillIfNeededonFocusChanged 中被调用
java 复制代码
public void notifyEnterOrExitForAutoFillIfNeeded(boolean enter) {
   
   AutofillManager afm = getAutofillManager();
   afm.notifyViewEntered(this);
}

notifyEnterOrExitForAutoFillIfNeeded 中就开始获取相关服务了,通过AutofillManager.notifyViewEntered开始了跨进程,准备与AutofillManagerServiceImpl 通信,绑定AotoFillService

autofill相关服务或者是类有以下几个,这里先把类名列举出来,有个大概的印象,后面会逐渐的串联起来

  1. AutofillManager
  2. AutofillManagerServiceImpl
  3. AutofillManagerService
  4. RemoteFillService
  5. com.android.server.autofill.Session

当然还有一些 callback 用来各类之间的通信

AutofillManager 算是一个代理,其中有个重要的变量IAutoFillManager ,IAutoFillManager是一个binder对象,即 AutofillManagerService的客户端部分.

afm.notifyViewEntered 中就是通过 IAutoFillManager.startSession 正式开启了binder通信.

scss 复制代码
mService.startSession(client.autofillClientGetActivityToken(),
        mServiceClient.asBinder(), id, bounds, value, mContext.getUserId(),
        mCallback != null, flags, clientActivity,
        isCompatibilityModeEnabledLocked(), receiver);
        
 // mService 是 IAutoFillManager 的实例
  • 系统进程 AutofillManagerServicestartSession的逻辑

这里又构造了一个AutofillManagerServiceImpl,调用了startSessionLocked

从这里到bindservice被分为了两个过程

  1. startSessionLockedSession.requestAssistStructureLocked

2.在requestAssistStructureLocked中有调用了 AMS 的 requestAutofillData

scss 复制代码
try {
    if (!ActivityTaskManager.getService().requestAutofillData(mAssistReceiver,
            receiverExtras, mActivityToken, flags)) {
        Slog.w(TAG, "failed to request autofill data for " + mActivityToken);
    }
} finally {
    Binder.restoreCallingIdentity(identity);
}
  1. 在AMS 的 requestAutofillData中又通过 IApplicationThreada.requestAssistContextExtras 调回了app
csharp 复制代码
try {
    activity.app.getThread().requestAssistContextExtras(activity.token, pae,
            requestType, mViSessionId, flags);
    mPendingAssistExtras.add(pae);
    mUiHandler.postDelayed(pae, timeout);
} catch (RemoteException e) {
    Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
    return null;
}

上面三个过程都在系统进程中:

  1. 调用到IApplicationThreada.requestAssistContextExtras后,在app中的调用链是:

最后又通过ams.reportAssistContextExtras 再次回到系统进程中

ini 复制代码
IActivityTaskManager mgr = ActivityTaskManager.getService();
try {
    mgr.reportAssistContextExtras(cmd.requestToken, data, structure, content, referrer);
} catch (RemoteException e) {
    throw e.rethrowFromSystemServer();
}
  1. 最后一步了,再次回到系统进程后,就要绑定autofillservice

enqueue的实现如下,绑定逻辑在 enqueueJobThread

less 复制代码
private boolean enqueue(@NonNull Job<I, ?> job) {
    cancelTimeout();
    android.util.Log.e("heyan","heyan  ServiceConnector$Impl enqueue======",new Exception());

    return mHandler.post(() -> enqueueJobThread(job));
}

enqueueJobThread中调用了 bindService

less 复制代码
void enqueueJobThread(@NonNull Job<I, ?> job) {
    if (DEBUG) {
        Log.i(LOG_TAG, "post(" + job + ", this = " + this + ")");
    }
    cancelTimeout();
    if (mUnbinding) {
        completeExceptionally(job,
                new IllegalStateException("Service is unbinding. Ignoring " + job));
    } else if (!mQueue.offer(job)) {
        completeExceptionally(job,
                new IllegalStateException("Failed to add to queue: " + job));
    } else if (isBound()) {
        processQueue();
    } else if (!mBinding) {
        if (bindService(mServiceConnection)) {
            mBinding = true;
        } else {
            completeExceptionally(job,
                    new IllegalStateException("Failed to bind to service " + mIntent));
        }
    }
}

bindService直接调用了 mContext.bindService,绑定成功了!!!

less 复制代码
protected boolean bindService(@NonNull ServiceConnection serviceConnection) {
    if (DEBUG) {
        logTrace();
    }

    return mContext.bindService(mIntent, Context.BIND_AUTO_CREATE | mBindingFlags,
            mExecutor, serviceConnection);
}

暂存

本篇只是粗略的走了一遍自动填充服务AutoFillService的绑定过程,很多细节都略过了,后续可能会逐步补充细节。

相关推荐
恋猫de小郭15 分钟前
Flutter 发布官方 Skills ,Flutter 在 AI 领域再添一助力
android·前端·flutter
Kapaseker5 小时前
一杯美式搞懂 Any、Unit、Nothing
android·kotlin
黄林晴5 小时前
你的 Android App 还没接 AI?Gemini API 接入全攻略
android
恋猫de小郭16 小时前
2026 Flutter VS React Native ,同时在 AI 时代 VS Native 开发,你没见过的版本
android·前端·flutter
冬奇Lab17 小时前
PowerManagerService(上):电源状态与WakeLock管理
android·源码阅读
BoomHe1 天前
Now in Android 架构模式全面分析
android·android jetpack
二流小码农1 天前
鸿蒙开发:上传一张参考图片便可实现页面功能
android·ios·harmonyos
鹏程十八少1 天前
4.Android 30分钟手写一个简单版shadow, 从零理解shadow插件化零反射插件化原理
android·前端·面试
Kapaseker1 天前
一杯美式搞定 Kotlin 空安全
android·kotlin
三少爷的鞋1 天前
Android 协程时代,Handler 应该退休了吗?
android