当前位置: 首页 > news >正文

Android中级——四大组件工作过程

四大组件工作过程

  • Activity
  • Service
    • startService()过程
    • bindService()过程
  • BroadcastReceiver
    • 注册过程
    • 发送和接收过程
  • ContentProvider

Activity

startActivity()最终都会调用到startActivityForResult()

public void startActivityForResult(@RequiresPermission Intent intent, int requestCode, @Nullable Bundle options) {if (mParent == null) {options = transferSpringboardActivityOptions(options);Instrumentation.ActivityResult ar =mInstrumentation.execStartActivity(this, mMainThread.getApplicationThread(), mToken, this,intent, requestCode, options);if (ar != null) {mMainThread.sendActivityResult(mToken, mEmbeddedID, requestCode, ar.getResultCode(),ar.getResultData());}if (requestCode >= 0) {mStartedActivity = true;}cancelInputsAndStartExitTransition(options);}......
}

上面调用Instrumentation的execStartActivity()

public ActivityResult execStartActivity(......) {......try {......int result = ActivityTaskManager.getService().startActivity(whoThread,who.getBasePackageName(), who.getAttributionTag(), intent,intent.resolveTypeIfNeeded(who.getContentResolver()), token,target != null ? target.mEmbeddedID : null, requestCode, 0, null, options);checkStartActivityResult(result, intent);} catch (RemoteException e) {throw new RuntimeException("Failure from system", e);}return null;
}

上面获取ActivityTaskManagerService,是IPC过程,调用其startActivity()启动,然后调到startActivityAsUser()

private int startActivityAsUser(......) {......return getActivityStartController().obtainStarter(intent, "startActivityAsUser").setCaller(caller).setCallingPackage(callingPackage).setCallingFeatureId(callingFeatureId).setResolvedType(resolvedType).setResultTo(resultTo).setResultWho(resultWho).setRequestCode(requestCode).setStartFlags(startFlags).setProfilerInfo(profilerInfo).setActivityOptions(bOptions).setUserId(userId).execute();
}

上面通过ActivityStartController获取ActivityStarter

  • 调用 ActivityStarter 的 execute()、executeRequest()、startActivityUnchecked()、startActivityInner()
  • 调用 ActivityStack 的 startActivityLocked() 、positionChildAtTop()、positionChildAt()
  • 调用 RootWindowContainer 的 resumeFocusedStacksTopActivities()
  • 调用 ActivityStack 的 resumeTopActivityUncheckedLocked()、resumeTopActivityInnerLocked()
  • 调用 ActivityStackSupervisor 的 startSpecificActivity()realStartActivityLocked()
  • 调用 ClientLifecycleManager 的 scheduleTransaction()
  • 调用 ClientTransaction 的 schedule()
  • 调用 ActivityThread 中 ApplicationThread 的 scheduleTransaction()
  • 调用 ClientTransactionHandler 的 scheduleTransaction()
  • 调用 ClientTransaction() 的 preExecute()
  • 向 ActivityThread 发送 H.EXECUTE_TRANSACTION
  • 调用 TransactionExecutor 的 execute()、executeCallbacks()、cycleToPath()、performLifecycleSequence()
  • 调用 ClientTransactionHandler 子类 ActivityThread 的handleLaunchActivity()performLaunchActivity()

下面主要分析performLaunchActivity(),首先从ActivityClientRecord获取Activity的信息,创建ContextImpl,其是Context的具体实现

ActivityInfo aInfo = r.activityInfo;
if (r.packageInfo == null) {r.packageInfo = getPackageInfo(aInfo.applicationInfo, r.compatInfo,Context.CONTEXT_INCLUDE_CODE);
}
ComponentName component = r.intent.getComponent();
if (component == null) {component = r.intent.resolveActivity(mInitialApplication.getPackageManager());r.intent.setComponent(component);
}
if (r.activityInfo.targetActivity != null) {component = new ComponentName(r.activityInfo.packageName,r.activityInfo.targetActivity);
}
ContextImpl appContext = createBaseContextForActivity(r);

通过Instrumentation的newActivity()使用ClassLoader创建Activity,返回 (Activity) cl.loadClass(className).newInstance();

try {java.lang.ClassLoader cl = appContext.getClassLoader();activity = mInstrumentation.newActivity(cl, component.getClassName(), r.intent);StrictMode.incrementExpectedActivityCount(activity.getClass());r.intent.setExtrasClassLoader(cl);r.intent.prepareToEnterProcess();if (r.state != null) {r.state.setClassLoader(cl);}
}......

通过LoadedApk的makeApplication()创建Application

  • 若已创建则不再创建
  • Instrumentation的newApplication() 返回 (Application) cl.loadClass(className).newInstance();
  • Instrumentation的callApplicationOnCreate() 调用onCreate()方法
