1. 程式人生 > >Activity啟動過程(一)

Activity啟動過程(一)

Launcher啟動Acivity(未啟動Activity所在程序)

public abstract class LauncherActivity extends ListActivity {
    @Override
    protected void onListItemClick(ListView l, View v, int position, long id) {
        Intent intent = intentForPosition(position);
        startActivity(intent);
    }
}

已有程序啟動Acivity

無論是那種方式,事件都是從Activity的startActivity(intent)開始的。
這是一張我畫的已有程序啟動Activity的時序圖:
這裡寫圖片描述

通過這張時序圖我們可以發現Activity的啟動是一件很複雜的東西,這裡面隱藏了很多的細節,涉及到了多次的IPC(程序間通訊),上面的場景可以想象成Activity_A啟動Activity_B,這張時序圖裡包含很多的知識點.

知識點1:

不知道大家有沒有看過我的Binder機制圖解那篇文章,client端持有Proxy代理物件,訪問Server端的本地物件時,Server端是通過Binder執行緒池中的執行緒來處理程序間通訊的,這也是為什麼程式會設計的一個名為H的內部類,因為當ApplicationThreadProxy呼叫ApplicationThread執行相應的pause或者create操作的時候,ApplicationThread這個Binder本地物件實際上是在Binder執行緒中執行的,所以才需要H這個Handler來和ActivityThread主執行緒進行執行緒間通訊,ActivityThread只是一個普通的java類,並不是一個執行緒,但它位於程序中,那ActivityThread的動力是什麼?

ActivityThread 的動力是什麼?

程序

每個app執行時前首先建立一個程序,該程序是由 Zygote fork 出來的,用於承載App上執行的各種 Activity/Service等元件。程序對於上層應用來說是完全透明的,這也是google有意為之,讓App程式都是執行在 Android Runtime。大多數情況一個App就執行在一個程序中,除非在 AndroidManifest.xml 中配置 Android:process 屬性,或通過 native 程式碼 fork 程序。

執行緒

執行緒對應用來說非常常見,比如每次 new Thread().start 都會建立一個新的執行緒。該執行緒與App所在程序之間資源共享,從Linux 角度來說程序與執行緒除了是否共享資源外,並沒有本質的區別,都是一個 task_struct結構體,在CPU看來程序或執行緒無非就是一段可執行的程式碼,CPU 採用 CFS排程演算法,保證每個 task 都儘可能公平的享有 CPU時間片。

其實承載 ActivityThread 的主執行緒就是由 Zygote fork 而建立的程序。

知識點2:
onPause中為什麼不推薦執行耗時操作,我們知道Activity_A啟動Activity_B會先啟動Activity_A生命週期中的onPause回撥函式,然後才執行Activity_B的生命週期中的onCreate回撥函式,從時序圖中我們可以發現H類將pause相關的資訊轉發給了位於主執行緒的ActivityThread,而ActivityThread又呼叫了Instrumentation的callActivityOnPause函式,最終執行Activity的onPause,也就是說這一系列的過程都是在主執行緒執行的,當然不可以進行耗時操作,這是其一,其二隻有當onPause執行完成才會執行activityPaused方法呼叫ActivityManagerProxy執行下一步的操作,也就是說如果onPause邏輯過多,過於耗時將不能很好的啟動Activity_B。

區別
那麼已有程序和Launcher啟動未啟動程序的區別在於ActivityStack.startSpecificActivityLocked函式執行後,會進行要啟動Activity是否有對應程序的判斷,如果有直接執行realStartActivityLocked,如果沒有就需要先建立程序。然後在程序啟動後再執行realStartActivityLocked來啟動Activity。

關於應用程序的建立我將單獨發一篇部落格來說明,然後大家再結合這張時序圖將空白程序建立部分補上。

相關推薦

Activity啟動過程

