Activity启动主要流程以及Window创建时机小结

来源:http://www.sh-fengwen.com 作者:鲜果干果 人气:123 发布时间:2019-10-03
摘要:1、简单描述下本次记录的内容:Android就是消息驱动,应用靠着Looper保持运行,若Looper退出,应用也就挂了,Android启动Application或Activity都是IPC过程,靠ActivityManagerService这个系统进程启

图片 1

1、简单描述下本次记录的内容:Android就是消息驱动,应用靠着Looper保持运行,若Looper退出,应用也就挂了,Android启动Application或Activity都是IPC过程,靠ActivityManagerService这个系统进程启动,在系统进程回调ApplicationThread像scheduleLaunchActivity从而开始了Activity的生命周期,因为系统进程的回调是在Binder线程池,所以通过Handler回调UI线程。

首先,我们定义一个只包含开始与结束节点的流程:

2、从ActivityThread的main开始,应用的启动的入口,注意的是ActivityThread是个类,new的时候才有线程:

图片 2

 public static void main(String[] args) {

        ........

        Looper.prepareMainLooper();   //创建主Looper

        ActivityThread thread = new ActivityThread();  //创建UI线程
        thread.attach(false);   //开始启动,下面分析

        if (sMainThreadHandler == null) {
            sMainThreadHandler = thread.getHandler();
        }

        if (false) {
            Looper.myLooper().setMessageLogging(new
                    LogPrinter(Log.DEBUG, "ActivityThread"));
        }

        // End of event ActivityThreadMain.
        Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
        Looper.loop();   //死循环,Android保证一直有消息存在,否则执行完下面就抛异常

        throw new RuntimeException("Main thread loop unexpectedly exited");
    }

流程定义描述文件:

下面看下thread.attach(false),false表示非系统:

<?xml version="1.0" encoding="UTF-8"?><definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:activiti="http://activiti.org/bpmn" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:omgdc="http://www.omg.org/spec/DD/20100524/DC" xmlns:omgdi="http://www.omg.org/spec/DD/20100524/DI" typeLanguage="http://www.w3.org/2001/XMLSchema" expressionLanguage="http://www.w3.org/1999/XPath" targetNamespace="http://www.activiti.org/test"> <process name="firstProcess" isExecutable="true"> <startEvent name="startevent1"></startEvent> <endEvent name="End"></endEvent> <sequenceFlow sourceRef="startevent1" targetRef="endevent1"></sequenceFlow> </process> <bpmndi:BPMNDiagram > <bpmndi:BPMNPlane bpmnElement="firstProcess" > <bpmndi:BPMNShape bpmnElement="startevent1" > <omgdc:Bounds height="35.0" width="35.0" x="270.0" y="200.0"></omgdc:Bounds> </bpmndi:BPMNShape> <bpmndi:BPMNShape bpmnElement="endevent1" > <omgdc:Bounds height="35.0" width="35.0" x="350.0" y="200.0"></omgdc:Bounds> </bpmndi:BPMNShape> <bpmndi:BPMNEdge bpmnElement="flow1" > <omgdi:waypoint x="305.0" y="217.0"></omgdi:waypoint> <omgdi:waypoint x="350.0" y="217.0"></omgdi:waypoint> </bpmndi:BPMNEdge> </bpmndi:BPMNPlane> </bpmndi:BPMNDiagram></definitions>
private void attach(boolean system) {
        sCurrentActivityThread = this;
        mSystemThread = system;
        if (!system) {
            ViewRootImpl.addFirstDrawHandler(new Runnable() {
                @Override
                public void run() {
                    ensureJitEnabled();
                }
            });
            android.ddm.DdmHandleAppName.setAppName("<pre-initialized>",
                                                    UserHandle.myUserId());
            RuntimeInit.setApplicationObject(mAppThread.asBinder());
            final IActivityManager mgr = ActivityManagerNative.getDefault();  //其实就是拿到ActivityManagerService,Binder过程
            try {   //mAppThread就是ApplicationThread
                mgr.attachApplication(mAppThread); //开始创建Application以及后续流程
            } catch (RemoteException ex) {
                throw ex.rethrowFromSystemServer();
            }
            // Watch for getting close to heap limit.
            BinderInternal.addGcWatcher(new Runnable() {  //GC回收相关
                @Override public void run() {
                    if (!mSomeActivitiesChanged) {
                        return;
                    }
                    Runtime runtime = Runtime.getRuntime();
                    long dalvikMax = runtime.maxMemory();
                    long dalvikUsed = runtime.totalMemory() - runtime.freeMemory();
                    if (dalvikUsed > ((3*dalvikMax)/4)) {
                        if (DEBUG_MEMORY_TRIM) Slog.d(TAG, "Dalvik max=" + (dalvikMax/1024)
                                + " total=" + (runtime.totalMemory()/1024)
                                + " used=" + (dalvikUsed/1024));
                        mSomeActivitiesChanged = false;
                        try {
                            mgr.releaseSomeActivities(mAppThread);
                        } catch (RemoteException e) {
                            throw e.rethrowFromSystemServer();
                        }
                    }
                }
            });
        } else {
             .............
        }
    }

