android学习笔记

291 阅读13分钟
一:
  四大组件启动流程
  1.进程没起来,fork进程,joinin binder线程,ActivityThread.main执行Loop消息循环, 启动Application
  2.启动四大组件
  Activity
    ContextImpl.startActivity->ActivityThread.Instrumentation.execStartActivity->(binder)ActivityManager.startActivity
    ActivityManagerService.startActivity-> ActivityStarter.startActivityMayWait
    ActivityStarter.startActivityMayWait {
                ResolveInfo rInfo = mSupervisor.resolveIntent(通过包管理服务获取intent对应的四大组件信息)
                ActivityInfo aInfo = mSupervisor.resolveActivity(intent, rInfo, startFlags, profilerInfo);(获取intent对应的activiy组件信息)
    }
    ->ActivityStarter.startActivity
    ProcessRecord callerApp = mService.getRecordForAppLocked(caller); 找到调用方进程对象
    final int launchFlags = intent.getFlags();
    check(ActivityManager.START_INTENT_NOT_RESOLVED  ActivityManager.START_CLASS_NOT_FOUND。。。)检查intent对应activity是否存在异常
    if (err != START_SUCCESS) {
        // 各种检查失败返回错误结果
    }
    mSupervisor.checkStartAnyActivityPermission;包管理服务检查activity权限
    ActivityStartInterceptor.intercept;拦截处理activity启动
    ActivityRecord r = new ActivityRecord(mService, callerApp, callingPid, callingUid,
                    callingPackage, intent, resolvedType, aInfo, mService.getGlobalConfiguration(),
                    resultRecord, resultWho, requestCode, componentSpecified, voiceSession != null,
                    mSupervisor, checkedOptions, sourceRecord); 生成新启动activityRecord对象
    ActivityStarter.startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord,...) {
        setInitialState ams 全局变量记录当前启动mStartActivity activityRecord,intent,启动模式,源activityRecord等信息
        mIntent.setFlags(mLaunchFlags); 计算flags赋予intent
        ActivityRecord reusedActivity = getReusableIntentActivity(); 像LAUNCH_SINGLE_INSTANCE,activity复用
        if(reusedActivity != null) {
            设置新reusedActivity所在task为mStartActivity activityRecord所在task
            若task intent不存在,设置task intent为新mStartActivity intent
            if(FLAG_ACTIVITY_CLEAR_TOP) {
               final TaskRecord task = reusedActivity.getTask();
               final ActivityRecord top = task.performClearTaskForReuseLocked(mStartActivity,
                                    mLaunchFlags); clear_top模式finish该activity上面栈顶所有的activity,
               if (top != null) {
                     deliverNewIntent(top); 该activity执行onNewIntent
                 }
               mSupervisor.resumeFocusedStackTopActivityLocked(mTargetStack, null, mOptions); 确保当前栈顶activity是onResume的,否则走onResume
               return
            }
        }
        普通模式正常启动新activity
        判断栈顶activity是否是将要启动的activity
         final ActivityStack topStack = mSupervisor.mFocusedStack;
                final ActivityRecord topFocused = topStack.getTopActivity();
                final ActivityRecord top = topStack.topRunningNonDelayedActivityLocked(mNotTop);
                final boolean dontStart = top != null && mStartActivity.resultTo == null
                        && top.realActivity.equals(mStartActivity.realActivity)
                        && top.userId == mStartActivity.userId
                        && top.app != null && top.app.thread != null
                        && ((mLaunchFlags & FLAG_ACTIVITY_SINGLE_TOP) != 0
                        || isLaunchModeOneOf(LAUNCH_SINGLE_TOP, LAUNCH_SINGLE_TASK));
                if (dontStart) {
                     deliverNewIntent(top); 栈顶activity是将要启动的activity,该activity执行onNewIntent
                }

        普通模式正常启动新activity
        // Should this be considered a new task?
        mTargetStack.createTaskRecord(...) 创建新task
        mTargetStack.startActivityLocked(mStartActivity, topFocused, newTask, mKeepCurTransition,
                        mOptions);  将Activity移动到Stack的顶端
        mSupervisor.resumeFocusedStackTopActivityLocked(mTargetStack, mStartActivity,
                                mOptions)-> ActivityStack.resumeTopActivityInnerLocked (Activity切换调度的核心逻辑。)
        ActivityStack.resumeTopActivityInnerLocked {
                                     当前可见activity pause
                                     if (mResumedActivity != null) {
                                                   if (DEBUG_STATES) Slog.d(TAG_STATES,
                                                           "resumeTopActivityLocked: Pausing " + mResumedActivity);
                                                   // mResumedActivity不为空,pause这个Activity
                                                   pausing |= startPausingLocked(userLeaving, false, next, false);
                                      }
        }
        startPausingLocked
        {
          mService.getLifecycleManager().scheduleTransaction(prev.app.thread, prev.appToken,
                                PauseActivityItem.obtain(prev.finishing, userLeaving,
                                        prev.configChangeFlags, pauseImmediately)); ams通知进程pause activity,对应token appToken
        }

        -------------------- app pause, ams阻塞等待,app进程pause activity

        startPausingLocked {
          mService.getLifecycleManager().scheduleTransaction(prev.app.thread, prev.appToken,
                                PauseActivityItem.obtain(prev.finishing, userLeaving,
                                        prev.configChangeFlags, pauseImmediately)); 每一个生命周期事件封装成ActivityLifecycleItem继承类(PauseActivityItem/DestoryActivityItem/ResumeActivityItem/StopActivityItem)
          mClient.scheduleTransaction(this); (applicationThread scheduleTransaction)远程调用进入到activityThread.ApplicationThread
          activityThread.ApplicationThread 处理activity生命周期 applicationThread(binder) -> Handler(h)
          sendMessage(msg.what = EXECUTE_TRANSACTION msg.obj = PauseActivityItem ) Handler h;
          {
             case EXECUTE_TRANSACTION:
                                final ClientTransaction transaction = (ClientTransaction) msg.obj;
                                mTransactionExecutor.execute(transaction) {
                                     case ON_PAUSE:
                                     ActivityThread.handlePauseActivity() {
                                     {
                                        mInstrumentation.callActivityOnPause(r.activity); -> activity.onPause
                                        lifecycleItem.postExecute(mTransactionHandler, token, mPendingActions) {
                                            ActivityManager.getService().activityPaused(token); // 告知ams已经pause
                                        }
                                     }
                                     case ON_CREATE: {
                                      ActivityThread.handleLaunchActivity {
                                         ContextImpl appContext = createBaseContextForActivity(r);
                                                 Activity activity = null;
                                                 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);
                                                     }
                                                 } catch (Exception e) {
                                                     if (!mInstrumentation.onException(activity, e)) {
                                                         throw new RuntimeException(
                                                             "Unable to instantiate activity " + component
                                                             + ": " + e.toString(), e);
                                                     }
                                                 }

                                                 。。。
                                                 Application app = r.packageInfo.makeApplication(false, mInstrumentation);
                                                 。。。
                                                 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);
                                                 ...
                                                 mInstrumentation.callActivityOnCreate -> activity.onCreate
                                                 ....

                                      }

                                      case ON_RESUME:
                                          mTransactionHandler.handleResumeActivity {
                                             ...
                                             mInstrumentation.callActivityOnResume(this); -> activity.onResume
                                             ...
                                             r.window = r.activity.getWindow();
                                                         View decor = r.window.getDecorView();
                                                         decor.setVisibility(View.INVISIBLE);
                                                         ViewManager wm = a.getWindowManager();
                                                         WindowManager.LayoutParams l = r.window.getAttributes();
                                                         a.mDecor = decor;
                                                         l.type = WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
                                                         l.softInputMode |= forwardBit;
                                              wm.addView(decor, l); {
                                                ViewRootImpl root = new ViewRootImpl(view.getContext(), display);
                                                view.setLayoutParams(wparams);
                                                mViews.add(view);
                                                mRoots.add(root);
                                                mParams.add(wparams);
                                                ...
                                                root.setView(view, wparams, panelParentView); -> requestLayout(); 三大绘制流程
                                              }
                                              ...
                                              Looper.myQueue().addIdleHandler(new Idler()); {
                                                 handle增加idle事件,待idle事件处理时,发送idle事件给ams,用于ams执行可以destory的activity
                                                 遍历所有finish activity
                                                 am.activityIdle(a.token, a.createdConfig, stopProfiling);
                                              }
                                              ...
                                          }
                                     }
                                      case ON_DESTROY: {
                                        performPauseActivityIfNeeded->  mInstrumentation.callActivityOnPause(r.activity); -> activity.onPause
                                        callActivityOnStop -> activity.onnStop
                                        mInstrumentation.callActivityOnDestroy(r.activity); ->activity.onDestory
                                        ...
                                         View v = r.activity.mDecor;
                                        wm.removeViewImmediate(v);
                                        ...
                                        Context c = r.activity.getBaseContext();
                                                    if (c instanceof ContextImpl) {
                                                        ((ContextImpl) c).scheduleFinalCleanup(
                                                                r.activity.getClass().getName(), "Activity");
                                                    } 清理该activity资源-> LoadedApk.removeContextRegistrations {
                                                        ...
                                                        ArrayMap<BroadcastReceiver, LoadedApk.ReceiverDispatcher> rmap =
                                                                            mReceivers.remove(context); 找出该activity注册的所有广播接收器, 还在集合里说明没有主动unregister
                                                        IntentReceiverLeaked leak = new IntentReceiverLeaked(
                                                                                     what + " " + who + " has leaked IntentReceiver "
                                                                                     + rd.getIntentReceiver() + " that was " +
                                                                                     "originally registered here. Are you missing a " +
                                                                                     "call to unregisterReceiver()?"); 提示用户是否忘记unregisterReceiver
                                                        ...
                                                        try {
                                                            ActivityManager.getService().unregisterReceiver(
                                                                                        rd.getIIntentReceiver()); 主动帮用户取消注册广播接收器
                                                        } catch (RemoteException e) {
                                                            throw e.rethrowFromSystemServer();
                                                        }
                                                        ... 同理处理绑定服务
                                                        ArrayMap<ServiceConnection, LoadedApk.ServiceDispatcher> smap =
                                                                            mServices.remove(context);
                                                        ...
                                                        LoadedApk.ServiceDispatcher sd = smap.valueAt(i);
                                                                            ServiceConnectionLeaked leak = new ServiceConnectionLeaked(
                                                                                    what + " " + who + " has leaked ServiceConnection "
                                                                                    + sd.getServiceConnection() + " that was originally bound here");
                                                                            leak.setStackTrace(sd.getLocation().getStackTrace());
                                                                            Slog.e(ActivityThread.TAG, leak.getMessage(), leak); 提示用户是否忘记unbind
                                                        ...
                                                        ActivityManager.getService().unbindService(
                                                                                        sd.getIServiceConnection()); // 主动帮用户unBindService
                                                        ...
                                                    }
                                        ...
                                        ActivityManager.getService().activityDestroyed(token); ->通知ams清理该activity数据
                                      }
                                }

          }

          ...............activity 执行完pause之后
          ActivityManager.getService().activityPaused(token); // 告知ams已经pause
          回到ams->activityPaused->....->ActivityStack.resumeTopActivityUncheckedLocked -> resumeTopActivityInnerLocked-> {
            ...
             try {
               transaction.setLifecycleStateRequest(
                                                     ResumeActivityItem.obtain(next.app.repProcState,
                                                             mService.isNextTransitionForward()));
               mService.getLifecycleManager().scheduleTransaction(transaction); 通知applicationthread resume
             } catch(Exception) {
                出现异常
                ...
                mStackSupervisor.startSpecificActivityLocked(next, true, false) {
                    ProcessRecord app = mService.getProcessRecordLocked(r.processName,
                                    r.info.applicationInfo.uid, true); 获取即将resume的activity所属进程
                    if (app != null && app.thread != null) {
                        ...
                        realStartActivityLocked(r, app, andResume, checkConfig); {
                            ...
                            mService.updateLruProcessLocked(app, true, null);
                            mService.updateOomAdjLocked();
                            ...
                            mService.getLifecycleManager().scheduleTransaction(clientTransaction); 通知applicationthread resume
                        }
                        return
                        ...
                    }
                    startProcessLocked {

                         ProcessRecord app = newProcessRecordLocked(info, processName, isolated, isolatedUid); new新进程对象
                         startProcessLocked(app,...) 启动新进程
                         ...
                         Process.start(entryPoint,
                                                             app.processName, uid, uid, gids, runtimeFlags, mountExternal,
                                                             app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
                                                             app.info.dataDir, invokeWith,
                                                             new String[] {PROC_START_SEQ_IDENT + app.startSeq}); {
                                                                    Process处理逻辑
                                                                    zygoteProcess.start-> zygoteProcess.startViaZygote {
                                                                        ...
                                                                        组织进程参数
                                                                        ...
                                                                        zygoteProcess.zygoteSendArgsAndGetResult {
                                                                             // socket 写
                                                                             final BufferedWriter writer = zygoteState.writer;
                                                                             final DataInputStream inputStream = zygoteState.inputStream;
                                                                             writer.write(Integer.toString(args.size()));
                                                                             writer.newLine();
                                                                             writer.flush();
                                                                             ...
                                                                             //socket 读
                                                                             // Should there be a timeout on this?
                                                                             Process.ProcessStartResult result = new Process.ProcessStartResult();
                                                                             result.pid = inputStream.readInt();
                                                                             result.usingWrapper = inputStream.readBoolean();
                                                                             return result;
                                                                        }
                                                                    }
                                                             }
                         ...
                         ams进入阻塞,zygoteProcess fork进程
                         ZygoteServer {
                            LocalServerSocket {
                                    impl = new LocalSocketImpl();

                                    impl.create(LocalSocket.SOCKET_STREAM);

                                    localAddress = new LocalSocketAddress(name);
                                    impl.bind(localAddress);

                                    impl.listen(LISTEN_BACKLOG);
                            }

                            runSelectLoop {
                               if (i == 0) {
                                                ZygoteConnection newPeer = acceptCommandPeer(abiList);
                                                peers.add(newPeer);
                                                fds.add(newPeer.getFileDesciptor());
                               } else {
                                   try {
                                         ZygoteConnection connection = peers.get(i);
                                         final Runnable command = connection.processOneCommand(this);
                                                    ...
                                   }
                            }
                            ...->ZygoteConnection.processOneCommand {
                              ...
                              args = readArgumentList(); ->  { ... String s = mSocketReader.readLine(); ... }
                              parsedArgs = new Arguments(args);
                              pid = Zygote.forkAndSpecialize(parsedArgs.uid, parsedArgs.gid, parsedArgs.gids,
                                              parsedArgs.runtimeFlags, rlimits, parsedArgs.mountExternal, parsedArgs.seInfo,
                                              parsedArgs.niceName, fdsToClose, fdsToIgnore, parsedArgs.startChildZygote,
                                              parsedArgs.instructionSet, parsedArgs.appDataDir); -> Zygote.nativeForkAndSpecialize
                              try {
                                   if (pid == 0) { 子进程此处返回
                                              // in child
                                              zygoteServer.setForkChild();
                                              zygoteServer.closeServerSocket();
                                              IoUtils.closeQuietly(serverPipeFd);
                                              serverPipeFd = null;
                                              return handleChildProc(parsedArgs, descriptors, childPipeFd,
                                                      parsedArgs.startChildZygote);
                                    } else {
                                            父进程此处返回
                                              // In the parent. A pid < 0 indicates a failure and will be handled in
                                              // handleParentProc.
                                              IoUtils.closeQuietly(childPipeFd);
                                              childPipeFd = null;
                                              handleParentProc(pid, descriptors, serverPipeFd);
                                              return null;
                                       }
                                      } finally {
                                          IoUtils.closeQuietly(childPipeFd);
                                          IoUtils.closeQuietly(serverPipeFd);
                                      }
                              ...
                            }

                         }
                         ...
                           ZygoteConnection.handleChildProc {
                               子进程逻辑
                               closeSocket(); 关闭socket
                               if (!isZygote) {
                                        子进程跑这里
                                               return ZygoteInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs,
                                                       null /* classLoader */);
                                } else {

                                               return ZygoteInit.childZygoteInit(parsedArgs.targetSdkVersion,
                                                       parsedArgs.remainingArgs, null /* classLoader */);
                               }
                           }
                         ... ZygoteInit.childZygoteInit {
                            Runnable runable = RuntimeInit.findStaticMain {
                             cl = Class.forName(className, true, classLoader);
                             m = cl.getMethod("main", new Class[] { String[].class });
                            }
                             runable.run {
                                mMethod.invoke(null, new Object[] { mArgs }); 执行activityThread.main 入口方法
                             }
                         }
                        ... ZygoteInit.zygoteInit{
                            RuntimeInit.redirectLogStreams(); -> redirectLogStreams
                                重定向输出
                                 System.out.close();
                                  System.setOut(new AndroidPrintStream(Log.INFO, "System.out"));
                                  System.err.close();
                                  System.setErr(new AndroidPrintStream(Log.WARN, "System.err"));
                            }
                            RuntimeInit.commonInit(); {
                                ...线程默认异常捕捉器
                                Thread.setDefaultUncaughtExceptionHandler(new KillApplicationHandler(loggingHandler));
                                ...时间zone
                                TimeZone.setDefault(null);
                                ...http.agent
                                String userAgent = getDefaultUserAgent();
                                System.setProperty("http.agent", userAgent);
                                ...
                            }
                            ... 加入binder线程,进程天生具备binder能力,binder线程进入阻塞状态,等待消息,不会阻塞主线程
                            ZygoteInit.nativeZygoteInit(); -> AndroidRuntime.cpp(onZygoteInit) -> app_main.cpp virtual void onZygoteInit()
                                                                                       {
                                                                                           sp<ProcessState> proc = ProcessState::self();
                                                                                           ALOGV("App process: starting thread pool.\n");
                                                                                           proc->startThreadPool();
                                                                                       }
                                                           ->void ProcessState::startThreadPool()
                                                             {
                                                                 AutoMutex _l(mLock);
                                                                 if (!mThreadPoolStarted) {
                                                                     mThreadPoolStarted = true;
                                                                     spawnPooledThread(true);
                                                                 }
                                                             }

                                                          ---
                                                          String8 ProcessState::makeBinderThreadName() {
                                                              int32_t s = android_atomic_add(1, &mThreadPoolSeq);
                                                              pid_t pid = getpid();
                                                              String8 name;
                                                              name.appendFormat("Binder:%d_%X", pid, s);
                                                              return name;
                                                          }

                                                          void ProcessState::spawnPooledThread(bool isMain)
                                                          {
                                                              if (mThreadPoolStarted) {
                                                                  String8 name = makeBinderThreadName();
                                                                  ALOGV("Spawning new pooled thread, name=%s\n", name.string());
                                                                  sp<Thread> t = new PoolThread(isMain);
                                                                  t->run(name.string());
                                                              }
                                                          }
                                                          ---
                                                          PoolThread {
                                                            virtual bool threadLoop()
                                                                {
                                                                    IPCThreadState::self()->joinThreadPool(mIsMain);
                                                                    return false;
                                                                }
                                                          }
                                                         ---
                            ...
                            runable = findStaticMain(args.startClass, args.startArgs, classLoader);
                            ...
                            runable.run {
                                  mMethod.invoke(null, new Object[] { mArgs }); 执行activityThread.main 入口方法 BootClassLoader 加载的
                            }
                        }
                    }
                }
                ...
                -------------进程起来执行activityThread.main
                final ApplicationThread mAppThread = new ApplicationThread();
                activityThread.main {
                  ...
                  Looper.prepareMainLooper();
                  ActivityThread thread = new ActivityThread();
                          thread.attach(false, startSeq); -> {
                            final IActivityManager mgr = ActivityManager.getService();
                                        try {
                                            mgr.attachApplication(mAppThread, startSeq);
                                        } catch (RemoteException ex) {
                                            throw ex.rethrowFromSystemServer();
                                        }
                          }
                  Looper.loop();
                }
                ...
                -----------attachApplication回到ams.attachApplication {
                    ...
                      AppDeathRecipient adr = new AppDeathRecipient(
                                        app, pid, thread);
                                thread.asBinder().linkToDeath(adr, 0);
                    ...
                     thread.bindApplication (初始化应用LoaderApk, classLoader(PathClassLoader)/ 类加载Instrumentation/applition并各自初始化
                    ...
                    mStackSupervisor.attachApplicationLocked(app) 启动top visible activity -> ActivityStackSupervisor.realStartActivityLocked ->
                     {
                        final ClientTransaction clientTransaction = ClientTransaction.obtain(app.thread,r.appToken);
                        clientTransaction.addCallback(LaunchActivityItem.obtain(new Intent(r.intent),
                        ...
                        mService.getLifecycleManager().scheduleTransaction(clientTransaction);
                     }

                    ...
                    mServices.attachApplicationLocked(app, processName); // Find any services that should be running in this process...
                    ...
                    sendPendingBroadcastsLocked(app); // Check if a next-broadcast receiver is in this process...

                    上面三个处理得到badApp didSomething
                    if (badApp) {
                         handleAppDiedLocked(app, false, true);
                         return false;
                    }
                    if (!didSomething) {
                         updateOomAdjLocked();
                    }

                }
                ----------回到进程activityThread.bindApplication->Handler(h)->(msg.what)BIND_APPLICATION->

                private void handleBindApplication(AppBindData data) {
                    ...
                    data.info = getPackageInfoNoCheck(data.appInfo, data.compatInfo);->  {
                        mPackages缓存获取LoadedApk
                        不存在 new LoadedApk
                        packageInfo = new LoadedApk(this, aInfo, compatInfo, baseLoader,securityViolation, includeCode &&  (aInfo.flags&ApplicationInfo.FLAG_HAS_CODE) != 0, registerPackage);
                        保存到缓存中
                        mPackages.put(aInfo.packageName,new WeakReference<LoadedApk>(packageInfo));
                        ...
                        LoadedApk 动态创建classLoader
                    }
                    ...
                    final ContextImpl appContext = ContextImpl.createAppContext(this, data.info);
                    final ContextImpl instrContext = ContextImpl.createAppContext(this, pi); // LoadedApk 动态创建classLoader, 判断空则初始化classLoader
                    try {
                        final ClassLoader cl = instrContext.getClassLoader();
                        mInstrumentation = (Instrumentation)
                            cl.loadClass(data.instrumentationName.getClassName()).newInstance(); // classLoader 加载Instrumentation
                    } catch (Exception e) {
                        throw new RuntimeException(
                            "Unable to instantiate instrumentation "
                            + data.instrumentationName + ": " + e.toString(), e);
                    }
                    mInstrumentation.init // mInstrumentation初始化
                    ...
                    Application app = data.info.makeApplication(data.restrictedBackupMode, null); {
                        ...
                        String appClass = mApplicationInfo.className;
                        ...
                        java.lang.ClassLoader cl = getClassLoader();
                                    if (!mPackageName.equals("android")) {
                                        Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER,
                                                "initializeJavaContextClassLoader");
                                        initializeJavaContextClassLoader();
                                        Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                                    }
                        ContextImpl appContext = ContextImpl.createAppContext(mActivityThread, this);
                        app = mActivityThread.mInstrumentation.newApplication(cl, appClass, appContext); -> Application.attach-> Application.attachBaseContext(context);
                        appContext.setOuterContext(app);
                        ...
                        instrumentation.callApplicationOnCreate(app); -> application.onCreate
                    } // LoadedApk classLoader加载

                    LoaderApk {
                        createOrUpdateClassLoaderLocked 初始化classLoader ->
                        ApplicationLoaders.getDefault().getClassLoader {
                            ClassLoader baseParent = ClassLoader.getSystemClassLoader().getParent(); BootClassLoader
                            ...
                             ClassLoader classloader = ClassLoaderFactory.createClassLoader(
                                                    zip,  librarySearchPath, libraryPermittedPath, parent,
                                                    targetSdkVersion, isBundled, classLoaderName);
                             ->ClassLoaderFactory.createClassLoader(dexPath, librarySearchPath, parent,
                                                                  classloaderName);
                             ->return new PathClassLoader(dexPath, librarySearchPath, parent);  用于加载程序中我们自己写的类。例如MyApplication、MainActivity等
                        }
                    }

                    ...
                    classLoader加载器区别
                    {
                        cl = Class.forName(className, true, classLoader); ActivityThread 类加载通过Class.forName
                        final ClassLoader cl = instrContext.getClassLoader();  android应用内Instrumentation/application/activity/Service等各个组件通过 ClassLoader.loadClass,来源于LoadedApk 生成的PathClassLoader
                        mInstrumentation = (Instrumentation)cl.loadClass(data.instrumentationName.getClassName()).newInstance();
                    }
                    ...LoadedApk 加载资源
                    {
                        {
                                if (mResources == null) {
                                    final String[] splitPaths;
                                    try {
                                        splitPaths = getSplitPaths(null);
                                    } catch (NameNotFoundException e) {
                                        // This should never fail.
                                        throw new AssertionError("null split not found");
                                    }

                                    mResources = ResourcesManager.getInstance().getResources(null, mResDir,
                                            splitPaths, mOverlayDirs, mApplicationInfo.sharedLibraryFiles,
                                            Display.DEFAULT_DISPLAY, null, getCompatibilityInfo(),
                                            getClassLoader());
                                }
                                return mResources;
                            }
                    }
                    ...LoadedApk(代码路径(dex)资源路径 classLoader Resources ActivityThread Application) apk代表
                    ...ContextImpl(ActivityThread classLoader Resources LoadedApk) 上下文代表
                }



             }

             ....
          }

        }

     }

     BroadcastReceiver
     动态注册
     ContextImpl.registerReceiver(BroadcastReceiver, intentFilter) ->
     ContextImpl.registerReceiverInternal {
        ...
        IIntentReceiver rd = null;
        // 缓存机制获取IIntentReceiver
        // BroadcastReceiver 是一个普通对象, 不具备binder传输能力
        // 封装BroadcastReceiver到一个binder对象里面,该binder对象是ReceiverDispatcher的内部类,通过内置handler从binder线程切到主线程执行BroadcastReceiver
        rd = mPackageInfo.getReceiverDispatcher(
                            receiver, context, scheduler,
                            mMainThread.getInstrumentation(), true);
        ...
        // 传输到ams的binder对象, 封装了BroadcastReceiver,主线程handler
        final static class InnerReceiver extends IIntentReceiver.Stub {
            public void performReceive(Intent intent, int resultCode, String data,
                                Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
                  // ams找到该binder,通知广播, 该binder对象是ReceiverDispatcher的内部类
                  // 执行外部类ReceiverDispatcher performReceive方法
                  rd.performReceive {
                   final Args args = new Args(intent, resultCode, data, extras, ordered,
                                      sticky, sendingUser); // 封装intent数据到Runnable
                    mActivityThread.post(args.getRunnable()); // 主线程handler发送该Runnable
                    // 该runnable
                    public final Runnable getRunnable() {
                                    return () -> {
                        ...外部类的BroadcastReceiver对象
                        final BroadcastReceiver receiver = mReceiver;
                        ...BroadcastReceiver
                        ClassLoader cl = mReceiver.getClass().getClassLoader();
                        intent.setExtrasClassLoader(cl);
                        intent.prepareToEnterProcess();
                        setExtrasClassLoader(cl);
                        receiver.setPendingResult(this);
                        receiver.onReceive(mContext, intent); // 执行BroadcastReceiver onReceive方法
                        ...
                        am.finishReceiver // 通知ams广播接收处理结束
                        ...
                    }
                  }
            }
        }
        静态注册广播
        packagemanagerService 扫描文件得到所有静态广播信息,activitymanagerService发送广播时通过pms便可查询到静态广播
        动态广播/静态广播在不同数据集合,动态广播优先静态广播处理, 后续分析
        粘性广播(当广播尚未注册,发送粘性广播ams会保存在集合里,待相关广播接收器注册时会处理粘性广播,类似Eventbus粘性事件)
        发送广播
        ContextImpl.sendBroadcast-> ams.broadcastIntent(ApplicationThread, intent ...)
        -> ams.broadcastIntentLocked {
            ...
            isProtectedBroadcast = AppGlobals.getPackageManager().isProtectedBroadcast(action); // 是否是保护类型广播
            ...
            final boolean isCallerSystem;
                    switch (UserHandle.getAppId(callingUid)) {
                        case ROOT_UID:
                        case SYSTEM_UID:
                        case PHONE_UID:
                        case BLUETOOTH_UID:
                        case NFC_UID:
                        case SE_UID:
                            isCallerSystem = true;
                            break;
                        default:
                            isCallerSystem = (callerApp != null) && callerApp.persistent;
                            break;
                    }
            ..
            if (!isCallerSystem) {
                        if (isProtectedBroadcast) {
                          // 非系统应用不能发送被保护广播
                            String msg = "Permission Denial: not allowed to send broadcast "
                                    + action + " from pid="
                                    + callingPid + ", uid=" + callingUid;
                            Slog.w(TAG, msg);
                            throw new SecurityException(msg);
                        } {
                            ...判断包空
                            if (callerPackage == null) { ... throw new SecurityException(msg);
                            ...判断intent组件包名是否匹配
                            if (!intent.getComponent().getPackageName().equals(
                                                        callerPackage)) { ... throw new SecurityException(msg); }
                            ...
                            intent.setPackage(callerPackage);
                        }
            }
            ...
             // Add to the sticky list if requested.处理粘性广播,增加到粘性广播集合
             if(sticky) {
                 ...判断应用是否有粘性广播权限
                 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
                                                 callingPid, callingUid)
                                                 != PackageManager.PERMISSION_GRANTED) {throw new SecurityException(msg);}

                ... requiredPermissions权限判断提示需要
                ... intent组件判断是否存在,粘性广播不允许指定target
                ...
                // 每个action可以对应多个intent(intent可不只action属性), String action -> ArrayList<Intent>
                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
                            if (stickies == null) {
                                stickies = new ArrayMap<>();
                                mStickyBroadcasts.put(userId, stickies);
                            }
                            ArrayList<Intent> list = stickies.get(intent.getAction());
                            if (list == null) {
                                list = new ArrayList<>();
                                stickies.put(intent.getAction(), list);
                            }
                            final int stickiesCount = list.size();
                            int i;
                            for (i = 0; i < stickiesCount; i++) {
                                // 判断是否intent已经存在,存在则替换
                                if (intent.filterEquals(list.get(i))) {
                                    // This sticky already exists, replace it.
                                    list.set(i, new Intent(intent));
                                    break;
                                }
                            }
                            if (i >= stickiesCount) {
                                list.add(new Intent(intent));
                            }
             }
             // Figure out who all will receive this broadcast.
             // 找到接收广播者
             // intent - intentFilter - broadcastReceiver关系
             // 一个intentFilter可匹配多个intent,一个intent可找到多个合适的intentFilter 一个broadcastReceiver可以注册多个intentFilter
             List<BroadcastFilter> registeredReceivers = null; // 根据intent找到所有符合的intentFilter

             List receivers = null; // 静态广播集合
             List<BroadcastFilter> registeredReceivers = null; // 动态广播集合
             // Need to resolve the intent to interested receivers...
                     if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
                              == 0) {
                         receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
                     }
                     // 广播基本上不指定target
                     if (intent.getComponent() == null) {
                         if (userId == UserHandle.USER_ALL && callingUid == SHELL_UID) {
                             // Query one target user at a time, excluding shell-restricted users
                             for (int i = 0; i < users.length; i++) {
                                 if (mUserController.hasUserRestriction(
                                         UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
                                     continue;
                                 }
                                 List<BroadcastFilter> registeredReceiversForUser =
                                         mReceiverResolver.queryIntent(intent,
                                                 resolvedType, false /*defaultOnly*/, users[i]);
                                 if (registeredReceivers == null) {
                                     registeredReceivers = registeredReceiversForUser;
                                 } else if (registeredReceiversForUser != null) {
                                     registeredReceivers.addAll(registeredReceiversForUser);
                                 }
                             }
                         } else {
                             // 查询所有动态注册的广播接收器中匹配该intent的项
                             registeredReceivers = mReceiverResolver.queryIntent(intent,
                                     resolvedType, false /*defaultOnly*/, userId);
                         }
                     }
                     int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
                             if (!ordered && NR > 0) {
                                ...
                                // 处理动态广播
                                final BroadcastQueue queue = broadcastQueueForIntent(intent);
                                            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
                                                    callerPackage, callingPid, callingUid, callerInstantApp, resolvedType,
                                                    requiredPermissions, appOp, brOptions, registeredReceivers, resultTo,
                                                    resultCode, resultData, resultExtras, ordered, sticky, false, userId);
                                            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing parallel broadcast " + r);
                                            final boolean replaced = replacePending
                                                    && (queue.replaceParallelBroadcastLocked(r) != null);
                                            // Note: We assume resultTo is null for non-ordered broadcasts.
                                if (!replaced) {
                                                queue.enqueueParallelBroadcastLocked(r); // 广播进入并行队列
                                                queue.scheduleBroadcastsLocked(); // 执行并行队列广播 -> {
                                                    BroadcastQueue.processNextBroadcastLocked {
                                                        for (int i=0; i<N; i++) {
                                                                        Object target = r.receivers.get(i);
                                                                        if (DEBUG_BROADCAST)  Slog.v(TAG_BROADCAST,
                                                                                "Delivering non-ordered on [" + mQueueName + "] to registered "
                                                                                + target + ": " + r);
                                                                        deliverToRegisteredReceiverLocked(r, (BroadcastFilter)target, false, i); ->
                                                                         // IPC处理广播接收
                                                                         performReceiveLocked(filter.receiverList.app, filter.receiverList.receiver,
                                                                                                new Intent(r.intent), r.resultCode, r.resultData,
                                                                                                r.resultExtras, r.ordered, r.initialSticky, r.userId); ->
                                                                                                receiver.performReceive(intent, resultCode, data, extras, ordered,
                                                                                                                    sticky, sendingUser);
                                                        }
                                                    }
                                                }
                                                静态广播处理
                                                ... 按优先级排序
                                                while (it < NT && ir < NR) {
                                                                if (curt == null) {
                                                                    curt = (ResolveInfo)receivers.get(it);
                                                                }
                                                                if (curr == null) {
                                                                    curr = registeredReceivers.get(ir);
                                                                }
                                                                if (curr.getPriority() >= curt.priority) {
                                                                    // Insert this broadcast record into the final list.
                                                                    receivers.add(it, curr);
                                                                    ir++;
                                                                    curr = null;
                                                                    it++;
                                                                    NT++;
                                                                } else {
                                                                    // Skip to the next ResolveInfo in the final list.
                                                                    it++;
                                                                    curt = null;
                                                                }
                                                            }
                                                 ... 进入串行广播队列
                                                 queue.enqueueOrderedBroadcastLocked(r);
                                                 queue.scheduleBroadcastsLocked();
                                                 ... 处理串行广播
                                                 {
                                                    while {
                                                    ...
                                                    if (mService.mProcessesReady && r.dispatchTime > 0) {
                                                                    long now = SystemClock.uptimeMillis();
                                                                    if ((numReceivers > 0) &&
                                                                            (now > r.dispatchTime + (2*mTimeoutPeriod*numReceivers))) {
                                                                        Slog.w(TAG, "Hung broadcast ["
                                                                                + mQueueName + "] discarded after timeout failure:"
                                                                                + " now=" + now
                                                                                + " dispatchTime=" + r.dispatchTime
                                                                                + " startTime=" + r.receiverTime
                                                                                + " intent=" + r.intent
                                                                                + " numReceivers=" + numReceivers
                                                                                + " nextReceiver=" + r.nextReceiver
                                                                                + " state=" + r.state);
                                                                        broadcastTimeoutLocked(false); // forcibly finish this broadcast
                                                                        forceReceive = true;
                                                                        r.state = BroadcastRecord.IDLE;
                                                                    }
                                                                }

                                                      ...
                                                      // 该广播第一次并不会走这里,该广播接收器都处理完了, 会通知ams该广播处理结束,然后清空receivers
                                                                  // 进入这里之后表示该广播处理完成,移除超时消息,加入历史记录,移除队列中数据
                                                                  // 重新循环队列
                                                                  if (r.receivers == null || r.nextReceiver >= numReceivers
                                                                          || r.resultAbort || forceReceive) {
                                                                      // No more receivers for this broadcast!  Send the final
                                                                      // result if requested...
                                                                      ...移除超时消息
                                                                      cancelBroadcastTimeoutLocked();
                                                                      addBroadcastToHistoryLocked(r);
                                                                      if (r.intent.getComponent() == null && r.intent.getPackage() == null
                                                                              && (r.intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
                                                                          // This was an implicit broadcast... let's record it for posterity.
                                                                          mService.addBroadcastStatLocked(r.intent.getAction(), r.callerPackage,
                                                                                  r.manifestCount, r.manifestSkipCount, r.finishTime-r.dispatchTime);
                                                                      }
                                                                      // 将该广播从串行队列移除
                                                                      mOrderedBroadcasts.remove(0);
                                                                      // r置为null,while循环继续遍历串行队列中的广播
                                                                      r = null;
                                                                      looped = true;
                                                                      continue;
                                                                  }
                                                              } while (r == null);

                                                              ... 处理该广播
                                                              ...判断进程是否起来,启动相关接收器进程
                                                              ... ipc
                                                 }
                                                 每个串行广播接收处理之后,会发出sendFinished
                                                 执行ams.finishReceiver
                                                 ...
                                                 BroadcastQueue queue = (flags & Intent.FLAG_RECEIVER_FOREGROUND) != 0
                                                                         ? mFgBroadcastQueue : mBgBroadcastQueue;
                                                                 r = queue.getMatchingOrderedReceiver(who);
                                                                 if (r != null) {
                                                                     // 该广播执行完毕,处理下一个串行广播
                                                                     doNext = r.queue.finishReceiverLocked(r, resultCode,
                                                                         resultData, resultExtras, resultAbort, true);
                                                                 }
                                                                 if (doNext) {
                                                                     // 处理下一个串行广播
                                                                     r.queue.processNextBroadcastLocked(/*fromMsg=*/ false, /*skipOomAdj=*/ true);
                                                                 }




                                }
                                ...
                             }
                          ... 并行广播,会直接遍历所有接收器ipc分发到app进程中, 并行广播耗时不会影响ams对其他广播的处理
                          ... 串行广播,当前广播接收器处理完之后,通知ams广播接收处理结束, 继续下一个广播处理, 串行广播耗时会影响ams对其他广播的处理,ams通过超时机制保证稳定性
                          ... 对app进程而言,所有广播分发最后都会进入handler,广播接收器处理超时会影响其他广播/主线程
        }

        service
        contextImpl.startService->ams.startService-> ams.startServiceLocked{

             ... 查找service
             ServiceLookupResult res =
                         retrieveServiceLocked(...) {
                             ...
                             从缓存中查找,查找失败从包管理服务查找
                             ServiceMap smap = getServiceMapLocked(userId);
                             ...
                             ResolveInfo rInfo = mAm.getPackageManagerInternalLocked().resolveService(service,
                                                                   resolvedType, flags, userId, callingUid);
                             ...包管理服务找到后加入缓存
                             smap.mServicesByName.put(name, r);

                         }
              ... 判断服务所在进程是否存在
              if (proc == null || proc.curProcState > ActivityManager.PROCESS_STATE_RECEIVER) {
                  ...
                  smap.mDelayedStartList.add(r); // 加入延迟启动列表
                  addToStarting = true;
              }
              ActiveServices.startServiceInnerLocked->ActiveServices.bringUpServiceLocked-> {
                ...
                if (r.app != null && r.app.thread != null) { // 该服务进程已经起来
                      sendServiceArgsLocked(r, execInFg, false); -> applicationThread-> service.onStartCommand
                      return null;
                }

                ...
                realStartServiceLocked {
                  // 如果进程存在
                  app.thread.scheduleCreateService(r, r.serviceInfo,
                                    mAm.compatibilityInfoForPackageLocked(r.serviceInfo.applicationInfo),
                                    app.repProcState);
                                   ---> ActivityThread.handleCreateService((CreateServiceData)msg.obj);
                                   ---> {
                                      ...
                                      LoadedApk packageInfo = getPackageInfoNoCheck(
                                                      data.info.applicationInfo, data.compatInfo);
                                              Service service = null;
                                              try {
                                                  java.lang.ClassLoader cl = packageInfo.getClassLoader();
                                                  service = packageInfo.getAppFactory()
                                                          .instantiateService(cl, data.info.name, data.intent); // classLoader加载对应service
                                      ...
                                      ContextImpl context = ContextImpl.createAppContext(this, packageInfo);
                                                  context.setOuterContext(service);
                                      Application app = packageInfo.makeApplication(false, mInstrumentation);
                                      service.attach(context, this, data.info.name, data.token, app, // service初始化
                                      ActivityManager.getService());
                                      service.onCreate(); // service onCreate
                                      mServices.put(data.token, service); // token 是ams serviceRecord对象
                                   }
                   // 如果进程不存在
                   ...
                   app=mAm.startProcessLocked()
                   // 保存该serviceRecord到mPendingServices
                    if (!mPendingServices.contains(r)) {
                               mPendingServices.add(r);
                    }
                   ...
                   applicationThread.attachApplication->ams.attachApplicationLocked->ActiveServices.attachApplicationLocked {
                        ... // mPendingServices 待启动的service
                          for (int i=0; i<mPendingServices.size(); i++) {
                                            sr = mPendingServices.get(i);
                                            if (proc != sr.isolatedProc && (proc.uid != sr.appInfo.uid
                                                    || !processName.equals(sr.processName))) {
                                                continue;
                                            }

                                            mPendingServices.remove(i);
                                            i--;
                                            proc.addPackage(sr.appInfo.packageName, sr.appInfo.longVersionCode,
                                                    mAm.mProcessStats);
                                            realStartServiceLocked(sr, proc, sr.createdFromFg);
                                            ...
                       }
                   }
                }
              }
             }

            bindservice
            ams.bindServiceLocked -> ActiveServices.bindServiceLocked {
                ...// 查找对应服务service
                ServiceLookupResult res =
                    retrieveServiceLocked();
                    ServiceRecord s = res.record;
                    ...
                     // 记录连接
                     AppBindRecord b = s.retrieveAppBindingLocked(service, callerApp);
                                ConnectionRecord c = new ConnectionRecord(b, activity,
                                        connection, flags, clientLabel, clientIntent);

                                IBinder binder = connection.asBinder();
                                ArrayList<ConnectionRecord> clist = s.connections.get(binder);
                                if (clist == null) {
                                    clist = new ArrayList<ConnectionRecord>();
                                    s.connections.put(binder, clist);
                                }
                                clist.add(c);
                                b.connections.add(c);
                                if (activity != null) {
                                    if (activity.connections == null) {
                                        activity.connections = new HashSet<ConnectionRecord>();
                                    }
                                    activity.connections.add(c);
                                }
                                b.client.connections.add(c);
                      ...
                       if (s.app != null && b.intent.received) {
                                      // Service is already running, so we can immediately
                                      // publish the connection.
                                      try {
                                          c.conn.connected(s.name, b.intent.binder, false);  // 找到connection binder,执行connect
                                      } catch (Exception e) {
                                          Slog.w(TAG, "Failure sending service " + s.shortName
                                                  + " to connection " + c.conn.asBinder()
                                                  + " (in " + c.binding.client.processName + ")", e);
                                      }
                                } else {
                                ...
                                  requestServiceBindingLocked(s, b.intent, callerFg, false); // 请求service执行handleBindService
                                }

            }
            activityThread->applicationThread.handleBindService {
                Service s = mServices.get(data.token);
                ...
                   IBinder binder = s.onBind(data.intent);
                   ActivityManager.getService().publishService(
                                                data.token, data.intent, binder);
            }
            ams.publishService->activeServices.publishServiceLocked {
                ...
                  for (int conni=r.connections.size()-1; conni>=0; conni--) {
                                        ArrayList<ConnectionRecord> clist = r.connections.valueAt(conni);
                                        for (int i=0; i<clist.size(); i++) {
                                            ConnectionRecord c = clist.get(i);
                                            ...
                                            c.conn.connected(r.name, service, false);
                                            }
            }
        }


     }
     // 缓存机制获取IIntentReceiver
     public IIntentReceiver getReceiverDispatcher(BroadcastReceiver r,
                 Context context, Handler handler,
                 Instrumentation instrumentation, boolean registered) {
             synchronized (mReceivers) {
                 LoadedApk.ReceiverDispatcher rd = null;
                 ArrayMap<BroadcastReceiver, LoadedApk.ReceiverDispatcher> map = null;
                 if (registered) {
                     map = mReceivers.get(context);
                     if (map != null) {
                         rd = map.get(r);
                     }
                 }
                 if (rd == null) {
                     rd = new ReceiverDispatcher(r, context, handler,
                             instrumentation, registered);
                     if (registered) {
                         if (map == null) {
                             map = new ArrayMap<BroadcastReceiver, LoadedApk.ReceiverDispatcher>();
                             mReceivers.put(context, map);
                         }
                         map.put(r, rd);
                     }
                 } else {
                     rd.validate(context, handler);
                 }
                 rd.mForgotten = false;
                 return rd.getIIntentReceiver();
             }
         }