@UnsupportedAppUsage
public Application makeApplication(boolean forceDefaultAppClass,Instrumentation instrumentation) {if (mApplication != null) {return mApplication;}Application app = null;String appClass = mApplicationInfo.className;if (forceDefaultAppClass || (appClass == null)) {appClass = "android.app.Application";}try {final java.lang.ClassLoader cl = getClassLoader();if (!mPackageName.equals("android")) {initializeJavaContextClassLoader();}SparseArray<String> packageIdentifiers = getAssets().getAssignedPackageIdentifiefalse, false);for (int i = 0, n = packageIdentifiers.size(); i < n; i++) {final int id = packageIdentifiers.keyAt(i);if (id == 0x01 || id == 0x7f) {continue;}rewriteRValues(cl, packageIdentifiers.valueAt(i), id);}ContextImpl appContext = ContextImpl.createAppContext(mActivityThread, this);NetworkSecurityConfigProvider.handleNewApplication(appContext);app = mActivityThread.mInstrumentation.newApplication(cl, appClass, appContext);appContext.setOuterContext(app);}......mActivityThread.mAllApplications.add(app);mApplication = app;if (instrumentation != null) {try {instrumentation.callApplicationOnCreate(app);}......}......return app;
}

通过Activity的attach初始化数据,包括和ContextImpl建立关联、创建Window及关联

CharSequence title = r.activityInfo.loadLabel(appContext.getPackageManager());
Configuration config = new Configuration(mCompatConfiguration);
if (r.overrideConfig != null) {config.updateFrom(r.overrideConfig);
}Window window = null;
if (r.mPendingRemoveWindow != null && r.mPreserveWindow) {window = r.mPendingRemoveWindow;r.mPendingRemoveWindow = null;r.mPendingRemoveWindowManager = null;
}appContext.getResources().addLoaders(app.getResources().getLoaders().toArray(new ResourcesLoader[0]));
appContext.setOuterContext(activity);
activity.attach(appContext, this, getInstrumentation(), r.token,r.ident, app, r.intent, r.activityInfo, title, r.parent,r.embeddedID, r.lastNonConfigurationInstances, config,r.referrer, r.voiceInteractor, window, r.configCallback,r.assistToken);

通过Instrumentation的callActivityOnCreate调用onCreate(),至此Activity启动完成

Service

startService()过程

会调用到ContextWrapper的startService(),mBase为ContextImpl

@Override
public ComponentName startService(Intent service) {return mBase.startService(service);
}

会调用到ContextImpl的startServiceCommon()

private ComponentName startServiceCommon(Intent service, boolean requireForeground,UserHandle user) {try {validateServiceIntent(service);service.prepareToLeaveProcess(this);ComponentName cn = ActivityManager.getService().startService(mMainThread.getApplicationThread(), service,service.resolveTypeIfNeeded(getContentResolver()), requireForeground,getOpPackageName(), getAttributionTag(), user.getIdentifier());......return cn;} catch (RemoteException e) {throw e.rethrowFromSystemServer();}
}

会调用到ActivityManagerService的startService()


@Override
public ComponentName startService(......)  throws TransactionTooLargeException {......synchronized (this) {final int callingPid = Binder.getCallingPid();final int callingUid = Binder.getCallingUid();final long origId = Binder.clearCallingIdentity();ComponentName res;try {res = mServices.startServiceLocked(caller, service,resolvedType, callingPid, callingUid,requireForeground, callingPackage, callingFeatureId, userId);} finally {Binder.restoreCallingIdentity(origId);}return res;}
}

会调用

  • ActiveServices 的 startServiceLocked()、startServiceInnerLocked()、bringUpServiceLocked()、realStartServiceLocked()、sendServiceArgsLocked()这里会调用onStartCommand()
  • ActivityThread 中 ApplicationThread 的 scheduleCreateService()、发送H.CREATE_SERVICE、handleCreateService()

主要分析handleCreateService()

  • 创建ContextImpl、Application、Service
  • 调用attach,建立ContextImpl和Service的联系
  • 调用onCreate(),将service放到mServices列表
private void handleCreateService(CreateServiceData data) {unscheduleGcIdler();LoadedApk packageInfo = getPackageInfoNoCheck(data.info.applicationInfo, data.compatInfo);Service service = null;try {ContextImpl context = ContextImpl.createAppContext(this, packageInfo);Application app = packageInfo.makeApplication(false, mInstrumentation);java.lang.ClassLoader cl = packageInfo.getClassLoader();service = packageInfo.getAppFactory().instantiateService(cl, data.info.name, data.intent);context.getResources().addLoaders(app.getResources().getLoaders().toArray(new ResourcesLoader[0]));context.setOuterContext(service);service.attach(context, this, data.info.name, data.token, app,ActivityManager.getService());service.onCreate();mServices.put(data.token, service);try {ActivityManager.getService().serviceDoneExecuting(data.token, SERVICE_DONE_EXECUTING_ANON, 0, 0);} catch (RemoteException e) {throw e.rethrowFromSystemServer();}}......
}

bindService()过程

会调用到ContextWrapper的bindService(),mBase为ContextImpl

@Override
public boolean bindService(Intent service, ServiceConnection conn,int flags) {return mBase.bindService(service, conn, flags);
}

上面调用到ContextImpl的bindServiceCommon()