分析如下:

至于在ActivityManagerService如何去处理调用,就不记录了,除非是做ROM,不然没办法去研究什么细节,有些博客分析什么调到那又调到哪的,我觉得我多大的记录意义,反正有一点是,Activity创建是在系统进程创建的,而生命周期的方法是系统进程回调ApplicationThread对应该的方法,再通过Handler对应处理的,看下面ApplicationThread几个方法:

  • 流程定义描述文件符合 BPMN 2.0 规范。
  • definitions 标签表示定义开始,内部可以包含多个 process 标签。
  • definitions 标签定义了 XMLSchema 内容规范以及命名空间。
  • process 标签表示流程定义。
  • startEvent 标签表示流程启动事件。
  • endEvent 标签表示流程结束事件。
  • sequenceFlow 标签表示流程节点之间的关系;sourceRef 定义了源节点;targetRef 定义了目标节点。
  • bpmndi:BPMNDiagram 标签是流程的图形定义。
    @Override
     public final void scheduleLaunchActivity(Intent intent, IBinder token, int ident,
                ActivityInfo info, Configuration curConfig, Configuration overrideConfig,
                CompatibilityInfo compatInfo, String referrer, IVoiceInteractor voiceInteractor,
                int procState, Bundle state, PersistableBundle persistentState,
                List<ResultInfo> pendingResults, List<ReferrerIntent> pendingNewIntents,
                boolean notResumed, boolean isForward, ProfilerInfo profilerInfo) {

            updateProcessState(procState, false);

            ActivityClientRecord r = new ActivityClientRecord();

            r.token = token;
            r.ident = ident;
            r.intent = intent;
            r.referrer = referrer;
            r.voiceInteractor = voiceInteractor;
            r.activityInfo = info;
            r.compatInfo = compatInfo;
            r.state = state;
            r.persistentState = persistentState;

            r.pendingResults = pendingResults;
            r.pendingIntents = pendingNewIntents;

            r.startsNotResumed = notResumed;
            r.isForward = isForward;

            r.profilerInfo = profilerInfo;

            r.overrideConfig = overrideConfig;
            updatePendingConfiguration(curConfig);

            sendMessage(H.LAUNCH_ACTIVITY, r);   //通过Handler对应
        }

 public final void scheduleResumeActivity(IBinder token, int processState,
            boolean isForward, Bundle resumeArgs) {
        int seq = getLifecycleSeq();
        if (DEBUG_ORDER) Slog.d(TAG, "resumeActivity " + ActivityThread.this
                + " operation received seq: " + seq);
        updateProcessState(processState, false);
        sendMessage(H.RESUME_ACTIVITY, token, isForward ? 1 : 0, 0, seq); //通过Handler对应
    }

