当前位置: 首页 > 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配置多个配置的情况没…...

观成科技:隐蔽隧道工具Ligolo-ng加密流量分析

1.工具介绍 Ligolo-ng是一款由go编写的高效隧道工具&#xff0c;该工具基于TUN接口实现其功能&#xff0c;利用反向TCP/TLS连接建立一条隐蔽的通信信道&#xff0c;支持使用Let’s Encrypt自动生成证书。Ligolo-ng的通信隐蔽性体现在其支持多种连接方式&#xff0c;适应复杂网…...

解决Ubuntu22.04 VMware失败的问题 ubuntu入门之二十八

现象1 打开VMware失败 Ubuntu升级之后打开VMware上报需要安装vmmon和vmnet&#xff0c;点击确认后如下提示 最终上报fail 解决方法 内核升级导致&#xff0c;需要在新内核下重新下载编译安装 查看版本 $ vmware -v VMware Workstation 17.5.1 build-23298084$ lsb_release…...

DIY|Mac 搭建 ESP-IDF 开发环境及编译小智 AI

前一阵子在百度 AI 开发者大会上&#xff0c;看到基于小智 AI DIY 玩具的演示&#xff0c;感觉有点意思&#xff0c;想着自己也来试试。 如果只是想烧录现成的固件&#xff0c;乐鑫官方除了提供了 Windows 版本的 Flash 下载工具 之外&#xff0c;还提供了基于网页版的 ESP LA…...

sqlserver 根据指定字符 解析拼接字符串

DECLARE LotNo NVARCHAR(50)A,B,C DECLARE xml XML ( SELECT <x> REPLACE(LotNo, ,, </x><x>) </x> ) DECLARE ErrorCode NVARCHAR(50) -- 提取 XML 中的值 SELECT value x.value(., VARCHAR(MAX))…...

鱼香ros docker配置镜像报错:https://registry-1.docker.io/v2/

使用鱼香ros一件安装docker时的https://registry-1.docker.io/v2/问题 一键安装指令 wget http://fishros.com/install -O fishros && . fishros出现问题&#xff1a;docker pull 失败 网络不同&#xff0c;需要使用镜像源 按照如下步骤操作 sudo vi /etc/docker/dae…...

大数据学习(132)-HIve数据分析

​​​​&#x1f34b;&#x1f34b;大数据学习&#x1f34b;&#x1f34b; &#x1f525;系列专栏&#xff1a; &#x1f451;哲学语录: 用力所能及&#xff0c;改变世界。 &#x1f496;如果觉得博主的文章还不错的话&#xff0c;请点赞&#x1f44d;收藏⭐️留言&#x1f4…...

python报错No module named ‘tensorflow.keras‘

是由于不同版本的tensorflow下的keras所在的路径不同&#xff0c;结合所安装的tensorflow的目录结构修改from语句即可。 原语句&#xff1a; from tensorflow.keras.layers import Conv1D, MaxPooling1D, LSTM, Dense 修改后&#xff1a; from tensorflow.python.keras.lay…...

C++课设:简易日历程序(支持传统节假日 + 二十四节气 + 个人纪念日管理)

名人说:路漫漫其修远兮,吾将上下而求索。—— 屈原《离骚》 创作者:Code_流苏(CSDN)(一个喜欢古诗词和编程的Coder😊) 专栏介绍:《编程项目实战》 目录 一、为什么要开发一个日历程序?1. 深入理解时间算法2. 练习面向对象设计3. 学习数据结构应用二、核心算法深度解析…...

协议转换利器,profinet转ethercat网关的两大派系,各有千秋

随着工业以太网的发展&#xff0c;其高效、便捷、协议开放、易于冗余等诸多优点&#xff0c;被越来越多的工业现场所采用。西门子SIMATIC S7-1200/1500系列PLC集成有Profinet接口&#xff0c;具有实时性、开放性&#xff0c;使用TCP/IP和IT标准&#xff0c;符合基于工业以太网的…...

32单片机——基本定时器

STM32F103有众多的定时器&#xff0c;其中包括2个基本定时器&#xff08;TIM6和TIM7&#xff09;、4个通用定时器&#xff08;TIM2~TIM5&#xff09;、2个高级控制定时器&#xff08;TIM1和TIM8&#xff09;&#xff0c;这些定时器彼此完全独立&#xff0c;不共享任何资源 1、定…...