@Override
public boolean bindService(Intent service, ServiceConnection conn, int flags) {warnIfCallingFromSystemProcess();return bindServiceCommon(service, conn, flags, null, mMainThread.getHandler(), null,getUser());
}private boolean bindServiceCommon(Intent service, ServiceConnection conn, int flags,String instanceName, Handler handler, Executor executor, UserHandle user) {IServiceConnection sd;......if (mPackageInfo != null) {if (executor != null) {sd = mPackageInfo.getServiceDispatcher(conn, getOuterContext(), executor, flags);} else {sd = mPackageInfo.getServiceDispatcher(conn, getOuterContext(), handler, flags);}}......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 = ActivityManager.getService().bindIsolatedService(mMainThread.getApplicationThread(), getActivityToken(), service,service.resolveTypeIfNeeded(getContentResolver()),sd, flags, instanceName, getOpPackageName(), user.getIdentifier());......return res != 0;}......
}

上面调用到LoadedApk的getServiceDispatcher()、getServiceDispatcherCommon()

  • 先查找是否存在当前ServiceConnection所对应的ServiceDispatcher,不存在则创建并存在mServices中
  • 将ServiceConnection转为ServiceDispatcher.InnerConnection对象(充当Binder),因为绑定服务可能是跨进程的
private IServiceConnection getServiceDispatcherCommon(ServiceConnection c,Context context, Handler handler, Executor executor, 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) {if (executor != null) {sd = new ServiceDispatcher(c, context, executor, flags);} else {sd = new ServiceDispatcher(c, context, handler, flags);}if (map == null) {map = new ArrayMap<>();mServices.put(context, map);}map.put(c, sd);} else {sd.validate(context, handler, executor);}return sd.getIServiceConnection();}
}

接下来调用

  • ActivityManagerService 的 bindIsolatedService()
  • ActiveServices 的 bindServiceLocked()、bringUpServiceLocked()、realStartServiceLocked()
  • ActivityThread 中 ApplicationThread 的 scheduleCreateService()创建Service,同上
  • ActiveServices 的 requestServiceBindingsLocked()、requestServiceBindingLocked()
  • ActivityThread 中 ApplicationThread 的 scheduleBindService()、发送H.BIND_SERVICE、handleBindService()

主要分析handleBindService(),从mServices取出Service,调用onBind()获取服务端Binder,此时已经绑定成功

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);ActivityManager.getService().publishService(data.token, data.intent, binder);} else {s.onRebind(data.intent);ActivityManager.getService().serviceDoneExecuting(data.token, SERVICE_DONE_EXECUTING_ANON, 0, 0);}}......}......}
}

接下来调用

  • ActivityManagerService() 的 publishService()
  • ActiveServices 的 publishServiceLocked()
  • ConnectionRecord 中 ServiceDispatcher.InnerConnection 的 connected(),传入onBind()获取的服务端Binder
  • LoadedApk 中 ServiceDispatcher 的 connected()

mActivityThread等于调用ContextImpl的bindService()时传入的mMainThread.getHandler(),故RunConnection会运行在主线程中

public void connected(ComponentName name, IBinder service, boolean dead) {if (mActivityExecutor != null) {mActivityExecutor.execute(new RunConnection(name, service, 0, dead));} else if (mActivityThread != null) {mActivityThread.post(new RunConnection(name, service, 0, dead));} else {doConnected(name, service, dead);}
}

调用LoadedApk 中 ServiceDispatcher 的 doConnected()

private final class RunConnection implements Runnable {RunConnection(ComponentName name, IBinder service, int command, boolean dead) {mName = name;mService = service;mCommand = command;mDead = dead;}public void run() {if (mCommand == 0) {doConnected(mName, mService, mDead);} else if (mCommand == 1) {doDeath(mName, mService);}}final ComponentName mName;final IBinder mService;final int mCommand;final boolean mDead;
}

doConnected()会调用onServiceConnected(),并将服务端Binder传回客户端

public void doConnected(ComponentName name, IBinder service, boolean dead) {ServiceDispatcher.ConnectionInfo old;ServiceDispatcher.ConnectionInfo info;synchronized (this) {if (mForgotten) {return;}old = mActiveConnections.get(name);if (old != null && old.binder == service) {return;}if (service != null) {info = new ConnectionInfo();info.binder = service;info.deathMonitor = new DeathMonitor(name, service);try {service.linkToDeath(info.deathMonitor, 0);mActiveConnections.put(name, info);} catch (RemoteException e) {mActiveConnections.remove(name);return;}} else {mActiveConnections.remove(name);}if (old != null) {old.binder.unlinkToDeath(old.deathMonitor, 0);}}if (old != null) {mConnection.onServiceDisconnected(name);}if (dead) {mConnection.onBindingDied(name);}if (service != null) {mConnection.onServiceConnected(name, service);} else {mConnection.onNullBinding(name);}
}

BroadcastReceiver

注册过程

静态注册在应用安装时由PackageManagerService完成注册,动态注册从ContextWrapper的registerReceiver()开始,mBase为ContextImpl