Launcher啟動Acivity(未啟動Activity所在程序) public abstract class LauncherActivity extends ListActivity { @Override protected voi

hadoop啟動過程 NameNode

  一、第一次啟動   NameNode 記憶體 本地磁碟 fsimage edits 格式化HDFS,目的是審查隔行fsimage

MySQL學習筆記——MySQL啟動過程

clas oot handler lis done con replica mut groups 首先去官網或者github下載MySQL5.7的源碼。 官網地址:https://dev.mysql.com/downloads/mysql/ github地址:https:/

Spring原始碼解析步分析,springMVC專案啟動過程

 springMVC專案啟動過程,分析原始碼。1、環境搭建,這步我就省略細節,只把我的大概環境說下:windows 7 、jdk 8、maven-3.3.9、tomcat 8.5.11、IDEA 2017.1 x64版 具體環境安裝,我就略過,可自行google、baidu安

Tomcat原始碼分析 -- Tomcat的啟動過程

本篇結構: 前言 bat檔案 startup.bat catalina.bat 總結 一、前言 一般啟動tomcat都是找到bin目錄下的startup.bat(windows)下或者startup.sh(linux下),所以要研究tomcat的啟

Android系統啟動流程解析init進程啟動過程

option 寫入 android change failed miss 通知 target sna 前言 作為“Android框架層”這個大系列中的第一個系列,我們首先要了解的是Android系統啟動流程,在這個流程中會涉及到很多重要的知識點,這個系列我們就來一一講解它們

Android系統啟動流程解析init程序啟動過程

前言 作為“Android框架層”這個大系列中的第一個系列,我們首先要了解的是Android系統啟動流程,在這個流程中會涉及到很多重要的知識點,這個系列我們就來一一講解它們,這一篇我們就來學習init程序。 1.init簡介 init程序是An

Tomcat原始碼分析三:Tomcat啟動載入過程的原始碼解析

Tomcat啟動載入過程(一)的原始碼解析 今天,我將分享用原始碼的方式講解Tomcat啟動的載入過程,關於Tomcat的架構請參閱《Tomcat原始碼分析二:先看看Tomcat的整體架構》一文。 先看看應用情況 在《Servlet與Tomcat執行示例》一文中,我詳細的記錄了Tomcat是如何啟動一個Ser

springboot啟動過程1-初始化

好的 事件監聽 spa 兩個 包括 servlet 實例對象 ice 機制 1 springboot啟動時,[email protected]/* */函數,執行SpringApplication.run(DemoApplication.class, arg

KubernetesK8s安裝部署過程--證書安裝

更改 目錄 hand /etc 主題 nbsp kubecon 安裝部署 post 一、安裝前主題環境準備   1、docker安裝   建議使用官網yum源安裝,添加yum源之後,直接yum install docker即可   2、關閉所有節點的selinux

Web滲透學習過程

滲透什麽是struts2? Struts2是一個基於MVC設計模式的Web應用框架,它本質上相當於一個servlet,在MVC設計模式中,Struts2作為控制器(Controller)來建立模型與視圖的數據交互。其被普遍應用於阿裏、京東等各大網站。 本次講的struts2漏洞是什麽? S2-016 S2-

Spring啟動流程

準備來一波SpringMVC攔截器原理的,但是發現,Spring原始碼流程應該是個前置內容,要先解決。 Spring初始化 通過xml方式使用Spring提供的IOC容器功能,首先需要在web.xml引入這段配置(還有Java配置的方式,不需要寫配置檔案,通過註解,這裡先不作討論)

記錄自己用python搭建個人部落格系統的完整過程

零、前言 本博文記錄搭建個人部落格系統的完整過程,網上有許多相關的教程,但是沒找到一個(適合自己能力的)快速搭建的完整教程。藉此篇博文梳理一下前不久學習到的有關整個過程前前後後的各種知識點。 一、搭建環境 採用架構:python3.6 + django1.10 + ngi

PostgreSQL+REDIS_FDW詳細記錄踩坑過程

案例環境: 虛擬機器:CenterOS 7.0.1406(注意:centerOS自帶postgres9.2的版本安裝包) PG版本:postgresql-10.5-1-linux-x64-binaries.tar.gz redis_fwd版本:redis_fdw-REL_10_STABL

Node.js之在服務端啟動網頁

var http = require('http');//建立伺服器的 var fs = require('fs'); //引入進來的是模組,模組中有方法,下一步就是使用方法 //Node.js一個最主要的特點:執行的基本都是函式 //建立服務 var myServer =

java基礎之----基本資料型別和引用資料型別的引數傳遞過程

值傳遞:方法呼叫時,實際引數把它的值傳遞給對應的形式引數,方法執行中形式引數值的改變不影響實際引數的值。 引用傳遞:也稱為傳地址。方法呼叫時,實際引數的引用(地址,而不是引數的值)被傳遞給方法中相對應的形式引數,在方法執行中,對形式引數的操作實際上就是對實際引

hadoop啟動過程secondNameNode

  作用:定期將namenode的fsimage和edits合併(資料或者操作不多的時候可以關閉 ),可加速hdfs啟動(如果edits很多的話,開啟會很難)   SecondNameNode: 它會定期的和namenode就行通訊來完成整個的備份操作(????更

YOLO學習過程

一.下載Darknet框架並測試 1.下載編譯Darknet框架 1)終端輸入命令 git clone https://github.com/pjreddie/darknet cd darknet 2)若沒有配置GPU,CUDA及OPENCV等環境則直接輸入命令

Centos7配置ThinkPHP5.0完整過程

在Centos中配置PHP伺服器環境,首先要安裝Apache的http服務,然後安裝php解析環境,最後再配置ThinkPHP5.0。 首先安裝HTTP  sudo yum install httpd -y   安裝時需要管理員許可權,所以需要使用sudo。安裝之後,啟動httpd服務 sudo s

Oracle中建立儲存過程和呼叫過程

1、定義         所謂儲存過程(Stored Procedure),就是一組用於完成特定資料庫功能的SQL語句集,該SQL語句集經過 編譯後儲存在資料庫系統中。在使用時候,使用者通過指定已經定義的儲存過程名字並給出相應的儲存過程引數 來呼叫並執行