做的好看的统一登录网站/网站每天做100个外链
四大组件工作过程
- 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来说一说: 1、首先定义三哥线性变换,query,key以及value: class BertSelfAttention(nn.Module):self.query nn.Linear(config.hidden_size, self.all_head_size)#输入768,输出768…...

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

动态规划之连续乘积最大子数组 连续和最大子数组
一. 连续和最大子数组 给你一个整数数组 nums ,请你找出一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。 子数组 是数组中的一个连续部分。 示例 1: 输入:nums [-2,1,-3,4,-1,2,1,-5,…...

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

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

如何伪造http头,让后端认为是本地访问
0x00 前言 这个知识点纯粹就是为了ctf准备的,很少有系统会出现这种情况。 0x01 正文 1.host头 如果后端从host取值来判断是否是本地就可以通过此方法进行绕过: host: 127.0.0.12.X-Forwarded-For X-Forwarded-For(XFF)是用来…...

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

搭建STM32F407的Freertos系统(基于STM32CubeMX)
本人长期开发Linux、Windows上应用软件,一直以来MCU开发有所接触,但较少(最近项目需要,小公司么,都得会,被逼的),好在有STM32CubeMX这样工具,貌似就是我想要的工具。 本次…...

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

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

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

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

Excel:通过Lookup函数提取指定文本关键词
函数公式:LOOKUP(9^9,FIND($G 2 : 2: 2:G 6 , C 2 ) , 6,C2), 6,C2),G 2 : 2: 2:G$6) 公式解释: lookup第一参数为9^9:代表的是一个极大值的数据,查询位置里面最接近这一个值的数据;lookup第二参数用find函数代替&am…...

sql:SQL优化知识点记录(六)
(1)索引优化1 查看一下有没有建立索引: 用到索引中的一个:type中的ref决定访问性能 用到索引中的两个:通过key_len的长度可以看出来,比第一个大一点。或者通过ref:中用到了两个常量const 用到了…...

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

eclipse/STS(Spring Tool Suite)安装CDT环境(C/C++)
在线安装 help -> eclipse marketplace 可以发现,我所使用eclipse给我推荐安装的CDT是10.5版本 离线安装 下载离线安装包 下载地址:https://github.com/eclipse-cdt/cdt/blob/main/Downloads.md 可以看到利息安装包主要有如下四大类,…...

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

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

Win7设备和打印机里空白,0个对象,但是可以打印的处理办法
呉師傅 你是不是遇到过Win7系统打开设备和打印机的时候显示是空白的,0个设备的情况?要怎么操作才能解决这一问题呢,下面就分享一下如何处理这个问题的小方法大家可以尝试一下。 问题如下: 解决方法: 1、点击桌面左下…...

Python基础学习第六天:Python 数据类型
内置数据类型 在编程中,数据类型是一个重要的概念。 变量可以存储不同类型的数据,并且不同类型可以执行不同的操作。 在这些类别中,Python 默认拥有以下内置数据类型: 获取数据类型 您可以使用 type() 函数获取任何对象的数据…...

C++信息学奥赛1184:明明的随机数
#include <bits/stdc.h> using namespace std; int main() {int n; // 数组长度cin >> n; // 输入数组长度int arr[n]; // 定义整数数组,用于存储输入的整数// 输入数组元素for (int i 0; i < n; i){cin >> arr[i];}int e 0; // 计数器&…...

NoSQL技术——Redis
简单介绍 Redis是当下最流行的NoSQL数据库。在Redis中,数据的存储格式是以键值对的方式进行存储的。在键值对的存储形式中,值除了是常见的字符串,也可以是类似于Json对象的形式,或者是List,Map等数组格式,…...

【探索SpringCloud】服务发现-Nacos服务端数据结构和模型
前言 上一文中,我们从官方的图示了解到Nacos的服务数据结构。但我关心的是,Nacos2.x不是重构了吗?怎么还是这种数据结构?我推测,必然是为了对Nacos1.x的兼容,实际存储应该不是这样的。于是,沿着…...

基于简单的信息变换实现自然语言模型
题目:基于简单的信息变换实现自然语言模型 摘要:在自然语言处理中,自然语言模型是至关重要的。本论文提出了一种基于简单的信息变换实现自然语言模型的方法。该方法将输入信息进行一系列的信息变换,如分割、属性、等效替换、增加删除等变换,与原始信息进行比较,得知信息是…...

低配版消息队列,redis——Stream
消息队列实现:群发效果 redis原有的消息队列数据不会持久化,所以它加了一个Stream数据结构。 添加数据:XADD s1(组名) *(*为自动生成) key val 取出数据: XREAD COUNT 1(取出个数) BLOCK 1(队列为空时等待时间0为一直等) STREA…...

【OpenCV入门】第五部分——图像运算
文章结构 掩模图像的加法运算图像的位运算按位与运算按位或运算按位取反运算按位异或运算图像位运算的运用 合并图像加权和覆盖 掩模 当计算机处理图像时,有些内容需要处理,有些内容不需要处理。能够覆盖原始图像,仅暴露原始图像“感兴趣区域…...

【Seata】00 - Seata Server 部署(Windows、Docker 基于 Jpom)
文章目录 前言参考目录版本说明Windows 部署 seata-server1:下载压缩包2:文件存储模式3:db 存储模式3.1:建表3.2:修改配置文件3.3:启动脚本4:源码部署 Docker 部署 seata-server (基…...

菜鸟教程第一天
1、Java变量类型 1.1 成员变量可以声明在使用前或者使用后。这句话怎么理解? 大家都知道,如果你在代码中使用这个变量,但是在此之前没有声明这个变量,是会报错的。如果是局部变量,在使用前,必须得声明并初…...