@Override
public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter) {return mBase.registerReceiver(receiver, filter);
}

上面调用到ContextImpl的registerReceiverInternal()

  • 将BroadcastReceiver转为LoadedApk.ReceiverDispatcher中的InnerReceiver(充当Binder),因为注册可能是跨进程的
private Intent registerReceiverInternal(BroadcastReceiver receiver, int userId,IntentFilter filter, String broadcastPermission,Handler scheduler, Context context, int flags) {IIntentReceiver rd = null;if (receiver != null) {if (mPackageInfo != null && context != null) {if (scheduler == null) {scheduler = mMainThread.getHandler();}rd = mPackageInfo.getReceiverDispatcher(receiver, context, scheduler,mMainThread.getInstrumentation(), true);} else {if (scheduler == null) {scheduler = mMainThread.getHandler();}rd = new LoadedApk.ReceiverDispatcher(receiver, context, scheduler, null, true).getIIntentReceiver();}}try {final Intent intent = ActivityManager.getService().registerReceiverWithFeature(mMainThread.getApplicationThread(), mBasePackageName, getAttributionTag(), rfilter, broadcastPermission, userId, flags);if (intent != null) {intent.setExtrasClassLoader(getClassLoader());intent.prepareToEnterProcess();}return intent;} catch (RemoteException e) {throw e.rethrowFromSystemServer();}
}

上面调用到ActivityManagerService的registerReceiverWithFeature(),将InnerReceiver和IntentFilter存储起来

public Intent registerReceiverWithFeature(IApplicationThread caller, String callerPackage,String callerFeatureId, IIntentReceiver receiver, String permission, int userId, int flags) {......synchronized (this) {......ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());if (rl == null) {rl = new ReceiverList(this, callerApp, callingPid, callingUid,userId, receiver);if (rl.app != null) {final int totalReceiversForApp = rl.app.receivers.size();rl.app.receivers.add(rl);} else {try {receiver.asBinder().linkToDeath(rl, 0);} catch (RemoteException e) {return sticky;}rl.linkedToDeath = true;}mRegisteredReceivers.put(receiver.asBinder(), rl);}......BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage, callerFeatureId,permission, callingUid, userId, instantApp, visibleToInstantApps);if (rl.containsFilter(filter)) {......} else {rl.add(bf);......mReceiverResolver.addFilter(bf);}......}
}

发送和接收过程

ContextWrapper的sendBroadcast()开始,mBase为ContextImpl

@Override
public void sendBroadcast(Intent intent) {mBase.sendBroadcast(intent);
}

上面调用ContextImpl的sendBroadcast()

@Override
public void sendBroadcast(Intent intent) {warnIfCallingFromSystemProcess();String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());try {intent.prepareToLeaveProcess(this);ActivityManager.getService().broadcastIntentWithFeature(mMainThread.getApplicationThread(), getAttributionTag(), intent, resolvedType,null, Activity.RESULT_OK, null, null, null, AppOpsManager.OP_NONE, null, false,false, getUserId());} catch (RemoteException e) {throw e.rethrowFromSystemServer();}
}

上面调用ActivityManagerService的broadcastIntentWithFeature()、broadcastIntentLocked()

  • FLAG_EXCLUDE_STOPPED_PACKAGES表示不会向已停止的app发送广播
  • 根据intent-filter查找匹配的BroadcastReceiver,并添加到BroadcastQueue

final int broadcastIntentLocked(ProcessRecord callerApp, String callerPackage,@Nullable String callerFeatureId, Intent intent, String resolvedType,IIntentReceiver resultTo, int resultCode, String resultData,Bundle resultExtras, String[] requiredPermissions, int appOp, Bundle bOptions,boolean ordered, boolean sticky, int callingPid, int callingUid, int realCallingUid,int realCallingPid, int userId, boolean allowBackgroundActivityStarts,@Nullable int[] broadcastWhitelist) {intent = new Intent(intent);......intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);......final BroadcastQueue queue = broadcastQueueForIntent(intent);BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, callerPackage,callerFeatureId, callingPid, callingUid, callerInstantApp, resolvedType,requiredPermissions, appOp, brOptions, registeredReceivers, resultTo,resultCode, resultData, resultExtras, ordered, sticky, false, userId,allowBackgroundActivityStarts, timeoutExempt);final boolean replaced = replacePending&& (queue.replaceParallelBroadcastLocked(r) != null);if (!replaced) {queue.enqueueParallelBroadcastLocked(r);queue.scheduleBroadcastsLocked();}
}

上面再调用

  • BroadcastQueue的scheduleBroadcastsLocked()、发送BROADCAST_INTENT_MSG、processNextBroadcast()、processNextBroadcastLocked()、deliverToRegisteredReceiverLocked()、performReceiveLocked()
  • ActivityThread 中 ApplicationThread 的 scheduleRegisteredReceiver()
  • LoadedApk.ReceiverDispatcher中InnerReceiver的performReceive()
  • LoadedApk.ReceiverDispatcher的performReceive()