在看下Handler如何处理,LAUNCH_ACTIVITY为例:

@Testpublic void test() { //使用内存数据库,创建流程引擎 ProcessEngine engine = ProcessEngineConfiguration .createStandaloneInMemProcessEngineConfiguration().buildProcessEngine(); //部署 RepositoryService repositoryService = engine.getRepositoryService(); repositoryService.createDeployment().addClasspathResource ("workflow/diagrams/xx.bpmn") .deploy(); //验证 ProcessDefinition definition = repositoryService.createProcessDefinitionQuery() .singleResult(); final String key = "firstProcess"; assertEquals(key, definition.getKey; //启动流程并返回实例 RuntimeService runtimeService = engine.getRuntimeService(); ProcessInstance instance = runtimeService.startProcessInstanceByKey; assertNotNull; System.out.println(",definitionId=" + instance .getProcessDefinitionId;}
 public void handleMessage(Message msg) {
        if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what));
        switch (msg.what) {
            case LAUNCH_ACTIVITY: {
                Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityStart");
                final ActivityClientRecord r = (ActivityClientRecord) msg.obj;

                r.packageInfo = getPackageInfoNoCheck(
                        r.activityInfo.applicationInfo, r.compatInfo);
                handleLaunchActivity(r, null, "LAUNCH_ACTIVITY");
                Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
            } break;
            ........
}

private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent, String reason) {
    // If we are getting ready to gc after going to the background, well
    // we are back active so skip it.
    unscheduleGcIdler();
    mSomeActivitiesChanged = true;

    if (r.profilerInfo != null) {
        mProfiler.setProfiler(r.profilerInfo);
        mProfiler.startProfiling();
    }

    // Make sure we are running with the most recent config.
    handleConfigurationChanged(null, null);

    if (localLOGV) Slog.v(
        TAG, "Handling launch of " + r);

    // Initialize before creating the activity
    WindowManagerGlobal.initialize();

    Activity a = performLaunchActivity(r, customIntent);  //开始了Activity启动

    if (a != null) {
        r.createdConfig = new Configuration(mConfiguration);
        reportSizeConfigurations(r);
        Bundle oldState = r.state;
        handleResumeActivity(r.token, false, r.isForward,
                !r.activity.mFinished && !r.startsNotResumed, r.lastProcessedSeq, reason);

        if (!r.activity.mFinished && r.startsNotResumed) {
            // The activity manager actually wants this one to start out paused, because it
            // needs to be visible but isn't in the foreground. We accomplish this by going
            // through the normal startup (because activities expect to go through onResume()
            // the first time they run, before their window is displayed), and then pausing it.
            // However, in this case we do -not- need to do the full pause cycle (of freezing
            // and such) because the activity manager assumes it can just retain the current
            // state it has.
            performPauseActivityIfNeeded(r, reason);

            // We need to keep around the original state, in case we need to be created again.
            // But we only do this for pre-Honeycomb apps, which always save their state when
            // pausing, so we can not have them save their state when restarting from a paused
            // state. For HC and later, we want to (and can) let the state be saved as the
            // normal part of stopping the activity.
            if (r.isPreHoneycomb()) {
                r.state = oldState;
            }
        }
    } else {
        // If there was an error, for any reason, tell the activity manager to stop us.
        try {
            ActivityManagerNative.getDefault()
                .finishActivity(r.token, Activity.RESULT_CANCELED, null,
                        Activity.DONT_FINISH_TASK_WITH_ACTIVITY);
        } catch (RemoteException ex) {
            throw ex.rethrowFromSystemServer();
        }
    }
}

本文由美高梅游戏平台网站发布于鲜果干果,转载请注明出处:Activity启动主要流程以及Window创建时机小结

关键词:

最火资讯