二:
  包解析
  packagemanagerService(apk信息/apk卸载安装)
  扫描apk(扫描AndroidManifest.xml), 线程池扫描apk,阻塞队列存储扫描结果package
  ParallelPackageParser->PackageParser.parse->AndroidManifest.xml->PackageParser.package
  安装: 安装ui->packageinstallerService->packagemanagerService->installer->InstalldNativeService(binder)
  framework pm内部将对外接口保存在LocalService缓存
   LocalServices.addService(
                      PackageManagerInternal.class, new PackageManagerInternalImpl());
  跨进程中将服务加入managerservice
   public static PackageManagerService main(Context context, Installer installer,
              boolean factoryTest, boolean onlyCore) {
          // Self-check for initial settings.
          PackageManagerServiceCompilerMapping.checkProperties();

          PackageManagerService m = new PackageManagerService(context, installer,
                  factoryTest, onlyCore);
          m.enableSystemUserPackages();
          ServiceManager.addService("package", m);
          final PackageManagerNative pmn = m.new PackageManagerNative();
          ServiceManager.addService("package_native", pmn);
          return m;
      }

三:
  class加载
  资源加载
  classloader.loadClass-> {
        Class<?> c = findLoadedClass(name); // 从缓存中查找
              if (c == null) { // 缓存中没有
                  try {
                      if (parent != null) { // 判断是否有parent
                          c = parent.loadClass(name, false); // parent加载类(递归)
                      } else {
                          c = findBootstrapClassOrNull(name); // 当前classLoader没有parent类,通过BootstrapClassLoader加载类
                      }
                  } catch (ClassNotFoundException e) {
                      // ClassNotFoundException thrown if class not found
                      // from the non-null parent class loader
                  }

                  if (c == null) {
                      // If still not found, then invoke findClass in order
                      // to find the class.
                      c = findClass(name); // 每个递归类通过自己的findClass方法查找类,找到就返回结果
                  }
              }
              return c;
  }

  BaseDexClassLoader extends ClassLoader {
    ...
    private final DexPathList pathList;
    ...
    protected Class<?> findClass(String name) throws ClassNotFoundException {
            List<Throwable> suppressedExceptions = new ArrayList<Throwable>();
            Class c = pathList.findClass(name, suppressedExceptions);
            if (c == null) {
                ...
                throw cnfe;
            }
            return c;
        }
  }

  DexPathList {
    ...
    private Element[] dexElements; // 每个Element代表一个dex
    ...
    public Class<?> findClass(String name, List<Throwable> suppressed) {
            for (Element element : dexElements) { // 遍历所有element即所有dex查找类,找到则返回
                Class<?> clazz = element.findClass(name, definingContext, suppressed);
                if (clazz != null) {
                    return clazz;
                }
            }

            if (dexElementsSuppressedExceptions != null) {
                suppressed.addAll(Arrays.asList(dexElementsSuppressedExceptions));
            }
            return null;
        }
  }

  static class Element {
          // dex文件路径
          private final File path;

          private final DexFile dexFile; // 该dex文件
          ...
          public Class<?> findClass(String name, ClassLoader definingContext,
                          List<Throwable> suppressed) {
                      return dexFile != null ? dexFile.loadClassBinaryName(name, definingContext, suppressed)
                              : null;
          }
          ...
  }

  动态加载jar/apk class方法有:
  1. 构建PathClassLoader PathClassLoader classloader = new PathClassLoader((String dexPath, String librarySearchPath, ClassLoader parent))
  2. 构建DexClassLoader DexClassLoader classLoader = new DexClassLoader(String dexPath, String optimizedDirectory,
                                                                                 String librarySearchPath, ClassLoader parent)
  两者目前并无大差别,均可加载外部jar/apk, DexClassLoader可提供optimizedDirectory(odex目录)PathClassLoader不提供默认在apk同级目录下oat
  热修复方案:
  1. 构建插件PathClassLoader,反射拿到DexPathList pathList,DexPathList再反射拿到Element[]
     同理反射拿到宿主classLoader Element[],将插件Element[] 和宿主Element[]合并,插件Element[]放在数组前面,合并的Element[]重新反射赋予宿主classLoader Element[]
     注意:同一个类里执行合并Element[],new某一个插件类会存在指令重拍? 优先加载了宿主的类?
     存在问题?
  插件化方案:
     每个插件均可构建插件的DexClassLoader用于加载插件的类, 可单独作为一个classLoader,也可像热修复一样和宿主classLoader合并(资源冲突)
     问题:四大组件生命周期
     1. 占坑类欺骗framework(反射)
     2. 使用宿主能力

四: AOP
    1. 编译期生成辅助类代码java文件(apt, javapoet)
    2. javasist等字节码编辑,修改class文件