public void performReceive(Intent intent, int resultCode, String data,Bundle extras, boolean ordered, boolean sticky, int sendingUser) {final Args args = new Args(intent, resultCode, data, extras, ordered,sticky, sendingUser);......if (intent == null || !mActivityThread.post(args.getRunnable())) {if (mRegistered && ordered) {IActivityManager mgr = ActivityManager.getService();args.sendFinished(mgr);}}
}

mActivityThread等于调用ContextImpl的sendBroadcast()时传入的mMainThread.getHandler(),故Args会运行在主线程中,回调onReceive(),此时应用已接收到广播

final class Args extends BroadcastReceiver.PendingResult {......public final Runnable getRunnable() {return () -> {.....try {ClassLoader cl = mReceiver.getClass().getClassLoader();intent.setExtrasClassLoader(cl);intent.prepareToEnterProcess();setExtrasClassLoader(cl);receiver.setPendingResult(this);receiver.onReceive(mContext, intent);}......};}
}

ContentProvider

以query()为例,调用ContentResolver的acquireUnstableProvider()或acquireProvider()获取IContentProvider,其是抽象方法

@Override
public final @Nullable Cursor query(final @RequiresPermission.Read @NonNull Uri uri,@Nullable String[] projection, @Nullable Bundle queryArgs,@Nullable CancellationSignal cancellationSignal) {......IContentProvider unstableProvider = acquireUnstableProvider(uri);if (unstableProvider == null) {return null;}IContentProvider stableProvider = null;Cursor qCursor = null;try {......            try {qCursor = unstableProvider.query(mPackageName, uri, projection,queryArgs, remoteCancellationSignal);} catch (DeadObjectException e) {unstableProviderDied(unstableProvider);stableProvider = acquireProvider(uri);if (stableProvider == null) {return null;}qCursor = stableProvider.query(mPackageName, uri, projection, queryArgs, remoteCancellationSignal);}if (qCursor == null) {return null;}qCursor.getCount();final IContentProvider provider = (stableProvider != null) ? stableProvider: acquireProvider(uri);final CursorWrapperInner wrapper = new CursorWrapperInner(qCursor, provider);stableProvider = null;qCursor = null;return wrapper;}.....
}

会调用ContextImpl.ApplicationContentResolver 的 acquireProvider()

private static final class ApplicationContentResolver extends ContentResolver {@UnsupportedAppUsageprivate final ActivityThread mMainThread;public ApplicationContentResolver(Context context, ActivityThread mainThread) {super(context);mMainThread = Objects.requireNonNull(mainThread);}@Override@UnsupportedAppUsageprotected IContentProvider acquireProvider(Context context, String auth) {return mMainThread.acquireProvider(context,ContentProvider.getAuthorityWithoutUserId(auth),resolveUserIdFromAuthority(auth), true);}......@Overrideprotected IContentProvider acquireUnstableProvider(Context c, String auth) {return mMainThread.acquireProvider(c,ContentProvider.getAuthorityWithoutUserId(auth),resolveUserIdFromAuthority(auth), false);}......
}

调用到ActivityThread 的 acquireProvider()、acquireExistingProvider()判断IContentProvider是否已经加载到mProviderMap

public final IContentProvider acquireProvider(Context c, String auth, int userId, boolean stable) {final IContentProvider provider = acquireExistingProvider(c, auth, userId, stable);if (provider != null) {return provider;}ContentProviderHolder holder = null;try {synchronized (getGetProviderLock(auth, userId)) {holder = ActivityManager.getService().getContentProvider(getApplicationThread(), c.getOpPackageName(), auth, userId, stable);}} catch (RemoteException ex) {throw ex.rethrowFromSystemServer();}if (holder == null) {......return null;}......holder = installProvider(c, holder, holder.info,true /*noisy*/, holder.noReleaseNeeded, stable);return holder.provider;
}

若没加载,则调用ActivityManagerService的getContentProvider(),startProcessLocked()启动ContentProvider所在的进程,进程入口方法为ActivityThread的main(),在此创建ActivityThread和主线程消息队列

public static void main(String[] args) {......Looper.prepareMainLooper();long startSeq = 0;if (args != null) {for (int i = args.length - 1; i >= 0; --i) {if (args[i] != null && args[i].startsWith(PROC_START_SEQ_IDENT)) {startSeq = Long.parseLong(args[i].substring(PROC_START_SEQ_IDENT.length()));}}}ActivityThread thread = new ActivityThread();thread.attach(false, startSeq);if (sMainThreadHandler == null) {sMainThreadHandler = thread.getHandler();}......Looper.loop();throw new RuntimeException("Main thread loop unexpectedly exited");
}

上面调用

  • ActivityThread 的 attach()
  • ActivityManagerService 的 attachApplication()、attachApplicationLocked(),传入ApplicationThread,其是Binder,用于ActivityThread和ActivityManagerService之间的通信
  • ApplicationThread 的 bindApplication()、发送H.BIND_APPLICATION、handleBindApplication()

在handleBindApplication(),创建Application、加载ContentProviders、然后再调用Application的OnCreate()

private void handleBindApplication(AppBindData data) {......Application app;try {app = data.info.makeApplication(data.restrictedBackupMode, null);.....if (!data.restrictedBackupMode) {if (!ArrayUtils.isEmpty(data.providers)) {installContentProviders(app, data.providers);}}try {mInstrumentation.onCreate(data.instrumentationArgs);}......try {mInstrumentation.callApplicationOnCreate(app);}......}......
}

在installContentProviders()中又调用installProvider()、instantiateProvider()通过反射创建ContentProvider,调用attachInfo()、回调onCreate()

private ContentProviderHolder installProvider(Context context,ContentProviderHolder holder, ProviderInfo info,boolean noisy, boolean noReleaseNeeded, boolean stable) {......try {final java.lang.ClassLoader cl = c.getClassLoader();LoadedApk packageInfo = peekPackageInfo(ai.packageName, true);if (packageInfo == null) {packageInfo = getSystemContext().mPackageInfo;}localProvider = packageInfo.getAppFactory().instantiateProvider(cl, info.name);provider = localProvider.getIContentProvider();if (provider == null) {Slog.e(TAG, "Failed to instantiate class " +info.name + " from sourceDir " +info.applicationInfo.sourceDir);return null;}if (DEBUG_PROVIDER) Slog.v(TAG, "Instantiating local provider " + info.name);localProvider.attachInfo(c, info);}.......synchronized (mProviderMap) {IBinder jBinder = provider.asBinder();if (localProvider != null) {ComponentName cname = new ComponentName(info.packageName, info.name);ProviderClientRecord pr = mLocalProvidersByName.get(cname);if (pr != null) {provider = pr.mProvider;} else {holder = new ContentProviderHolder(info);holder.provider = provider;holder.noReleaseNeeded = true;pr = installProviderAuthoritiesLocked(provider, localProvider, holder);mLocalProviders.put(jBinder, pr);mLocalProvidersByName.put(cname, pr);}retHolder = pr.mHolder;}
}

调用installProviderAuthoritiesLocked(),将ContentProvider封装到ProviderClientRecord存放在mProviderMap

private ProviderClientRecord installProviderAuthoritiesLocked(IContentProvider provider,ContentProvider localProvider, ContentProviderHolder holder) {......final ProviderClientRecord pcr = new ProviderClientRecord(auths, provider, localProvider, holder);for (String auth : auths) {final ProviderKey key = new ProviderKey(auth, userId);final ProviderClientRecord existing = mProviderMap.get(key);if (existing != null) {Slog.w(TAG, "Content provider " + pcr.mHolder.info.name+ " already published as " + auth);} else {mProviderMap.put(key, pcr);}}return pcr;
}

相关文章:

Android中级——四大组件工作过程

四大组件工作过程 ActivityServicestartService()过程bindService()过程 BroadcastReceiver注册过程发送和接收过程 ContentProvider Activity startActivity()最终都会调用到startActivityForResult() public void startActivityForResult(RequiresPermission Intent intent…...

【RabbitMQ】RabbitMQ 服务无法启动。系统出错。发生系统错误 1067。进程意外终止。

问题描述 RabbitMQ 服务无法启动。 rabbitmq-service.bat startRabbitMQ 服务正在启动 . RabbitMQ 服务无法启动。系统出错。发生系统错误 1067。进程意外终止。原因分析 RabbitMQ和Erlang版本不匹配。 解决方案 查询并安装RabbitMQ版本对应Erlang版本 https://www.rabbitm…...

如何理解attention中的Q、K、V?

y直接用torch实现一个SelfAttention来说一说&#xff1a; 1、首先定义三哥线性变换&#xff0c;query&#xff0c;key以及value&#xff1a; class BertSelfAttention(nn.Module):self.query nn.Linear(config.hidden_size, self.all_head_size)#输入768&#xff0c;输出768…...

Redis----取代RabbitMq 和 Kafka的解决方案

背景 已知rabbitmq和kafka作为消息中间件来给程序之间增加异步消息传递功能&#xff0c;这两个中间件都是专业的&#xff0c;功能也很强&#xff0c;但是有的时候过于复杂&#xff0c;对于只有一组消费者的消息队列&#xff0c;使用Redis 就可以轻松搞定。 异步消息队列 读者…...

动态规划之连续乘积最大子数组 连续和最大子数组

一. 连续和最大子数组 给你一个整数数组 nums &#xff0c;请你找出一个具有最大和的连续子数组&#xff08;子数组最少包含一个元素&#xff09;&#xff0c;返回其最大和。 子数组 是数组中的一个连续部分。 示例 1&#xff1a; 输入&#xff1a;nums [-2,1,-3,4,-1,2,1,-5,…...

keil在点击debug无法运行(全速运行)

1、今天发现我之前可以debug的程序&#xff0c;在板子上无法debug了&#xff0c;打断点完全没用 2、换了电脑&#xff0c;带板子过去也这样&#xff0c;之前可以运行的代码都debug不了 3、按照网上的方法&#xff0c;都不行&#xff0c;全速运行&#xff0c;单步执行都是灰色…...

go语言-协程

mOS结构体 每一种操作系统不同的线程信息 g给g0栈给g0协程内存中分配的地址&#xff0c;记录函数跳转信息&#xff0c; 单线程循环 0.x版本 1.0版本 多线程循环 操作系统并不知道Goroutine的存在 操作系统线程执行一个调度循环&#xff0c;顺序执行Goroutine 调度循环非常…...

如何伪造http头,让后端认为是本地访问

0x00 前言 这个知识点纯粹就是为了ctf准备的&#xff0c;很少有系统会出现这种情况。 0x01 正文 1.host头 如果后端从host取值来判断是否是本地就可以通过此方法进行绕过&#xff1a; host: 127.0.0.12.X-Forwarded-For X-Forwarded-For&#xff08;XFF&#xff09;是用来…...

视频剪辑音效处理软件有哪些?视频剪辑软件那个好用

音效是视频剪辑的重要部分&#xff0c;能起到画龙点睛的作用。在短视频平台中&#xff0c;一段出彩的音效能将原本平平无奇的视频变得生动有趣。那么&#xff0c;视频剪辑音效处理软件有哪些&#xff1f;本文会给大家介绍好用的音效处理软件&#xff0c;同时也会介绍视频剪辑音…...

搭建STM32F407的Freertos系统(基于STM32CubeMX)

本人长期开发Linux、Windows上应用软件&#xff0c;一直以来MCU开发有所接触&#xff0c;但较少&#xff08;最近项目需要&#xff0c;小公司么&#xff0c;都得会&#xff0c;被逼的&#xff09;&#xff0c;好在有STM32CubeMX这样工具&#xff0c;貌似就是我想要的工具。 本次…...

vite 配置自动补全文件的后缀名

vite 不建议自动补全&#xff0c;文件的后缀名的 const Home ()>import("/views/Home.vue");文件是必须要加上 .vue 的后缀名的 如果 想要像 webpack 一样的不用写&#xff0c; 可以在vite.config.js中配置如下就可以了...

基于Spring Boot的人才公寓管理系统设计与实现(Java+spring boot+MySQL)

获取源码或者论文请私信博主 演示视频&#xff1a; 基于Spring Boot的人才公寓管理系统设计与实现&#xff08;Javaspring bootMySQL&#xff09; 使用技术&#xff1a; 前端&#xff1a;html css javascript jQuery ajax thymeleaf 微信小程序 后端&#xff1a;Java spring…...

Python 编写函数

文章目录 条件语句循环语句自定义函数函数参数的传递类型函数的参数传入方法 lambda, map, filter, reduce 函数try-except 语句调试一些常用的内置函数 条件语句 编写程序时&#xff0c;经常用到一些条件或判断&#xff0c;需要用到 if 语句&#xff0c;它的字面意思是&#…...

C# Solidworks二次开发:创建距离配合以及移动组件API详解

今天要讲的文章是关于如何创建距离配合和移动组件的API详解。 &#xff08;1&#xff09;创建配合API&#xff0c;CreateMate() 这个API的解释是根据指定的特性数据对象来创建配合&#xff0c;也就可以理解为输入什么样的特征对象就可以创建出什么配合&#xff0c;这个API的输…...

Excel:通过Lookup函数提取指定文本关键词

函数公式&#xff1a;LOOKUP(9^9,FIND($G 2 : 2: 2:G 6 , C 2 ) , 6,C2), 6,C2),G 2 : 2: 2:G$6) 公式解释&#xff1a; lookup第一参数为9^9&#xff1a;代表的是一个极大值的数据&#xff0c;查询位置里面最接近这一个值的数据&#xff1b;lookup第二参数用find函数代替&am…...

sql:SQL优化知识点记录(六)

&#xff08;1&#xff09;索引优化1 查看一下有没有建立索引&#xff1a; 用到索引中的一个&#xff1a;type中的ref决定访问性能 用到索引中的两个&#xff1a;通过key_len的长度可以看出来&#xff0c;比第一个大一点。或者通过ref&#xff1a;中用到了两个常量const 用到了…...

C#搭建WebSocket服务实现通讯

在学习使用websocket之前我们先了解一下websocket&#xff1a; WebSocket是一种在单个TCP连接上进行全双工通信的通信协议。与HTTP协议不同&#xff0c;它允许服务器主动向客户端发送数据&#xff0c;而不需要客户端明确地请求。这使得WebSocket非常适合需要实时或持续通信的应…...

eclipse/STS(Spring Tool Suite)安装CDT环境(C/C++)

在线安装 help -> eclipse marketplace 可以发现&#xff0c;我所使用eclipse给我推荐安装的CDT是10.5版本 离线安装 下载离线安装包 下载地址&#xff1a;https://github.com/eclipse-cdt/cdt/blob/main/Downloads.md 可以看到利息安装包主要有如下四大类&#xff0c;…...

Python爬虫抓取经过JS加密的API数据的实现步骤

随着互联网的快速发展&#xff0c;越来越多的网站和应用程序提供了API接口&#xff0c;方便开发者获取数据。然而&#xff0c;为了保护数据的安全性和防止漏洞&#xff0c;一些API接口采用了JS加密技术这种加密技术使得数据在传输过程中更加安全&#xff0c;但也给爬虫开发带来…...

Nacos基础(2)——nacos的服务器和命名空间 springBoot整合nacos 多个nacos配置的情况

目录 引出nacos服务器和命名空间Nacos服务器命名空间 springBoot整合nacosspringcloud Alibaba 版本与springcloud对应关系引包配置maincontroller 报错以及解决【报错】错误&#xff1a;缺少服务名称报错&#xff1a;9848端口未开放 启动测试引入多个nacos配置多个配置的情况没…...

Vim 调用外部命令学习笔记

Vim 外部命令集成完全指南 文章目录 Vim 外部命令集成完全指南核心概念理解命令语法解析语法对比 常用外部命令详解文本排序与去重文本筛选与搜索高级 grep 搜索技巧文本替换与编辑字符处理高级文本处理编程语言处理其他实用命令 范围操作示例指定行范围处理复合命令示例 实用技…...

云启出海,智联未来|阿里云网络「企业出海」系列客户沙龙上海站圆满落地

借阿里云中企出海大会的东风&#xff0c;以**「云启出海&#xff0c;智联未来&#xff5c;打造安全可靠的出海云网络引擎」为主题的阿里云企业出海客户沙龙云网络&安全专场于5.28日下午在上海顺利举办&#xff0c;现场吸引了来自携程、小红书、米哈游、哔哩哔哩、波克城市、…...

【SQL学习笔记1】增删改查+多表连接全解析(内附SQL免费在线练习工具)

可以使用Sqliteviz这个网站免费编写sql语句&#xff0c;它能够让用户直接在浏览器内练习SQL的语法&#xff0c;不需要安装任何软件。 链接如下&#xff1a; sqliteviz 注意&#xff1a; 在转写SQL语法时&#xff0c;关键字之间有一个特定的顺序&#xff0c;这个顺序会影响到…...

Neo4j 集群管理:原理、技术与最佳实践深度解析

Neo4j 的集群技术是其企业级高可用性、可扩展性和容错能力的核心。通过深入分析官方文档,本文将系统阐述其集群管理的核心原理、关键技术、实用技巧和行业最佳实践。 Neo4j 的 Causal Clustering 架构提供了一个强大而灵活的基石,用于构建高可用、可扩展且一致的图数据库服务…...

GitHub 趋势日报 (2025年06月08日)

&#x1f4ca; 由 TrendForge 系统生成 | &#x1f310; https://trendforge.devlive.org/ &#x1f310; 本日报中的项目描述已自动翻译为中文 &#x1f4c8; 今日获星趋势图 今日获星趋势图 884 cognee 566 dify 414 HumanSystemOptimization 414 omni-tools 321 note-gen …...

什么?连接服务器也能可视化显示界面?:基于X11 Forwarding + CentOS + MobaXterm实战指南

文章目录 什么是X11?环境准备实战步骤1️⃣ 服务器端配置(CentOS)2️⃣ 客户端配置(MobaXterm)3️⃣ 验证X11 Forwarding4️⃣ 运行自定义GUI程序(Python示例)5️⃣ 成功效果![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/55aefaea8a9f477e86d065227851fe3d.pn…...

10-Oracle 23 ai Vector Search 概述和参数

一、Oracle AI Vector Search 概述 企业和个人都在尝试各种AI&#xff0c;使用客户端或是内部自己搭建集成大模型的终端&#xff0c;加速与大型语言模型&#xff08;LLM&#xff09;的结合&#xff0c;同时使用检索增强生成&#xff08;Retrieval Augmented Generation &#…...

JVM虚拟机:内存结构、垃圾回收、性能优化

1、JVM虚拟机的简介 Java 虚拟机(Java Virtual Machine 简称:JVM)是运行所有 Java 程序的抽象计算机,是 Java 语言的运行环境,实现了 Java 程序的跨平台特性。JVM 屏蔽了与具体操作系统平台相关的信息,使得 Java 程序只需生成在 JVM 上运行的目标代码(字节码),就可以…...

【Nginx】使用 Nginx+Lua 实现基于 IP 的访问频率限制

使用 NginxLua 实现基于 IP 的访问频率限制 在高并发场景下&#xff0c;限制某个 IP 的访问频率是非常重要的&#xff0c;可以有效防止恶意攻击或错误配置导致的服务宕机。以下是一个详细的实现方案&#xff0c;使用 Nginx 和 Lua 脚本结合 Redis 来实现基于 IP 的访问频率限制…...

MySQL 8.0 事务全面讲解

以下是一个结合两次回答的 MySQL 8.0 事务全面讲解&#xff0c;涵盖了事务的核心概念、操作示例、失败回滚、隔离级别、事务性 DDL 和 XA 事务等内容&#xff0c;并修正了查看隔离级别的命令。 MySQL 8.0 事务全面讲解 一、事务的核心概念&#xff08;ACID&#xff09; 事务是…...