Slide 1

Slide 1 text

윤희성 소스코드로 알아보는 안드로이드 Context 세션 02

Slide 2

Slide 2 text

윤희성 소스코드로 알아보는 안드로이드 Context 세션 02 삼성전자 MX 사업부 프레임워크 Medium: https://quokkaman.medium.com GitHub: https://github.com/heesung6701

Slide 3

Slide 3 text

소스코드로 알아보는 안드로이드 Context 3 Context 누구나 알고 있지만 설명 하기는 어려운 ActivityContext, ApplicationContext, BaseContext Activity is Context -> Activity와 ActivityContext의 관계

Slide 4

Slide 4 text

Agenda 소스코드로 알아보는 안드로이드 Context 4 SubClasses

Slide 5

Slide 5 text

소스코드로 알아보는 안드로이드 Context Context의 서브 클래스 윤희성 세션 02

Slide 6

Slide 6 text

공식 문서 Context의 서브 클래스 6

Slide 7

Slide 7 text

서브클래스 Context의 서브 클래스 7 frameworks/base/core

Slide 8

Slide 8 text

ContextWrapper Context의 서브 클래스 8 ContextImpl를 제외하고 
 모두 ContextWrapper 상속

Slide 9

Slide 9 text

ContextWrapper.java Context의 서브 클래스 9 base 멤버 변수를 가지는 Context 서브 클래스 Context 메소드를 모두 base로 위임

Slide 10

Slide 10 text

Activity Application Context의 서브 클래스 10 Activity는 ContextThemeWrapper 상속

Slide 11

Slide 11 text

ContextThemeWrapper.java Context의 서브 클래스 11 테마 멤버 변수

Slide 12

Slide 12 text

ContextThemeWrapper.java Context의 서브 클래스 12 테마 조정

Slide 13

Slide 13 text

ContextThemeWrapper.java Context의 서브 클래스 13 applyOverrideConfiguration baseContext::getResources 대신 새로 생성된 resContext에서 가져옴

Slide 14

Slide 14 text

Summary - Context 서브 클래스 Context의 서브 클래스 14 Context는 추상 클래스 ContextImpl를 제외한 모든 Context는 ContextWrapper 상속 ContextWrapper는 Context 동작을 base로 위임하는 래퍼 클래스 ContextThemeWrapper는 테마/리소스를 재정의한 ContextWrapper Activity는 ContextThemeWrapper를 상속

Slide 15

Slide 15 text

소스코드로 알아보는 안드로이드 Context Context.java 살펴보기 윤희성 세션 02

Slide 16

Slide 16 text

안드로이드 고려 사항 Context.java 살펴보기 16 앱 화면을 이탈 시에도 유지 빠른 앱 전환 속도 디바이스에 한정된 메모리 Context를 이해하기 위한 배경

Slide 17

Slide 17 text

안드로이드 어플리케이션 Context.java 살펴보기 17 Application Process System ActivityManagerService 에 의해 어플리케이션 관리 System Context를 이해하기 위한 배경

Slide 18

Slide 18 text

ActiovityMagerService ActiovityMagerService 안드로이드 시스템 서비스 Context.java 살펴보기 18 app main.cpp ZygoteInit AndroidRuntime SystemServer ActivityManagerService #1 부팅 시 SystemServer가 ActivityManagerService 등 시스템 서비스 생성 Context를 이해하기 위한 배경

Slide 19

Slide 19 text

Application Package Kit APK Context.java 살펴보기 19 Activity 
 UI Service 
 Background ContentProvider 
 Data BroadcastReceiver 
 Action Resources 
 image, string, etc Context를 이해하기 위한 배경

Slide 20

Slide 20 text

Context Context.java 살펴보기 20 Component A Component B Context 컴포넌트 간 커뮤니케이션 / 식별자 Context를 이해하기 위한 배경 System Context

Slide 21

Slide 21 text

Context.java Context.java 살펴보기 21 패키지/애플리케이션 정보 public abstract String getPackageName public abstract String getBasePackageName public String getOpPackageName public abstract String getPackageResourcePath public abstract String getPackageCodePath public abstract ApplicationInfo getApplicationInfo

Slide 22

Slide 22 text

Context.java Context.java 살펴보기 22 리소스 정보 public abstract AssetManager getAssets ; public abstract Resources getResources ; public final CharSequence getText public final String getString public final String getString public final int getColor public final Drawable getDrawable public final ColorStateList getColorStateList @

Slide 23

Slide 23 text

public abstract AssetManager getAssets ; public abstract Resources getResources ; public final CharSequence getText public final String getString public final String getString public final int getColor public final Drawable getDrawable public final ColorStateList getColorStateList @ Context.java Context.java 살펴보기 23 리소스 정보

Slide 24

Slide 24 text

Context.java Context.java 살펴보기 24 컴포넌트 액티비티 서비스 브로드캐스트 콘텐트 리졸버 제어 public abstract void startActivity public void startActivityAsUser public abstract void startActivity public void startActivityAsUser public void startActivityForResult public abstract void startActivities public abstract void startActivities public int startActivitiesAsUser Intent intents, Bundle options, UserHandle userHandle

Slide 25

Slide 25 text

Context.java Context.java 살펴보기 25 컴포넌트 액티비티 서비스 브로드캐스트 콘텐트 리졸버 제어 public abstract ComponentName startService Intent service public abstract ComponentName startForegroundService Intent service public abstract ComponentName startForegroundServiceAsUser Intent service, UserHandle user public abstract boolean stopService Intent service public abstract ComponentName startServiceAsUser Intent service, UserHandle user public abstract boolean stopServiceAsUser Intent service, UserHandle user public abstract boolean bindService public boolean bindService public boolean bindIsolatedService public boolean bindServiceAsUser public boolean bindServiceAsUser Intent service, ServiceConnection conn, int flags, Handler handler, UserHandle user public void updateServiceGroup ServiceConnection conn, int group, int importance public abstract void unbindService ServiceConnection conn

Slide 26

Slide 26 text

Context.java Context.java 살펴보기 26 컴포넌트 액티비티 서비스 브로드캐스트 콘텐트 리졸버 제어 @ StringDef suffix SERVICE , value POWER SERVICE, WINDOW SERVICE, ACTIVITY SERVICE, ALARM SERVICE, NOTIFICATION SERVICE,, LOCATION SERVICE, INPUT METHOD SERVICE, APPWIDGET SERVICE, UI MODE SERVICE, INPUT SERVICE, /* many kind of services … */ @ Retention RetentionPolicy.SOURCE public interface ServiceName public abstract @ Nullable Object getSystemService @ ServiceName String name public final @ Nullable < T > T getSystemService Class T > serviceClass public abstract @ Nullable String getSystemServiceName Class ? > serviceClass 시스템 서비스 접근 api 제공

Slide 27

Slide 27 text

Context.java Context.java 살펴보기 27 컴포넌트 액티비티 서비스 브로드캐스트 콘텐트 리졸버 제어 public abstract void sendBroadcast public abstract void sendBroadcast public void sendBroadcastMultiplePermissions Intent intent, String receiverPermissions, /* … */ public void sendBroadcastWithMultiplePermissions Intent intent, String receiverPermissions public abstract void sendBroadcastAsUserMultiplePermissions Intent intent, UserHandle user, String receiverPermissions public abstract void sendBroadcast Intent intent, String receiverPermission, Bundle options public abstract void sendBroadcast Intent intent, String receiverPermission, int appOp public abstract void sendOrderedBroadcast public abstract void sendBroadcastAsUser public abstract void sendOrderedBroadcastAsUser public void sendOrderedBroadcast Intent intent, String receiverPermission, String receiverAppOp, /* … */ 
 public abstract Intent registerReceiver public Intent registerReceiverForAllUsers public abstract Intent registerReceiverAsUser BroadcastReceiver receiver, UserHandle user, IntentFilter filter, String broadcastPermission, /* … */ public abstract void unregisterReceiver BroadcastReceiver receiver

Slide 28

Slide 28 text

Context.java Context.java 살펴보기 28 컴포넌트 액티비티 서비스 브로드캐스트 콘텐트 리졸버 제어 public abstract ContentResolver getContentResolver

Slide 29

Slide 29 text

Context.java Context.java 살펴보기 29 파일 시스템 / SQLiteDatabase / SharedPreferences public abstract FileInputStream openFileInput String name CursorFactory factory public abstract SharedPreferences getSharedPreferences String name, @

Slide 30

Slide 30 text

Context Context.java 살펴보기 30

Slide 31

Slide 31 text

Context Context.java 살펴보기 31 4대 컴포넌트 스레드 데이터베이스 리소스 앱 정보 유저 토큰 디스플레이 자동완성 캡처

Slide 32

Slide 32 text

Summary - Context Context.java 살펴보기 32 앱 정보 / 리소스 접근 시스템 요청이 필요한 작업에 대한 api 제공 Context는 안드로이드 시스템과 커뮤니케이션 하기 위한 맥락

Slide 33

Slide 33 text

소스코드로 알아보는 안드로이드 Context ContextImpl.java 
 컨텍스트 생성 윤희성 세션 02

Slide 34

Slide 34 text

ContextImpl 34 생성자 ContextImpl.java 컨텍스트 생성

Slide 35

Slide 35 text

35 private 생성자 ContextImpl 생성자 ContextImpl.java 컨텍스트 생성

Slide 36

Slide 36 text

36 Container 정보 복사 ContextImpl 생성자 ContextImpl.java 컨텍스트 생성

Slide 37

Slide 37 text

ContextImpl static ContextImpl createSystemContext ActivityThread mainThread static ContextImpl createActivityContext ActivityThread mainThread, LoadedApk packageInfo, 
 37 Static 생성자 ContextImpl.java 컨텍스트 생성

Slide 38

Slide 38 text

createSystemContext 38 static ContextImpl createSystemContext ActivityThread mainThread LoadedApk packageInfo new LoadedApk mainThread ; ContextImpl context new ContextImpl null, mainThread, packageInfo, ContextParams.EMPTY, null, null, null, null, null, 0, null, null ; context.setResources packageInfo.getResources ; context.mResources.updateConfiguration context.mResourcesManager.getConfiguration , context.mResourcesManager.getDisplayMetrics ; context.mContextType return context; ContextImpl.java 컨텍스트 생성

Slide 39

Slide 39 text

createSystemContext 39 static ContextImpl createSystemContext ActivityThread mainThread LoadedApk packageInfo new LoadedApk mainThread ; ContextImpl context new ContextImpl null, mainThread, packageInfo, ContextParams.EMPTY, null, null, null, null, null, 0, null, null ; context.setResources packageInfo.getResources ; context.mResources.updateConfiguration context.mResourcesManager.getConfiguration , context.mResourcesManager.getDisplayMetrics ; context.mContextType return context; ContextImpl.java 컨텍스트 생성

Slide 40

Slide 40 text

static ContextImpl createSystemContext ActivityThread mainThread LoadedApk packageInfo new LoadedApk mainThread ; ContextImpl context new ContextImpl null, mainThread, packageInfo, ContextParams.EMPTY, null, null, null, null, null, 0, null, null ; context.setResources packageInfo.getResources ; context.mResources.updateConfiguration context.mResourcesManager.getConfiguration , context.mResourcesManager.getDisplayMetrics ; context.mContextType return context; createSystemContext 40 ContextImpl.java 컨텍스트 생성

Slide 41

Slide 41 text

SystemContext 41 mainThread로 생성 mainThread로 packageInfo 생성 packageInfo의 리소스 연결 SYSTEM 타입 ContextImpl.java 컨텍스트 생성

Slide 42

Slide 42 text

createSystemUiContext 42 static ContextImpl createSystemUiContext ContextImpl systemContext, int displayId final WindowTokenClient token new WindowTokenClient ; final ContextImpl context systemContext.createWindowContextBase token, displayId ; token.attachContext context ; token.attachToDisplayContent displayId ; context.mContextType context.mOwnsToken true; return context; ContextImpl.java 컨텍스트 생성

Slide 43

Slide 43 text

createSystemUiContext 43 static ContextImpl createSystemUiContext ContextImpl systemContext, int displayId final WindowTokenClient token new WindowTokenClient ; final ContextImpl context systemContext.createWindowContextBase token, displayId ; token.attachContext context ; token.attachToDisplayContent displayId ; context.mContextType context.mOwnsToken true; return context; SystemUiContext는 SystemContext로 부터 생성 ContextImpl.java 컨텍스트 생성

Slide 44

Slide 44 text

createWindowContextBase 44 ContextImpl createWindowContextBase ContextImpl baseContext new ContextImpl this, mMainThread, mPackageInfo, mParams, mAttributionSource.getAttributionTag , mAttributionSource.getNext , mSplitName, token, mUser, mFlags, mClassLoader, null ; baseContext.mForceDisplayOverrideInResources false; baseContext.mContextType final Resources windowContextResources createWindowContextResources baseContext ; baseContext.setResources windowContextResources ; 
 baseContext.mDisplay windowContextResources ; return baseContext; ContextImpl.java 컨텍스트 생성

Slide 45

Slide 45 text

ContextImpl createWindowContextBase ContextImpl baseContext new ContextImpl this, mMainThread, mPackageInfo, mParams, mAttributionSource.getAttributionTag , mAttributionSource.getNext , mSplitName, token, mUser, mFlags, mClassLoader, null ; baseContext.mForceDisplayOverrideInResources false; baseContext.mContextType final Resources windowContextResources createWindowContextResources baseContext ; baseContext.setResources windowContextResources ; 
 baseContext.mDisplay windowContextResources ; return baseContext; createWindowContextBase 45 SystemUiContext는 SystemContext 정보 복사 ContextImpl.java 컨텍스트 생성 Non static

Slide 46

Slide 46 text

ContextImpl createWindowContextBase ContextImpl baseContext new ContextImpl this, mMainThread, mPackageInfo, mParams, mAttributionSource.getAttributionTag , mAttributionSource.getNext , mSplitName, token, mUser, mFlags, mClassLoader, null ; baseContext.mForceDisplayOverrideInResources false; baseContext.mContextType final Resources windowContextResources createWindowContextResources baseContext ; baseContext.setResources windowContextResources ; 
 baseContext.mDisplay windowContextResources ; return baseContext; createWindowContextBase 46 Token을 제외하고는 호출 Context의 정보 전달 ContextImpl.java 컨텍스트 생성

Slide 47

Slide 47 text

createWindowContextBase 47 ContextImpl createWindowContextBase ContextImpl baseContext new ContextImpl this, mMainThread, mPackageInfo, mParams, mAttributionSource.getAttributionTag , mAttributionSource.getNext , mSplitName, token, mUser, mFlags, mClassLoader, null ; baseContext.mForceDisplayOverrideInResources false; baseContext.mContextType final Resources windowContextResources createWindowContextResources baseContext ; baseContext.setResources windowContextResources ; 
 baseContext.mDisplay windowContextResources ; return baseContext; ContextImpl.java 컨텍스트 생성

Slide 48

Slide 48 text

createWindowContextBase 48 ContextImpl createWindowContextBase ContextImpl baseContext new ContextImpl this, mMainThread, mPackageInfo, mParams, mAttributionSource.getAttributionTag , mAttributionSource.getNext , mSplitName, token, mUser, mFlags, mClassLoader, null ; baseContext.mForceDisplayOverrideInResources false; baseContext.mContextType final Resources windowContextResources createWindowContextResources baseContext ; baseContext.setResources windowContextResources ; 
 baseContext.mDisplay windowContextResources ; return baseContext; ContextImpl.java 컨텍스트 생성

Slide 49

Slide 49 text

createWindowContextBase 49 ContextImpl createWindowContextBase ContextImpl baseContext new ContextImpl this, mMainThread, mPackageInfo, mParams, mAttributionSource.getAttributionTag , mAttributionSource.getNext , mSplitName, token, mUser, mFlags, mClassLoader, null ; baseContext.mForceDisplayOverrideInResources false; baseContext.mContextType final Resources windowContextResources createWindowContextResources baseContext ; baseContext.setResources windowContextResources ; 
 baseContext.mDisplay windowContextResources ; return baseContext; ContextImpl.java 컨텍스트 생성 #2

Slide 50

Slide 50 text

WindowContextBase 50 ContextImpl 인스턴스로 부터 생성 windowContextResources를 리소스로 사용 디스플레이 정보 WINDOW CONTEXT 타입 ContextImpl.java 컨텍스트 생성

Slide 51

Slide 51 text

static ContextImpl createSystemUiContext ContextImpl systemContext, int displayId final WindowTokenClient token new WindowTokenClient ; final ContextImpl context systemContext.createWindowContextBase token, displayId ; token.attachContext context ; token.attachToDisplayContent displayId ; context.mContextType context.mOwnsToken true; return context; createSystemUiContext 51 ContextImpl.java 컨텍스트 생성

Slide 52

Slide 52 text

static ContextImpl createSystemUiContext ContextImpl systemContext, int displayId final WindowTokenClient token new WindowTokenClient ; final ContextImpl context systemContext.createWindowContextBase token, displayId ; token.attachContext context ; token.attachToDisplayContent displayId ; context.mContextType context.mOwnsToken true; return context; createSystemUiContext 52 ContextImpl.java 컨텍스트 생성

Slide 53

Slide 53 text

createSystemUiContext 53 static ContextImpl createSystemUiContext ContextImpl systemContext, int displayId final WindowTokenClient token new WindowTokenClient ; final ContextImpl context systemContext.createWindowContextBase token, displayId ; token.attachContext context ; token.attachToDisplayContent displayId ; context.mContextType context.mOwnsToken true; return context; ContextImpl.java 컨텍스트 생성

Slide 54

Slide 54 text

createSystemUiContext 54 static ContextImpl createSystemUiContext ContextImpl systemContext, int displayId final WindowTokenClient token new WindowTokenClient ; final ContextImpl context systemContext.createWindowContextBase token, displayId ; token.attachContext context ; token.attachToDisplayContent displayId ; context.mContextType context.mOwnsToken true; return context; ContextImpl.java 컨텍스트 생성

Slide 55

Slide 55 text

SystemUiContext 55 SystemContext 인스턴스에서 생성 디스플레이 정보 WindowContextBase의 한 형태 SYSTEM UI 타입 ContextImpl.java 컨텍스트 생성

Slide 56

Slide 56 text

createAppContext 56 static ContextImpl createAppContext ActivityThread mainThread, LoadedApk packageInfo, String opPackageName if packageInfo null throw new IllegalArgumentException packageInfo ; ContextImpl context new ContextImpl null, mainThread, packageInfo, ContextParams.EMPTY, null, null, null, null, null, 0, null, opPackageName ; context.setResources packageInfo.getResources ; context.mContextType isSystemOrSystemUI context ? CONTEXT TYPE SYSTEM OR SYSTEM UI return context; ContextImpl.java 컨텍스트 생성

Slide 57

Slide 57 text

createAppContext 57 static ContextImpl createAppContext ActivityThread mainThread, LoadedApk packageInfo, String opPackageName if packageInfo null throw new IllegalArgumentException packageInfo ; ContextImpl context new ContextImpl null, mainThread, packageInfo, ContextParams.EMPTY, null, null, null, null, null, 0, null, opPackageName ; context.setResources packageInfo.getResources ; context.mContextType isSystemOrSystemUI context ? CONTEXT TYPE SYSTEM OR SYSTEM UI return context; ContextImpl.java 컨텍스트 생성

Slide 58

Slide 58 text

createAppContext 58 static ContextImpl createAppContext ActivityThread mainThread, LoadedApk packageInfo, String opPackageName if packageInfo null throw new IllegalArgumentException packageInfo ; ContextImpl context new ContextImpl null, mainThread, packageInfo, ContextParams.EMPTY, null, null, null, null, null, 0, null, opPackageName ; context.setResources packageInfo.getResources ; context.mContextType isSystemOrSystemUI context ? CONTEXT TYPE SYSTEM OR SYSTEM UI return context; ContextImpl.java 컨텍스트 생성

Slide 59

Slide 59 text

createAppContext 59 static ContextImpl createAppContext ActivityThread mainThread, LoadedApk packageInfo, String opPackageName if packageInfo null throw new IllegalArgumentException packageInfo ; ContextImpl context new ContextImpl null, mainThread, packageInfo, ContextParams.EMPTY, null, null, null, null, null, 0, null, opPackageName ; context.setResources packageInfo.getResources ; context.mContextType isSystemOrSystemUI context ? CONTEXT TYPE SYSTEM OR SYSTEM UI return context; ContextImpl.java 컨텍스트 생성 #3

Slide 60

Slide 60 text

AppContext 60 mainThread, packageInfo로 생성 NON UI 또는 SYSTEM OR SYSTEM UI ContextImpl.java 컨텍스트 생성

Slide 61

Slide 61 text

createActivityContext 61 static ContextImpl createActivityContext ActivityThread mainThread, LoadedApk packageInfo, ActivityInfo activityInfo, IBinder activityToken, int displayId, Configuration overrideConfiguration // … String splitDirs packageInfo.getSplitResDirs ; ClassLoader classLoader packageInfo.getClassLoader ; // … final String attributionTag; if activityInfo.attributionTags ! attributionTag activityInfo.attributionTags 0 ; else attributionTag null; ContextImpl context new ContextImpl null, mainThread, packageInfo, ContextParams.EMPTY, attributionTag, null, activityInfo.splitName, activityToken, null, 0, classLoader, null ; context.mContextType context.mIsConfigurationBasedContext true; displayId displayId ! final CompatibilityInfo compatInfo displayId ? packageInfo.getCompatibilityInfo final ResourcesManager resourcesManager context.setResources /* … */ ; context.mDisplay resourcesManager.getAdjustedDisplay displayId, context.getResources ; return context; ContextImpl.java 컨텍스트 생성

Slide 62

Slide 62 text

createActivityContext 62 static ContextImpl createActivityContext ActivityThread mainThread, LoadedApk packageInfo, ActivityInfo activityInfo, IBinder activityToken, int displayId, Configuration overrideConfiguration if packageInfo null throw new IllegalArgumentException packageInfo ; String splitDirs packageInfo.getSplitResDirs ; ClassLoader classLoader packageInfo.getClassLoader ; if packageInfo.getApplicationInfo .requestsIsolatedSplitLoading try classLoader packageInfo.getSplitClassLoader activityInfo.splitName ; splitDirs packageInfo.getSplitPaths activityInfo.splitName ; catch NameNotFoundException e throw new RuntimeException e ; // … ContextImpl context new ContextImpl /* … */ packageInfo, /* … */ ; // … final CompatibilityInfo compatInfo displayId // … context.setResources resourcesManager.createBaseTokenResources activityToken, packageInfo.getResDir , splitDirs, packageInfo.getOverlayDirs , packageInfo.getOverlayPaths , packageInfo.getApplicationInfo .sharedLibraryFiles, displayId, overrideConfiguration, compatInfo, ContextImpl.java 컨텍스트 생성

Slide 63

Slide 63 text

createActivityContext 63 static ContextImpl createActivityContext ActivityThread mainThread, LoadedApk packageInfo, ActivityInfo activityInfo, IBinder activityToken, int displayId, Configuration overrideConfiguration // … String splitDirs packageInfo.getSplitResDirs ; ClassLoader classLoader packageInfo.getClassLoader ; if packageInfo.getApplicationInfo .requestsIsolatedSplitLoading try classLoader packageInfo.getSplitClassLoader activityInfo.splitName ; splitDirs packageInfo.getSplitPaths activityInfo.splitName ; catch NameNotFoundException e throw new RuntimeException e ; final String attributionTag; if activityInfo.attributionTags ! attributionTag activityInfo.attributionTags 0 ; else attributionTag null; // … ContextImpl.java 컨텍스트 생성

Slide 64

Slide 64 text

createActivityContext 64 static ContextImpl createActivityContext ActivityThread mainThread, LoadedApk packageInfo, ActivityInfo activityInfo, IBinder activityToken, int displayId, Configuration overrideConfiguration // … String splitDirs packageInfo.getSplitResDirs ; ClassLoader classLoader packageInfo.getClassLoader ; // … final String attributionTag; if activityInfo.attributionTags ! attributionTag activityInfo.attributionTags 0 ; else attributionTag null; ContextImpl context new ContextImpl null, mainThread, packageInfo, ContextParams.EMPTY, attributionTag, null, activityInfo.splitName, activityToken, null, 0, classLoader, null ; context.mContextType context.mIsConfigurationBasedContext true; // … ContextImpl.java 컨텍스트 생성

Slide 65

Slide 65 text

createActivityContext 65 static ContextImpl createActivityContext ActivityThread mainThread, LoadedApk packageInfo, ActivityInfo activityInfo, IBinder activityToken, int displayId, Configuration overrideConfiguration // … String splitDirs packageInfo.getSplitResDirs ; ClassLoader classLoader packageInfo.getClassLoader ; // … final String attributionTag; // … ContextImpl context new ContextImpl null, mainThread, packageInfo, ContextParams.EMPTY, attributionTag, null, activityInfo.splitName, activityToken, null, 0, classLoader, null ; context.mContextType context.mIsConfigurationBasedContext true; displayId displayId ! final CompatibilityInfo compatInfo displayId ? packageInfo.getCompatibilityInfo // … return context; ContextImpl.java 컨텍스트 생성

Slide 66

Slide 66 text

createActivityContext 66 static ContextImpl createActivityContext ActivityThread mainThread, LoadedApk packageInfo, ActivityInfo activityInfo, IBinder activityToken, int displayId, Configuration overrideConfiguration // … String splitDirs packageInfo.getSplitResDirs ; ClassLoader classLoader packageInfo.getClassLoader ; // … final String attributionTag; // … ContextImpl context new ContextImpl null, mainThread, packageInfo, ContextParams.EMPTY, attributionTag, null, activityInfo.splitName, activityToken, null, 0, classLoader, null ; context.mContextType context.mIsConfigurationBasedContext true; displayId displayId ! final CompatibilityInfo compatInfo displayId ? packageInfo.getCompatibilityInfo // … return context; ContextImpl.java 컨텍스트 생성

Slide 67

Slide 67 text

createActivityContext 67 static ContextImpl createActivityContext ActivityThread mainThread, LoadedApk packageInfo, ActivityInfo activityInfo, IBinder activityToken, int displayId, Configuration overrideConfiguration // … String splitDirs packageInfo.getSplitResDirs ; ClassLoader classLoader packageInfo.getClassLoader ; // … final String attributionTag; // … ContextImpl context new ContextImpl null, mainThread, packageInfo, ContextParams.EMPTY, attributionTag, null, activityInfo.splitName, activityToken, null, 0, classLoader, null ; // … displayId displayId ! final CompatibilityInfo compatInfo displayId ? packageInfo.getCompatibilityInfo final ResourcesManager resourcesManager context.setResources /* … */ ; context.mDisplay resourcesManager.getAdjustedDisplay displayId, context.getResources ; return context; ContextImpl.java 컨텍스트 생성

Slide 68

Slide 68 text

createActivityContext 68 static ContextImpl createActivityContext ActivityThread mainThread, LoadedApk packageInfo, ActivityInfo activityInfo, IBinder activityToken, int displayId, Configuration overrideConfiguration // … String splitDirs packageInfo.getSplitResDirs ; ClassLoader classLoader packageInfo.getClassLoader ; ContextImpl context new ContextImpl null, mainThread, packageInfo, ContextParams.EMPTY, final CompatibilityInfo compatInfo displayId // … final ResourcesManager resourcesManager context.setResources resourcesManager.createBaseTokenResources activityToken, packageInfo.getResDir , splitDirs, packageInfo.getOverlayDirs , packageInfo.getOverlayPaths , packageInfo.getApplicationInfo .sharedLibraryFiles, displayId, overrideConfiguration, compatInfo, classLoader, packageInfo.getApplication null ? null : packageInfo.getApplication .getResources .getLoaders ; context.mDisplay resourcesManager.getAdjustedDisplay displayId, context.getResources ; return context; ContextImpl.java 컨텍스트 생성

Slide 69

Slide 69 text

createActivityContext 69 static ContextImpl createActivityContext ActivityThread mainThread, LoadedApk packageInfo, ActivityInfo activityInfo, IBinder activityToken, int displayId, Configuration overrideConfiguration // … String splitDirs packageInfo.getSplitResDirs ; ClassLoader classLoader packageInfo.getClassLoader ; // … final String attributionTag; // … ContextImpl context new ContextImpl null, mainThread, packageInfo, ContextParams.EMPTY, // … final CompatibilityInfo compatInfo displayId // … final ResourcesManager resourcesManager context.setResources /* … */ ; context.mDisplay resourcesManager.getAdjustedDisplay displayId, context.getResources ; return context; ContextImpl.java 컨텍스트 생성

Slide 70

Slide 70 text

ActivityContext 70 액티비티 관련 다양한 인자 Split 로직 baseTokenResources 디스플레이 정보 ContextImpl.java 컨텍스트 생성

Slide 71

Slide 71 text

Static 생성자 71 ContextImpl.java 컨텍스트 생성

Slide 72

Slide 72 text

Context Type 72 Type UI Associate
 with Display windonConetextToken ActivityToken None UI X X X X Display X O X X Activity O O X O Window O O O X System or System UI O O O X ContextImpl.java 컨텍스트 생성 #4

Slide 73

Slide 73 text

Context 종류 73 ContextImpl.java 컨텍스트 생성

Slide 74

Slide 74 text

createApplicationContext 74 public Context createApplicationContext ApplicationInfo application, int flags throws NameNotFoundException LoadedApk pi mMainThread.getPackageInfo application, mResources.getCompatibilityInfo , flags CONTEXT REGISTER PACKAGE ; if pi ! ContextImpl c new ContextImpl this, mMainThread, pi, ContextParams.EMPTY, mAttributionSource.getAttributionTag , mAttributionSource.getNext , null, mToken, new UserHandle UserHandle.getUserId application.uid , flags, null, null ; final int displayId getDisplayId ; final Integer overrideDisplayId mForceDisplayOverrideInResources ? displayId : null; c.setResources createResources mToken, pi, null, overrideDisplayId, null, getDisplayAdjustments displayId .getCompatibilityInfo , null ; if c.mResources ! throw new PackageManager.NameNotFoundException Application package application.packageName not found ; ContextImpl.java 컨텍스트 생성

Slide 75

Slide 75 text

public Context createApplicationContext ApplicationInfo application, int flags throws NameNotFoundException LoadedApk pi mMainThread.getPackageInfo application, mResources.getCompatibilityInfo , flags CONTEXT REGISTER PACKAGE ; if pi ! ContextImpl c new ContextImpl this, mMainThread, pi, ContextParams.EMPTY, mAttributionSource.getAttributionTag , mAttributionSource.getNext , null, mToken, new UserHandle UserHandle.getUserId application.uid , flags, null, null ; final int displayId getDisplayId ; final Integer overrideDisplayId mForceDisplayOverrideInResources ? displayId : null; c.setResources createResources mToken, pi, null, overrideDisplayId, null, getDisplayAdjustments displayId .getCompatibilityInfo , null ; if c.mResources ! throw new PackageManager.NameNotFoundException Application package application.packageName not found ; createApplicationContext 75 ApplicationInfo에서 
 PackageInfo와 User 정보 가져와서 
 업데이트한 ContextImpl 생성 ContextImpl.java 컨텍스트 생성

Slide 76

Slide 76 text

createPackageContext 76 public Context createPackageContextAsUser String packageName, int flags, UserHandle user throws NameNotFoundException if packageName.equals system packageName.equals android return new ContextImpl this, mMainThread, mPackageInfo, mParams, mAttributionSource.getAttributionTag , mAttributionSource.getNext , null, mToken, user, flags, null, null ; LoadedApk pi mMainThread.getPackageInfo packageName, mResources.getCompatibilityInfo , flags CONTEXT REGISTER PACKAGE, user.getIdentifier ; if pi ! ContextImpl c new ContextImpl this, mMainThread, pi, mParams, mAttributionSource.getAttributionTag , mAttributionSource.getNext , null, mToken, user, flags, null, null ; final int displayId getDisplayId ; final Integer overrideDisplayId mForceDisplayOverrideInResources ? displayId : null; c.setResources createResources mToken, pi, null, overrideDisplayId, null, getDisplayAdjustments displayId .getCompatibilityInfo , null ; if c.mResources ! throw new PackageManager.NameNotFoundException Application package packageName not found ; ContextImpl.java 컨텍스트 생성

Slide 77

Slide 77 text

public Context createPackageContextAsUser String packageName, int flags, UserHandle user throws NameNotFoundException if packageName.equals system packageName.equals android return new ContextImpl this, mMainThread, mPackageInfo, mParams, mAttributionSource.getAttributionTag , mAttributionSource.getNext , null, mToken, user, flags, null, null ; LoadedApk pi mMainThread.getPackageInfo packageName, mResources.getCompatibilityInfo , flags CONTEXT REGISTER PACKAGE, user.getIdentifier ; if pi ! ContextImpl c new ContextImpl this, mMainThread, pi, mParams, mAttributionSource.getAttributionTag , mAttributionSource.getNext , null, mToken, user, flags, null, null ; final int displayId getDisplayId ; final Integer overrideDisplayId mForceDisplayOverrideInResources ? displayId : null; c.setResources createResources mToken, pi, null, overrideDisplayId, null, getDisplayAdjustments displayId .getCompatibilityInfo , null ; if c.mResources ! throw new PackageManager.NameNotFoundException Application package packageName not found ; createPackageContext 77 packageName으로 PackageInfo 가져와서 
 업데이트 한 ContextImpl 생성 ContextImpl.java 컨텍스트 생성

Slide 78

Slide 78 text

createContextForSplit 78 public Context createContextForSplit String splitName throws NameNotFoundException if !mPackageInfo.getApplicationInfo .requestsIsolatedSplitLoading return this; final ClassLoader classLoader mPackageInfo.getSplitClassLoader splitName ; final String paths mPackageInfo.getSplitPaths splitName ; final ContextImpl context new ContextImpl this, mMainThread, mPackageInfo, mParams, mAttributionSource.getAttributionTag , mAttributionSource.getNext , splitName, mToken, mUser, mFlags, classLoader, null ; context.setResources ResourcesManager.getInstance .getResources mToken, mPackageInfo.getResDir , paths, mPackageInfo.getOverlayDirs , mPackageInfo.getOverlayPaths , mPackageInfo.getApplicationInfo .sharedLibraryFiles, mForceDisplayOverrideInResources ? getDisplayId : null, null, mPackageInfo.getCompatibilityInfo , classLoader, mResources.getLoaders ; return context; ContextImpl.java 컨텍스트 생성

Slide 79

Slide 79 text

public Context createContextForSplit String splitName throws NameNotFoundException if !mPackageInfo.getApplicationInfo .requestsIsolatedSplitLoading return this; final ClassLoader classLoader mPackageInfo.getSplitClassLoader splitName ; final String paths mPackageInfo.getSplitPaths splitName ; final ContextImpl context new ContextImpl this, mMainThread, mPackageInfo, mParams, mAttributionSource.getAttributionTag , mAttributionSource.getNext , splitName, mToken, mUser, mFlags, classLoader, null ; context.setResources ResourcesManager.getInstance .getResources mToken, mPackageInfo.getResDir , paths, mPackageInfo.getOverlayDirs , mPackageInfo.getOverlayPaths , mPackageInfo.getApplicationInfo .sharedLibraryFiles, mForceDisplayOverrideInResources ? getDisplayId : null, null, mPackageInfo.getCompatibilityInfo , classLoader, mResources.getLoaders ; return context; createContextForSplit 79 splitName을 인자로 넘겨서 ClassLoader와 Paths를 생성하고 ContextImpl과 Resource 생성 ContextImpl.java 컨텍스트 생성

Slide 80

Slide 80 text

createDisplayContext 80 public Context createDisplayContext Display display if display null throw new IllegalArgumentException display must not be null ; ContextImpl context new ContextImpl this, mMainThread, mPackageInfo, mParams, mAttributionSource.getAttributionTag , mAttributionSource.getNext , mSplitName, mToken, mUser, mFlags, mClassLoader, null ; final int displayId display.getDisplayId ; Configuration overrideConfig new Configuration ; overrideConfig.setTo display.getDisplayAdjustments .getConfiguration , ActivityInfo.CONFIG WINDOW CONFIGURATION, 1 ; context.setResources createResources mToken, mPackageInfo, mSplitName, displayId, overrideConfig, display.getDisplayAdjustments .getCompatibilityInfo , mResources.getLoaders ; context.mDisplay display; context.mContextType mContextType ? CONTEXT TYPE SYSTEM OR SYSTEM UI context.mForceDisplayOverrideInResources true; context.mIsConfigurationBasedContext false; return context; ContextImpl.java 컨텍스트 생성

Slide 81

Slide 81 text

public Context createDisplayContext Display display if display null throw new IllegalArgumentException display must not be null ; ContextImpl context new ContextImpl this, mMainThread, mPackageInfo, mParams, mAttributionSource.getAttributionTag , mAttributionSource.getNext , mSplitName, mToken, mUser, mFlags, mClassLoader, null ; final int displayId display.getDisplayId ; Configuration overrideConfig new Configuration ; overrideConfig.setTo display.getDisplayAdjustments .getConfiguration , ActivityInfo.CONFIG WINDOW CONFIGURATION, 1 ; context.setResources createResources mToken, mPackageInfo, mSplitName, displayId, overrideConfig, display.getDisplayAdjustments .getCompatibilityInfo , mResources.getLoaders ; context.mDisplay display; context.mContextType mContextType ? CONTEXT TYPE SYSTEM OR SYSTEM UI context.mForceDisplayOverrideInResources true; context.mIsConfigurationBasedContext false; return context; createDisplayContext 81 Context 인스턴스에서 display 정보 업데이트 ContextImpl.java 컨텍스트 생성

Slide 82

Slide 82 text

createTokenContext 82 public Context createTokenContext if display null throw new IllegalArgumentException Display must not be null ; return createWindowContextBase token, display.getDisplayId ; createWindowContextBase로 전달 ContextImpl.java 컨텍스트 생성

Slide 83

Slide 83 text

createWindowContext 83 public WindowContext createWindowContext if display null throw new IllegalArgumentException Display must not be null ; return createWindowContextInternal display, type, options ; private WindowContext createWindowContextInternal final WindowTokenClient windowTokenClient new WindowTokenClient ; final ContextImpl windowContextBase createWindowContextBase windowTokenClient, display.getDisplayId ; final WindowContext windowContext new WindowContext windowContextBase, type, options ; windowContextBase.setOuterContext windowContext ; windowTokenClient.attachContext windowContext ; windowContext.attachToDisplayArea ; return windowContext; ContextImpl.java 컨텍스트 생성

Slide 84

Slide 84 text

public WindowContext createWindowContext if display null throw new IllegalArgumentException Display must not be null ; return createWindowContextInternal display, type, options ; private WindowContext createWindowContextInternal final WindowTokenClient windowTokenClient new WindowTokenClient ; final ContextImpl windowContextBase createWindowContextBase windowTokenClient, display.getDisplayId ; final WindowContext windowContext new WindowContext windowContextBase, type, options ; windowContextBase.setOuterContext windowContext ; windowTokenClient.attachContext windowContext ; windowContext.attachToDisplayArea ; return windowContext; createWindowContext 84 WindowCotext 타입 반환 ContextImpl.java 컨텍스트 생성

Slide 85

Slide 85 text

createAttributionContext 85 public return createContext new ContextParams.Builder mParams .setAttributionTag attributionTag .build ; ContextImpl.java 컨텍스트 생성

Slide 86

Slide 86 text

public return createContext new ContextParams.Builder mParams .setAttributionTag attributionTag .build ; createAttributionContext 86 AttributionTag만 재설정 ContextImpl.java 컨텍스트 생성

Slide 87

Slide 87 text

createConfigurationContext 87 public Context createConfigurationContext Configuration overrideConfiguration if overrideConfiguration null throw new IllegalArgumentException overrideConfiguration must not be null ; if mForceDisplayOverrideInResources Configuration displayAdjustedConfig new Configuration ; displayAdjustedConfig.setTo mDisplay.getDisplayAdjustments .getConfiguration , ActivityInfo.CONFIG WINDOW CONFIGURATION, 1 ; displayAdjustedConfig.updateFrom overrideConfiguration ; overrideConfiguration displayAdjustedConfig; ContextImpl context new ContextImpl this, mMainThread, mPackageInfo, mParams, mAttributionSource.getAttributionTag , mAttributionSource.getNext , mSplitName, mToken, mUser, mFlags, mClassLoader, null ; context.mIsConfigurationBasedContext true; final int displayId getDisplayId ; final Integer overrideDisplayId mForceDisplayOverrideInResources ? displayId : null; context.setResources createResources mToken, mPackageInfo, mSplitName, overrideDisplayId, overrideConfiguration, getDisplayAdjustments displayId .getCompatibilityInfo , mResources.getLoaders ; return context; ContextImpl.java 컨텍스트 생성

Slide 88

Slide 88 text

public Context createConfigurationContext Configuration overrideConfiguration if overrideConfiguration null throw new IllegalArgumentException overrideConfiguration must not be null ; if mForceDisplayOverrideInResources Configuration displayAdjustedConfig new Configuration ; displayAdjustedConfig.setTo mDisplay.getDisplayAdjustments .getConfiguration , ActivityInfo.CONFIG WINDOW CONFIGURATION, 1 ; displayAdjustedConfig.updateFrom overrideConfiguration ; overrideConfiguration displayAdjustedConfig; ContextImpl context new ContextImpl this, mMainThread, mPackageInfo, mParams, mAttributionSource.getAttributionTag , mAttributionSource.getNext , mSplitName, mToken, mUser, mFlags, mClassLoader, null ; context.mIsConfigurationBasedContext true; final int displayId getDisplayId ; final Integer overrideDisplayId mForceDisplayOverrideInResources ? displayId : null; context.setResources createResources mToken, mPackageInfo, mSplitName, overrideDisplayId, overrideConfiguration, getDisplayAdjustments displayId .getCompatibilityInfo , mResources.getLoaders ; return context; createConfigurationContext 88 리소스 생성 시 overrideConfiguration 사용 ContextImpl.java 컨텍스트 생성

Slide 89

Slide 89 text

storageContext 89 public Context createDeviceProtectedStorageContext final int flags mFlags Context.CONTEXT DEVICE PROTECTED STORAGE; return new ContextImpl this, mMainThread, mPackageInfo, mParams, mAttributionSource.getAttributionTag , mAttributionSource.getNext , mSplitName, mToken, mUser, flags, mClassLoader, null ; public Context createCredentialProtectedStorageContext final int flags mFlags Context.CONTEXT CREDENTIAL PROTECTED STORAGE; return new ContextImpl this, mMainThread, mPackageInfo, mParams, mAttributionSource.getAttributionTag , mAttributionSource.getNext , mSplitName, mToken, mUser, flags, mClassLoader, null ; ContextImpl.java 컨텍스트 생성

Slide 90

Slide 90 text

getImpl 90 static ContextImpl getImpl Context context Context nextContext; while context instanceof ContextWrapper nextContext ContextWrapper context .getBaseContext ! context nextContext; return ContextImpl context; 모든 Context는 ContextImpl에서 시작 ContextImpl.java 컨텍스트 생성

Slide 91

Slide 91 text

Summary - ContextImpl 91 private static 생성자 모든 Context는 ContextImpl로 시작 최상위 컨택스트: system/systemUi/app/activity Context는 일부 정보 갱신한 다양한 형태의 Context로 파생 ContextImpl.java 컨텍스트 생성

Slide 92

Slide 92 text

소스코드로 알아보는 안드로이드 Context ActivityThread.java 살펴보기 윤희성 세션 02

Slide 93

Slide 93 text

Main 함수 ActivityThread.java 살펴보기 93 public static void main String args Trace.traceBegin Trace.TRACE TAG ACTIVITY MANAGER, ActivityThreadMain ; AndroidOs.install ; CloseGuard.setEnabled false ; Environment.initForCurrentUser ; // … Looper.prepareMainLooper ; // … long startSeq // … ActivityThread thread new ActivityThread ; thread.attach false, startSeq ; if sMainThreadHandler null sMainThreadHandler thread.getHandler ; // … Looper.loop ; throw new RuntimeException Main thread loop unexpectedly exited ;

Slide 94

Slide 94 text

ActivityThread.H ActivityThread.java 살펴보기 94 class H extends Handler public static final int BIND APPLICATION // … public static final int RELAUNCH ACTIVITY // … public void handleMessage Message msg switch msg.what case BIND APPLICATION AppBindData data AppBindData msg.obj; handleBindApplication data ; break; case RELAUNCH ACTIVITY handleRelaunchActivityLocally IBinder msg.obj ; break; // …

Slide 95

Slide 95 text

ActivityThread ActivityThread.java 살펴보기 95

Slide 96

Slide 96 text

ClientTransactionHandler ActivityThread.java 살펴보기 96 /** * This manages the execution of the main thread in an * application process, scheduling and executing activities, * broadcasts, and other operations on it as the activity * manager requests. * * hide */ public final class ActivityThread extends ClientTransactionHandler implements ActivityThreadInternal /** hide */ public static final String TAG private static final android.graphics.Bitmap.Config THUMBNAIL FORMAT =

Slide 97

Slide 97 text

TransactionExecutor ActivityThread.java 살펴보기 97 public final class ActivityThread extends ClientTransactionHandler implements ActivityThreadInternal // … // An executor that performs multi step transactions. private final TransactionExecutor mTransactionExecutor new TransactionExecutor this ; // … class H extends Handler public void handleMessage Message msg // … switch msg.what case EXECUTE TRANSACTION final ClientTransaction transaction ClientTransaction msg.obj; mTransactionExecutor.execute transaction ; if isSystem transaction.recycle ; break;

Slide 98

Slide 98 text

ClientTransaction ActivityThread.java 살펴보기 98 /** * A container that holds a sequence of messages, which may be sent to a client. * This includes a list of callbacks and a final lifecycle state. * * see com.android.server.am.ClientLifecycleManager * see ClientTransactionItem * see ActivityLifecycleItem * hide */ public class ClientTransaction implements Parcelable, ObjectPoolItem /** A list of individual callbacks to a client. */ private List ClientTransactionItem mActivityCallbacks;

Slide 99

Slide 99 text

ObjectPoolItem ActivityThread.java 살펴보기 99 public interface ObjectPoolItem void recycle ; class ObjectPool private static final Object sPoolSync new Object ; private static final Map Class, ArrayList ? extends ObjectPoolItem sPoolMap new HashMap ; private static final int MAX POOL SIZE public static synchronized sPoolSync final ArrayList T if itemPool ! return itemPool.remove itemPool.size return null; public static synchronized sPoolSync ArrayList T if itemPool null itemPool new ArrayList ; sPoolMap.put item.getClass , itemPool ; final int size itemPool.size ; // … if size

Slide 100

Slide 100 text

BaseClientRequest ActivityThread.java 살펴보기 100 public interface BaseClientRequest extends ObjectPoolItem /** * Prepare the client request before scheduling. * An example of this might be informing about pending updates for some values. * * param client Target client handler. * param token Target activity token. */ default void preExecute ClientTransactionHandler client, IBinder token /** * Execute the request. * param client Target client handler. * param token Target activity token. * param pendingActions Container that may have data pending to be used. */ void execute ClientTransactionHandler client, IBinder token, PendingTransactionActions pendingActions ; /** * Perform all actions that need to happen after execution, e.g. report the result to server. * param client Target client handler. * param token Target activity token. * param pendingActions Container that may have data pending to be used. */ default void postExecute ClientTransactionHandler client, IBinder token, PendingTransactionActions pendingActions

Slide 101

Slide 101 text

ClientTransactionItem ActivityThread.java 살펴보기 101 /** * A callback message to a client that can be scheduled and executed. * Examples of these might be activity configuration change, multi window mode change, activity * result delivery etc. * * see ClientTransaction * see com.android.server.am.ClientLifecycleManager * hide */ public abstract class ClientTransactionItem implements BaseClientRequest, Parcelable /** Get the state that must follow this callback. */ public int getPostExecutionState return UNDEFINED; // Parcelable public int describeContents return 0; #5

Slide 102

Slide 102 text

LaunchActivityItem ActivityThread.java 살펴보기 102 public class LaunchActivityItem extends ClientTransactionItem // … private IBinder mTaskFragmentToken; private IActivityClientController mActivityClientController; public void preExecute ClientTransactionHandler client, IBinder token client.countLaunchingActivities 1 ; client.updateProcessState mProcState, false ; client.updatePendingConfiguration mCurConfig ; if mActivityClientController ! ActivityClient.setActivityClientController mActivityClientController ; public void execute ClientTransactionHandler client, IBinder token, PendingTransactionActions pendingActions ActivityClientRecord r new ActivityClientRecord token, /* … */ ; client.handleLaunchActivity r, pendingActions, null /* customIntent */ ; public void postExecute ClientTransactionHandler client, IBinder token, PendingTransactionActions pendingActions client.countLaunchingActivities

Slide 103

Slide 103 text

ActivityTransactionItem ActivityThread.java 살펴보기 103 public final class ActivityThread extends ClientTransactionHandler implements ActivityThreadInternal /** Activity client record, used for bookkeeping for the real link Activity instance. */ public static final class ActivityClientRecord public abstract class ActivityTransactionItem extends ClientTransactionItem 
 public final void execute ClientTransactionHandler client, IBinder token, PendingTransactionActions pendingActions final ActivityClientRecord r getActivityClientRecord client, token ; execute client, r, pendingActions ; public abstract void execute PendingTransactionActions pendingActions ; ActivityClientRecord getActivityClientRecord final ActivityClientRecord r client.getActivityClient token ; // … return r;

Slide 104

Slide 104 text

ActivityConfigurationChangeItem ActivityThread.java 살펴보기 104 public class ActivityConfigurationChangeItem extends ActivityTransactionItem private Configuration mConfiguration; public void preExecute android.app.ClientTransactionHandler client, IBinder token // Notify the client of an upcoming change in the token configuration. This ensures that // batches of config change items only process the newest configuration. client.updatePendingActivityConfiguration token, mConfiguration ; public void execute ClientTransactionHandler client, ActivityClientRecord r, PendingTransactionActions pendingActions // TODO lifecycler : detect if PIP or multi window mode changed and report it here. Trace.traceBegin TRACE TAG ACTIVITY MANAGER, activityConfigChanged ; client.handleActivityConfigurationChanged r, mConfiguration, INVALID DISPLAY ; Trace.traceEnd TRACE TAG ACTIVITY MANAGER ; // …

Slide 105

Slide 105 text

ActivityLifecycleItem ActivityThread.java 살펴보기 105 public abstract class ActivityLifecycleItem extends ActivityTransactionItem // … public interface LifecycleState public static final int UNDEFINED public static final int PRE ON CREATE public static final int ON CREATE public static final int ON START public static final int ON RESUME public static final int ON PAUSE public static final int ON STOP public static final int ON DESTROY public static final int ON RESTART public abstract int getTargetState ; public void recycle

Slide 106

Slide 106 text

ActivityLifecycleItem ActivityThread.java 살펴보기 106 public class StartActivityItem extends ActivityLifecycleItem private static final String TAG private ActivityOptions mActivityOptions; public void execute ClientTransactionHandler client, ActivityClientRecord r, PendingTransactionActions pendingActions Trace.traceBegin TRACE TAG ACTIVITY MANAGER, startActivityItem ; client.handleStartActivity r, pendingActions, mActivityOptions ; Trace.traceEnd TRACE TAG ACTIVITY MANAGER ; public int getTargetState return ON START;

Slide 107

Slide 107 text

ActivityLifecycleItem ActivityThread.java 살펴보기 107 public class StartActivityItem extends ActivityLifecycleItem // … public int getTargetState return ON START; public class StopActivityItem extends ActivityLifecycleItem // … public int getTargetState return ON STOP; 
 public class ResumeActivityItem extends ActivityLifecycleItem // … public int getTargetState return ON RESUME; public class PauseActivityItem extends ActivityLifecycleItem // … public int getTargetState return ON PAUSE; public class DestroyActivityItem extends ActivityLifecycleItem // … public int getTargetState return ON DESTROY; 


Slide 108

Slide 108 text

생명주기 알아보기 ActivityThread.java 살펴보기 108 public class TransactionExecutor // … public void execute ClientTransaction transaction final IBinder token transaction.getActivityToken ; // … executeCallbacks transaction ; executeLifecycleState transaction ; mPendingActions.clear ;

Slide 109

Slide 109 text

생명주기 알아보기 ActivityThread.java 살펴보기 109 public class TransactionExecutor // … /** Transition to the final state if requested by the transaction. */ private void executeLifecycleState ClientTransaction transaction final ActivityLifecycleItem lifecycleItem transaction.getLifecycleStateRequest ; if lifecycleItem null // No lifecycle request, return early. return; final IBinder token transaction.getActivityToken ; final ActivityClientRecord r mTransactionHandler.getActivityClient token ; // … // Cycle to the state right before the final requested state. cycleToPath r, lifecycleItem.getTargetState , true /* excludeLastState */, transaction ; // Execute the final transition with proper parameters. lifecycleItem.execute mTransactionHandler, token, mPendingActions ; lifecycleItem.postExecute mTransactionHandler, token, mPendingActions ;

Slide 110

Slide 110 text

생명주기 알아보기 ActivityThread.java 살펴보기 110 public class TransactionExecutor // … * Transition the client between states with an option not to perform the last hop in the * sequence. This is used when resolving lifecycle state request, when the last transition must * be performed with some specific parameters. */ private void cycleToPath ActivityClientRecord r, int finish, boolean excludeLastState, ClientTransaction transaction final int start r.getLifecycleState ; if DEBUG RESOLVER Slog.d TAG, tId transaction Cycle activity: getShortActivityName r.token, mTransactionHandler from: getStateName start to: getStateName finish excludeLastState: excludeLastState ; final IntArray path mHelper.getLifecyclePath start, finish, excludeLastState ; performLifecycleSequence r, path, transaction ; /** Get the current lifecycle state. */ public int getLifecycleState return mLifecycleState; 전환하고자 하는 LifecycleState

Slide 111

Slide 111 text

ActivityThread.java 살펴보기 111 public class TransactionExecutorHelper // … // … mLifecycleSequence.clear ; if finish start if start mLifecycleSequence.add ON STOP ; else for int i start // … if excludeLastState mLifecycleSequence.size ! mLifecycleSequence.remove mLifecycleSequence.size return mLifecycleSequence; public static final int UNDEFINED public static final int PRE ON CREATE public static final int ON CREATE public static final int ON START public static final int ON RESUME public static final int ON PAUSE public static final int ON STOP public static final int ON DESTROY public static final int ON RESTART = #6 생명주기 알아보기

Slide 112

Slide 112 text

생명주기 알아보기 public class TransactionExecutor // … private void performLifecycleSequence ActivityClientRecord r, IntArray path, ClientTransaction transaction final int size path.size ; for int i state path.get i ; switch state case ON CREATE mTransactionHandler.handleLaunchActivity r, mPendingActions, /* .. */ ; ; break; case ON START mTransactionHandler.handleStartActivity r, mPendingActions, /* .. */ ; ; break; case ON RESUME mTransactionHandler.handleResumeActivity r, false, /* .. */ ; break; case ON PAUSE mTransactionHandler.handlePauseActivity r, false, /* .. */ ; break; case ON STOP mTransactionHandler.handleStopActivity r, 0 /* configChanges */, /* .. */ ; break; case ON DESTROY mTransactionHandler.handleDestroyActivity r, false /* finishing */, /* .. */ ; break; case ON RESTART mTransactionHandler.performRestartActivity r, false /* start */ ; break; // … ActivityThread.java 살펴보기 112

Slide 113

Slide 113 text

Summary - ActivityThread ContextImpl.java 살펴보기 113 ActivityThread는 ClientTransActionHandler의 서브 클래스 BaseClientRequest는 ActivityThread의 특정 동작을 추상화 한 클래스 ActivityTransactionItem은 액티비티가 생성된 이후 수행되는 동작을 정의 ActivityLifecyleItem은 액티비티 생명주기와 관련 동작 정의 TransActionExecutorHelper::getLifecyclePath에서 ActivitiyLifecycyle 순서 생성 Lifecycle 동작은 handleLaunchActivity, handleStartActivity, handleStopActivity 등에 정의

Slide 114

Slide 114 text

소스코드로 알아보는 안드로이드 Context 애플리케이션 /액티비티 윤희성 세션 02

Slide 115

Slide 115 text

Context::getApplicationContext ApplicationContext 찾기 애플리케이션//액티비티 115 class ContextImpl extends Context public Context getApplicationContext return mPackageInfo ! mPackageInfo.getApplication : mMainThread.getApplication ;

Slide 116

Slide 116 text

LoadedApk::getApplication ApplicationContext 찾기 애플리케이션//액티비티 116 public final class LoadedApk // … return mApplication; // … private Application makeApplicationInner boolean forceDefaultAppClass, Instrumentation instrumentation, boolean allowDuplicateInstances // … Application app null; // … ContextImpl appContext // … app mActivityThread.mInstrumentation.newApplication cl, appClass, appContext ; appContext.setOuterContext app ; // … mActivityThread.mAllApplications.add app ; mApplication app;

Slide 117

Slide 117 text

LoadedApk::makeApplicationInner ApplicationContext 찾기 애플리케이션//액티비티 117 public final class LoadedApk // … return mApplication; // … private Application makeApplicationInner boolean forceDefaultAppClass, Instrumentation instrumentation, boolean allowDuplicateInstances // … Application app null; // … ContextImpl appContext // … app mActivityThread.mInstrumentation.newApplication cl, appClass, appContext ; appContext.setOuterContext app ; // … mActivityThread.mAllApplications.add app ; mApplication app;

Slide 118

Slide 118 text

LoadedApk::makeApplicationInner ApplicationContext 찾기 애플리케이션//액티비티 118 public final class LoadedApk // … return mApplication; // … private Application makeApplicationInner boolean forceDefaultAppClass, Instrumentation instrumentation, boolean allowDuplicateInstances // … Application app null; // … ContextImpl appContext // … app mActivityThread.mInstrumentation.newApplication cl, appClass, appContext ; appContext.setOuterContext app ; // … mActivityThread.mAllApplications.add app ; mApplication app;

Slide 119

Slide 119 text

LoadedApk::makeApplicationInner ApplicationContext 찾기 애플리케이션//액티비티 119 public final class LoadedApk // … return mApplication; // … private Application makeApplicationInner boolean forceDefaultAppClass, Instrumentation instrumentation, boolean allowDuplicateInstances // … Application app null; // … ContextImpl appContext // … app mActivityThread.mInstrumentation.newApplication cl, appClass, appContext ; appContext.setOuterContext app ; // … mActivityThread.mAllApplications.add app ; mApplication app;

Slide 120

Slide 120 text

Instrumentation::newApplication ApplicationContext 찾기 애플리케이션//액티비티 120 public class Instrumentation public Application newApplication ClassLoader cl, String className, Context context throws /* … */ Application app getFactory context.getPackageName .instantiateApplication cl, className ; app.attach context ; return app; Application::attach public class Application extends ContextWrapper implements ComponentCallbacks2 attachBaseContext context ; mLoadedApk

Slide 121

Slide 121 text

Instrumentation::newApplication ApplicationContext 찾기 애플리케이션//액티비티 121 Application::attach public class Instrumentation public Application newApplication ClassLoader cl, String className, Context context throws /* … */ Application app getFactory context.getPackageName .instantiateApplication cl, className ; app.attach context ; return app; public class Application extends ContextWrapper implements ComponentCallbacks2 attachBaseContext context ; mLoadedApk

Slide 122

Slide 122 text

ApplicationContext 애플리케이션//액티비티 122 Application은 ContextWrapper의 서브 클래스 Application 객체는 appContext를 base로 가지고 기능을 확장한 클래스 < < Application Application < < ContextImpl 
 appContext

Slide 123

Slide 123 text

ActivityThread::handleLaunchActivity ActivityContext 찾기 애플리케이션//액티비티 123 public Activity handleLaunchActivity ActivityClientRecord r, PendingTransactionActions pendingActions, Intent customIntent // … final Activity a performLaunchActivity r, customIntent ; // … return a;

Slide 124

Slide 124 text

ActivityThread::performLaunchActivity ActivityContext 찾기 애플리케이션//액티비티 124 private Activity performLaunchActivity ActivityClientRecord r, Intent customIntent ActivityInfo aInfo r.activityInfo; // … ContextImpl appContext createBaseContextForActivity r ; Activity activity null; // … activity mInstrumentation.newActivity cl, component.getClassName , r.intent ; // … appContext.setOuterContext activity ; activity.attach appContext, this, /* … */ ; // … int theme r.activityInfo.getThemeResource ; if theme ! // … mInstrumentation.callActivityOnCreate activity, r.state, r.persistentState ; // … r.setState ON CREATE ; // … return activity;

Slide 125

Slide 125 text

ActivityThread::performLaunchActivity ActivityContext 찾기 애플리케이션//액티비티 125 private Activity performLaunchActivity ActivityClientRecord r, Intent customIntent ActivityInfo aInfo r.activityInfo; // … ContextImpl appContext createBaseContextForActivity r ; Activity activity null; // … activity mInstrumentation.newActivity cl, component.getClassName , r.intent ; // … appContext.setOuterContext activity ; activity.attach appContext, this, /* … */ ; // … int theme r.activityInfo.getThemeResource ; if theme ! // … mInstrumentation.callActivityOnCreate activity, r.state, r.persistentState ; // … r.setState ON CREATE ; // … return activity;

Slide 126

Slide 126 text

ActivityThread::performLaunchActivity ActivityContext 찾기 애플리케이션//액티비티 126 private ContextImpl createBaseContextForActivity ActivityClientRecord r final int displayId ContextImpl appContext this, r.packageInfo, r.activityInfo, r.token, displayId, r.overrideConfig ; final DisplayManagerGlobal dm // … String pkgName if pkgName ! r.packageInfo.mPackageName.contains pkgName for int id : dm.getDisplayIds if id ! Display display dm.getCompatibleDisplay id, appContext.getResources ; appContext ContextImpl appContext.createDisplayContext display ; break; return appContext;

Slide 127

Slide 127 text

ActivityThread::performLaunchActivity ActivityContext 찾기 애플리케이션//액티비티 127 private Activity performLaunchActivity ActivityClientRecord r, Intent customIntent ActivityInfo aInfo r.activityInfo; // … ContextImpl appContext createBaseContextForActivity r ; Activity activity null; // … activity mInstrumentation.newActivity cl, component.getClassName , r.intent ; // … appContext.setOuterContext activity ; activity.attach appContext, this, /* … */ ; // … int theme r.activityInfo.getThemeResource ; if theme ! // … mInstrumentation.callActivityOnCreate activity, r.state, r.persistentState ; // … r.setState ON CREATE ; // … return activity;

Slide 128

Slide 128 text

Activity::attach ActivityContext 찾기 애플리케이션//액티비티 128 final void attach Context context, ActivityThread aThread, Instrumentation instr, IBinder token, int ident, Application application, Intent intent, ActivityInfo info, CharSequence title, Activity parent, String id, NonConfigurationInstances lastNonConfigurationInstances, Configuration config, String referrer, IVoiceInteractor voiceInteractor, Window window, ActivityConfigCallback activityConfigCallback, IBinder assistToken, IBinder shareableActivityToken attachBaseContext context ; mFragments.attachHost null /*parent*/ ;

Slide 129

Slide 129 text

AcivityContext 애플리케이션//액티비티 129 Activity는 ContextThemeWrapper의 서브 클래스 Activity 객체는 activityContext를 base로 가지는 기능을 확장한 클래스 < < Activity Activity < < ContextImpl 
 activityContext

Slide 130

Slide 130 text

소스코드로 알아보는 안드로이드 Context 요약 윤희성 세션 02

Slide 131

Slide 131 text

Things we know about Context Compose 적용 의사결정 과정 131 Context는 추상 클래스 / ContextImpl는 구현 클래스 액티비티, 서비스, 어플리케이션 등은 ContextWrapper의 서브 클래스 Context는 시스템 의존 동작을 API로 제공 및 식별자로 사용 모든 컨택스트는 System/SystemUi/App/Activity Context 부터 시작 기존 Context로 부터 일부 정보를 수정한 다양한 Context 생성 액티비티는 activityContext를 베이스 객체로 확장한 클래스 애플리케이션는 appContext를 베이스 객체로 확장한 클래스

Slide 132

Slide 132 text

소스코드로 알아보는 안드로이드 Context 윤희성 세션 02 Slide

Slide 133

Slide 133 text

소스코드로 알아보는 안드로이드 Context 윤희성 세션 02 Thanks Medium: https://quokkaman.medium.com/ email: heesung6701 naver.com kakao id: Writers GitHub: heesung6701

Slide 134

Slide 134 text

소스코드로 알아보는 안드로이드 Context 윤희성 세션 02 Appendix Medium: https://quokkaman.medium.com/

Slide 135

Slide 135 text

ActivityManagerService 생성 까지 ActivityThread.java 살펴보기 135 int main int argc, char* const argv //… if zygote runtime.start com.android.internal.os.ZygoteInit , args, zygote ; frameworks/base/cmds/app process/app main.cpp void AndroidRuntime::start const char* className, const Vector String8 > options, bool zygote // … char* slashClassName toSlashClassName className ! = NULL ? className : ; jclass startClass env -> FindClass slashClassName ; if startClass = = NULL ALOGE JavaVM unable to locate class s \n , slashClassName ; else jmethodID startMeth env -> GetStaticMethodID startClass, main , Ljava/lang/String; V ; if startMeth = = NULL ALOGE JavaVM unable to find main in s \n , className ; else env -> CallStaticVoidMethod startClass, startMeth, strArray ; free slashClassName ; #1 frameworks/base/core/jni/AndroidRuntime.cpp

Slide 136

Slide 136 text

createWindowContextBase 136 @ UiContext ContextImpl createWindowContextBase @ NonNull IBinder token, int displayId ContextImpl baseContext new ContextImpl this, mMainThread, mPackageInfo, mParams, mAttributionSource.getAttributionTag , mAttributionSource.getNext , mSplitName, token, mUser, mFlags, mClassLoader, null ; baseContext.mForceDisplayOverrideInResources false; baseContext.mContextType = CONTEXT TYPE WINDOW CONTEXT; final Resources windowContextResources createWindowContextResources baseContext ; baseContext.setResources windowContextResources ; 
 baseContext.mDisplay = ResourcesManager.getInstance .getAdjustedDisplay displayId, windowContextResources ; return baseContext; ContextImpl.java 컨텍스트 생성 #2

Slide 137

Slide 137 text

ResourcesManager::getInstance 137 @ UnsupportedAppUsage public static ResourcesManager getInstance synchronized ResourcesManager.class if sResourcesManager null sResourcesManager new ResourcesManager ; return sResourcesManager; ResourcesManager::getAdjustedDisplay public Display getAdjustedDisplay final int displayId, Resources resources synchronized mLock final DisplayManagerGlobal dm = DisplayManagerGlobal.getInstance ; if dm null // may be null early in system startup return null; return dm.getCompatibleDisplay displayId, resources ; displayId와 resources로 Display 객체를 생성 Singleton 객체 ContextImpl.java 컨텍스트 생성 #2

Slide 138

Slide 138 text

ContextImpl::isSystemOrSystemUI 138 private static boolean isSystemOrSystemUI Context context return ActivityThread.isSystem context.checkPermission android.permission.STATUS BAR SERVICE , Binder.getCallingPid , Binder.getCallingUid = = PERMISSION GRANTED; ContextImpl.java 컨텍스트 생성 #3

Slide 139

Slide 139 text

ActivityThread::isSystem 139 public static boolean isSystem return sCurrentActivityThread ! = null ? sCurrentActivityThread.mSystemThread : false; private void attach boolean system, long startSeq sCurrentActivityThread this; // … mSystemThread system; 
 // … 
 public static void main String args // … ActivityThread thread new ActivityThread ; thread.attach false, startSeq ; 
 // … 
 public static ActivityThread systemMain // … ActivityThread thread new ActivityThread ; thread.attach true, 0 ; return thread; ContextImpl.java 컨텍스트 생성 #3

Slide 140

Slide 140 text

ActivityThread::isSystem 140 public static boolean isSystem return sCurrentActivityThread ! = null ? sCurrentActivityThread.mSystemThread : false; private void attach boolean system, long startSeq sCurrentActivityThread this; // … mSystemThread system; 
 // … 
 public static void main String args // … ActivityThread thread new ActivityThread ; thread.attach false, startSeq ; 
 // … 
 public static ActivityThread systemMain // … ActivityThread thread new ActivityThread ; thread.attach true, 0 ; return thread; ContextImpl.java 컨텍스트 생성 #3

Slide 141

Slide 141 text

ActivityThread::isSystem 141 public static void main String args // … ActivityThread thread new ActivityThread ; thread.attach false, startSeq ; 
 // … 
 public static ActivityThread systemMain // … ActivityThread thread new ActivityThread ; thread.attach true, 0 ; return thread; ContextImpl.java 컨텍스트 생성 public static boolean isSystem return sCurrentActivityThread ! = null ? sCurrentActivityThread.mSystemThread : false; private void attach boolean system, long startSeq sCurrentActivityThread this; // … mSystemThread system; 
 // … 
 #3

Slide 142

Slide 142 text

/** * Indicates this link Context can not handle UI components properly and is not associated * with a link Display instance. */ private static final int CONTEXT TYPE NON UI = 0; /** * Indicates this link Context is associated with a link Display instance but should not * be handled UI components properly because it doesn t receive configuration changes * regardless of display property updates. */ private static final int CONTEXT TYPE DISPLAY CONTEXT = 1; /** * Indicates this link Context is an link Activity or link Activity derived * link Context . */ private static final int CONTEXT TYPE ACTIVITY = 2; /** * Indicates this link Context is a link WindowContext or link WindowContext derived * link Context . */ private static final int CONTEXT TYPE WINDOW CONTEXT = 3; // TODO b/170369943 : Remove after WindowContext migration /** * Indicates this link Context is created from link #createSystemContext ActivityThread * or link #createSystemUiContext ContextImpl, int or any link Context that system UI * uses. */ private static final int CONTEXT TYPE SYSTEM OR SYSTEM UI = 4; Context Type 142 @ IntDef prefix CONTEXT TYPE , value CONTEXT TYPE NON UI, CONTEXT TYPE DISPLAY CONTEXT, CONTEXT TYPE ACTIVITY, CONTEXT TYPE WINDOW CONTEXT, CONTEXT TYPE SYSTEM OR SYSTEM UI @ Retention RetentionPolicy.SOURCE private interface ContextType ContextImpl.java 컨텍스트 생성 #4

Slide 143

Slide 143 text

Context Type 143 /** * Indicates this link Context can not handle UI components properly and is not associated * with a link Display instance. */ private static final int CONTEXT TYPE NON UI = 0; /** * Indicates this link Context is associated with a link Display instance but should not * be handled UI components properly because it doesn t receive configuration changes * regardless of display property updates. */ private static final int CONTEXT TYPE DISPLAY CONTEXT = 1; /** * Indicates this link Context is an link Activity or link Activity derived * link Context . */ private static final int CONTEXT TYPE ACTIVITY = 2; /** * Indicates this link Context is a link WindowContext or link WindowContext derived * link Context . */ private static final int CONTEXT TYPE WINDOW CONTEXT = 3; // TODO b/170369943 : Remove after WindowContext migration /** * Indicates this link Context is created from link #createSystemContext ActivityThread * or link #createSystemUiContext ContextImpl, int or any link Context that system UI * uses. */ private static final int CONTEXT TYPE SYSTEM OR SYSTEM UI = 4; @ IntDef prefix CONTEXT TYPE , value CONTEXT TYPE NON UI, CONTEXT TYPE DISPLAY CONTEXT, CONTEXT TYPE ACTIVITY, CONTEXT TYPE WINDOW CONTEXT, CONTEXT TYPE SYSTEM OR SYSTEM UI @ Retention RetentionPolicy.SOURCE private interface ContextType ContextImpl.java 컨텍스트 생성 #4

Slide 144

Slide 144 text

@ Override public boolean isUiContext switch mContextType case CONTEXT TYPE ACTIVITY : case CONTEXT TYPE WINDOW CONTEXT : case CONTEXT TYPE SYSTEM OR SYSTEM UI : return true; case CONTEXT TYPE DISPLAY CONTEXT : case CONTEXT TYPE NON UI : return false; default: return false; static ContextImpl createAppContext ActivityThread mainThread, LoadedApk packageInfo, String opPackageName if packageInfo null throw new IllegalArgumentException packageInfo ; ContextImpl context new ContextImpl null, mainThread, packageInfo, ContextParams.EMPTY, null, null, null, null, null, 0, null, opPackageName ; context.setResources packageInfo.getResources ; context.mContextType isSystemOrSystemUI context ? CONTEXT TYPE SYSTEM OR SYSTEM UI : CONTEXT TYPE NON UI; return context; TYPE NON UI 144 ContextImpl.java 컨텍스트 생성 #4

Slide 145

Slide 145 text

TYPE NON UI 145 @ Override public boolean isUiContext switch mContextType case CONTEXT TYPE ACTIVITY : case CONTEXT TYPE WINDOW CONTEXT : case CONTEXT TYPE SYSTEM OR SYSTEM UI : return true; case CONTEXT TYPE DISPLAY CONTEXT : case CONTEXT TYPE NON UI : return false; default: return false; static ContextImpl createAppContext ActivityThread mainThread, LoadedApk packageInfo, String opPackageName if packageInfo null throw new IllegalArgumentException packageInfo ; ContextImpl context new ContextImpl null, mainThread, packageInfo, ContextParams.EMPTY, null, null, null, null, null, 0, null, opPackageName ; context.setResources packageInfo.getResources ; context.mContextType isSystemOrSystemUI context ? CONTEXT TYPE SYSTEM OR SYSTEM UI : CONTEXT TYPE NON UI; return context; ContextImpl.java 컨텍스트 생성 #4

Slide 146

Slide 146 text

Context Type 146 /** * Indicates this link Context can not handle UI components properly and is not associated * with a link Display instance. */ private static final int CONTEXT TYPE NON UI = 0; /** * Indicates this link Context is associated with a link Display instance but should not * be handled UI components properly because it doesn t receive configuration changes * regardless of display property updates. */ private static final int CONTEXT TYPE DISPLAY CONTEXT = 1; /** * Indicates this link Context is an link Activity or link Activity derived * link Context . */ private static final int CONTEXT TYPE ACTIVITY = 2; /** * Indicates this link Context is a link WindowContext or link WindowContext derived * link Context . */ private static final int CONTEXT TYPE WINDOW CONTEXT = 3; // TODO b/170369943 : Remove after WindowContext migration /** * Indicates this link Context is created from link #createSystemContext ActivityThread * or link #createSystemUiContext ContextImpl, int or any link Context that system UI * uses. */ private static final int CONTEXT TYPE SYSTEM OR SYSTEM UI = 4; @ IntDef prefix CONTEXT TYPE , value CONTEXT TYPE NON UI, CONTEXT TYPE DISPLAY CONTEXT, CONTEXT TYPE ACTIVITY, CONTEXT TYPE WINDOW CONTEXT, CONTEXT TYPE SYSTEM OR SYSTEM UI @ Retention RetentionPolicy.SOURCE private interface ContextType ContextImpl.java 컨텍스트 생성 #4

Slide 147

Slide 147 text

private boolean isAssociatedWithDisplay switch mContextType case CONTEXT TYPE DISPLAY CONTEXT : case CONTEXT TYPE ACTIVITY : case CONTEXT TYPE WINDOW CONTEXT : // TODO b/170369943 : Remove after WindowContext migration case CONTEXT TYPE SYSTEM OR SYSTEM UI : return true; default: return false; @ Override public void updateDisplay int displayId mDisplay mResourcesManager.getAdjustedDisplay displayId, mResources ; if mContextType = = CONTEXT TYPE NON UI mContextType = CONTEXT TYPE DISPLAY CONTEXT; TYPE DISPLAY CONTEXT 147 @ Override public boolean isUiContext switch mContextType case CONTEXT TYPE ACTIVITY : case CONTEXT TYPE WINDOW CONTEXT : case CONTEXT TYPE SYSTEM OR SYSTEM UI : return true; case CONTEXT TYPE DISPLAY CONTEXT : case CONTEXT TYPE NON UI : return false; default: return false; ContextImpl.java 컨텍스트 생성 #4

Slide 148

Slide 148 text

@ Override public void updateDisplay int displayId mDisplay mResourcesManager.getAdjustedDisplay displayId, mResources ; if mContextType = = CONTEXT TYPE NON UI mContextType = CONTEXT TYPE DISPLAY CONTEXT; TYPE DISPLAY CONTEXT 148 ContextImpl.java 컨텍스트 생성 @ Override public boolean isUiContext switch mContextType case CONTEXT TYPE ACTIVITY : case CONTEXT TYPE WINDOW CONTEXT : case CONTEXT TYPE SYSTEM OR SYSTEM UI : return true; case CONTEXT TYPE DISPLAY CONTEXT : case CONTEXT TYPE NON UI : return false; default: return false; private boolean isAssociatedWithDisplay switch mContextType case CONTEXT TYPE DISPLAY CONTEXT : case CONTEXT TYPE ACTIVITY : case CONTEXT TYPE WINDOW CONTEXT : // TODO b/170369943 : Remove after WindowContext migration case CONTEXT TYPE SYSTEM OR SYSTEM UI : return true; default: return false; #4

Slide 149

Slide 149 text

@ Override public boolean isUiContext switch mContextType case CONTEXT TYPE ACTIVITY : case CONTEXT TYPE WINDOW CONTEXT : case CONTEXT TYPE SYSTEM OR SYSTEM UI : return true; case CONTEXT TYPE DISPLAY CONTEXT : case CONTEXT TYPE NON UI : return false; default: return false; TYPE DISPLAY CONTEXT 149 ContextImpl.java 컨텍스트 생성 private boolean isAssociatedWithDisplay switch mContextType case CONTEXT TYPE DISPLAY CONTEXT : case CONTEXT TYPE ACTIVITY : case CONTEXT TYPE WINDOW CONTEXT : // TODO b/170369943 : Remove after WindowContext migration case CONTEXT TYPE SYSTEM OR SYSTEM UI : return true; default: return false; @ Override public void updateDisplay int displayId mDisplay mResourcesManager.getAdjustedDisplay displayId, mResources ; if mContextType = = CONTEXT TYPE NON UI mContextType = CONTEXT TYPE DISPLAY CONTEXT; #4

Slide 150

Slide 150 text

TYPE DISPLAY CONTEXT 150 @ Override public Context createDisplayContext Display display if display null throw new IllegalArgumentException display must not be null ; ContextImpl context new ContextImpl this, mMainThread, mPackageInfo, mParams, mAttributionSource.getAttributionTag , mAttributionSource.getNext , mSplitName, mToken, mUser, mFlags, mClassLoader, null ; // … context.setResources createResources mToken, mPackageInfo, mSplitName, displayId, overrideConfig, display.getDisplayAdjustments .getCompatibilityInfo , mResources.getLoaders ; context.mDisplay display; context.mContextType mContextType = = CONTEXT TYPE SYSTEM OR SYSTEM UI ? CONTEXT TYPE SYSTEM OR SYSTEM UI : CONTEXT TYPE DISPLAY CONTEXT; context.mForceDisplayOverrideInResources true; context.mIsConfigurationBasedContext false; return context; ContextImpl.java 컨텍스트 생성 #4

Slide 151

Slide 151 text

Context Type 151 /** * Indicates this link Context can not handle UI components properly and is not associated * with a link Display instance. */ private static final int CONTEXT TYPE NON UI = 0; /** * Indicates this link Context is associated with a link Display instance but should not * be handled UI components properly because it doesn t receive configuration changes * regardless of display property updates. */ private static final int CONTEXT TYPE DISPLAY CONTEXT = 1; /** * Indicates this link Context is an link Activity or link Activity derived * link Context . */ private static final int CONTEXT TYPE ACTIVITY = 2; /** * Indicates this link Context is a link WindowContext or link WindowContext derived * link Context . */ private static final int CONTEXT TYPE WINDOW CONTEXT = 3; // TODO b/170369943 : Remove after WindowContext migration /** * Indicates this link Context is created from link #createSystemContext ActivityThread * or link #createSystemUiContext ContextImpl, int or any link Context that system UI * uses. */ private static final int CONTEXT TYPE SYSTEM OR SYSTEM UI = 4; @ IntDef prefix CONTEXT TYPE , value CONTEXT TYPE NON UI, CONTEXT TYPE DISPLAY CONTEXT, CONTEXT TYPE ACTIVITY, CONTEXT TYPE WINDOW CONTEXT, CONTEXT TYPE SYSTEM OR SYSTEM UI @ Retention RetentionPolicy.SOURCE private interface ContextType ContextImpl.java 컨텍스트 생성 #4

Slide 152

Slide 152 text

TYPE ACTIVITY 152 @ Override public boolean isUiContext switch mContextType case CONTEXT TYPE ACTIVITY : case CONTEXT TYPE WINDOW CONTEXT : case CONTEXT TYPE SYSTEM OR SYSTEM UI : return true; case CONTEXT TYPE DISPLAY CONTEXT : case CONTEXT TYPE NON UI : return false; default: return false; ContextImpl.java 컨텍스트 생성 private boolean isAssociatedWithDisplay switch mContextType case CONTEXT TYPE DISPLAY CONTEXT : case CONTEXT TYPE ACTIVITY : case CONTEXT TYPE WINDOW CONTEXT : // TODO b/170369943 : Remove after WindowContext migration case CONTEXT TYPE SYSTEM OR SYSTEM UI : return true; default: return false; @ Override @ UnsupportedAppUsage public IBinder getActivityToken return mContextType = = CONTEXT TYPE ACTIVITY ? mToken : null; #4

Slide 153

Slide 153 text

TYPE ACTIVITY 153 ContextImpl.java 컨텍스트 생성 @ Override public boolean isUiContext switch mContextType case CONTEXT TYPE ACTIVITY : case CONTEXT TYPE WINDOW CONTEXT : case CONTEXT TYPE SYSTEM OR SYSTEM UI : return true; case CONTEXT TYPE DISPLAY CONTEXT : case CONTEXT TYPE NON UI : return false; default: return false; private boolean isAssociatedWithDisplay switch mContextType case CONTEXT TYPE DISPLAY CONTEXT : case CONTEXT TYPE ACTIVITY : case CONTEXT TYPE WINDOW CONTEXT : // TODO b/170369943 : Remove after WindowContext migration case CONTEXT TYPE SYSTEM OR SYSTEM UI : return true; default: return false; @ Override @ UnsupportedAppUsage public IBinder getActivityToken return mContextType = = CONTEXT TYPE ACTIVITY ? mToken : null; #4

Slide 154

Slide 154 text

@ Override public boolean isUiContext switch mContextType case CONTEXT TYPE ACTIVITY : case CONTEXT TYPE WINDOW CONTEXT : case CONTEXT TYPE SYSTEM OR SYSTEM UI : return true; case CONTEXT TYPE DISPLAY CONTEXT : case CONTEXT TYPE NON UI : return false; default: return false; private boolean isAssociatedWithDisplay switch mContextType case CONTEXT TYPE DISPLAY CONTEXT : case CONTEXT TYPE ACTIVITY : case CONTEXT TYPE WINDOW CONTEXT : // TODO b/170369943 : Remove after WindowContext migration case CONTEXT TYPE SYSTEM OR SYSTEM UI : return true; default: return false; @ Override @ UnsupportedAppUsage public IBinder getActivityToken return mContextType = = CONTEXT TYPE ACTIVITY ? mToken : null; TYPE ACTIVITY 154 ContextImpl.java 컨텍스트 생성 #4

Slide 155

Slide 155 text

TYPE ACTIVITY 155 static ContextImpl createActivityContext ActivityThread mainThread, LoadedApk packageInfo, ActivityInfo activityInfo, IBinder activityToken, int displayId, Configuration overrideConfiguration // … ContextImpl context new ContextImpl null, mainThread, packageInfo, ContextParams.EMPTY, attributionTag, null, activityInfo.splitName, activityToken, null, 0, classLoader, null ; context.mContextType = CONTEXT TYPE ACTIVITY; context.mIsConfigurationBasedContext true; ContextImpl.java 컨텍스트 생성 #4

Slide 156

Slide 156 text

Context Type 156 /** * Indicates this link Context can not handle UI components properly and is not associated * with a link Display instance. */ private static final int CONTEXT TYPE NON UI = 0; /** * Indicates this link Context is associated with a link Display instance but should not * be handled UI components properly because it doesn t receive configuration changes * regardless of display property updates. */ private static final int CONTEXT TYPE DISPLAY CONTEXT = 1; /** * Indicates this link Context is an link Activity or link Activity derived * link Context . */ private static final int CONTEXT TYPE ACTIVITY = 2; /** * Indicates this link Context is a link WindowContext or link WindowContext derived * link Context . */ private static final int CONTEXT TYPE WINDOW CONTEXT = 3; // TODO b/170369943 : Remove after WindowContext migration /** * Indicates this link Context is created from link #createSystemContext ActivityThread * or link #createSystemUiContext ContextImpl, int or any link Context that system UI * uses. */ private static final int CONTEXT TYPE SYSTEM OR SYSTEM UI = 4; @ IntDef prefix CONTEXT TYPE , value CONTEXT TYPE NON UI, CONTEXT TYPE DISPLAY CONTEXT, CONTEXT TYPE ACTIVITY, CONTEXT TYPE WINDOW CONTEXT, CONTEXT TYPE SYSTEM OR SYSTEM UI @ Retention RetentionPolicy.SOURCE private interface ContextType ContextImpl.java 컨텍스트 생성 #4

Slide 157

Slide 157 text

TYPE WINDOW CONTEXT 157 @ Override public boolean isUiContext switch mContextType case CONTEXT TYPE ACTIVITY : case CONTEXT TYPE WINDOW CONTEXT : case CONTEXT TYPE SYSTEM OR SYSTEM UI : return true; case CONTEXT TYPE DISPLAY CONTEXT : case CONTEXT TYPE NON UI : return false; default: return false; ContextImpl.java 컨텍스트 생성 private boolean isAssociatedWithDisplay switch mContextType case CONTEXT TYPE DISPLAY CONTEXT : case CONTEXT TYPE ACTIVITY : case CONTEXT TYPE WINDOW CONTEXT : case CONTEXT TYPE SYSTEM OR SYSTEM UI : return true; default: return false; @ Override public IBinder getWindowContextToken switch mContextType case CONTEXT TYPE WINDOW CONTEXT : case CONTEXT TYPE SYSTEM OR SYSTEM UI : return mToken; default: return null; #4

Slide 158

Slide 158 text

TYPE WINDOW CONTEXT 158 ContextImpl.java 컨텍스트 생성 @ Override public boolean isUiContext switch mContextType case CONTEXT TYPE ACTIVITY : case CONTEXT TYPE WINDOW CONTEXT : case CONTEXT TYPE SYSTEM OR SYSTEM UI : return true; case CONTEXT TYPE DISPLAY CONTEXT : case CONTEXT TYPE NON UI : return false; default: return false; private boolean isAssociatedWithDisplay switch mContextType case CONTEXT TYPE DISPLAY CONTEXT : case CONTEXT TYPE ACTIVITY : case CONTEXT TYPE WINDOW CONTEXT : case CONTEXT TYPE SYSTEM OR SYSTEM UI : return true; default: return false; @ Override public IBinder getWindowContextToken switch mContextType case CONTEXT TYPE WINDOW CONTEXT : case CONTEXT TYPE SYSTEM OR SYSTEM UI : return mToken; default: return null; #4

Slide 159

Slide 159 text

TYPE WINDOW CONTEXT 159 ContextImpl.java 컨텍스트 생성 @ Override public boolean isUiContext switch mContextType case CONTEXT TYPE ACTIVITY : case CONTEXT TYPE WINDOW CONTEXT : case CONTEXT TYPE SYSTEM OR SYSTEM UI : return true; case CONTEXT TYPE DISPLAY CONTEXT : case CONTEXT TYPE NON UI : return false; default: return false; private boolean isAssociatedWithDisplay switch mContextType case CONTEXT TYPE DISPLAY CONTEXT : case CONTEXT TYPE ACTIVITY : case CONTEXT TYPE WINDOW CONTEXT : case CONTEXT TYPE SYSTEM OR SYSTEM UI : return true; default: return false; @ Override public IBinder getWindowContextToken switch mContextType case CONTEXT TYPE WINDOW CONTEXT : case CONTEXT TYPE SYSTEM OR SYSTEM UI : return mToken; default: return null; #4

Slide 160

Slide 160 text

TYPE WINDOW CONTEXT 160 @ UiContext ContextImpl createWindowContextBase @ NonNull IBinder token, int displayId ContextImpl baseContext new ContextImpl this, mMainThread, mPackageInfo, mParams, mAttributionSource.getAttributionTag , mAttributionSource.getNext , mSplitName, token, mUser, mFlags, mClassLoader, null ; baseContext.mForceDisplayOverrideInResources false; baseContext.mContextType = CONTEXT TYPE WINDOW CONTEXT; final Resources windowContextResources createWindowContextResources baseContext ; baseContext.setResources windowContextResources ; // Associate the display with window context resources so that configuration update from // the server side will also apply to the display s metrics. baseContext.mDisplay = ResourcesManager.getInstance .getAdjustedDisplay displayId, windowContextResources ; return baseContext; ContextImpl.java 컨텍스트 생성 #4

Slide 161

Slide 161 text

Context Type 161 /** * Indicates this link Context can not handle UI components properly and is not associated * with a link Display instance. */ private static final int CONTEXT TYPE NON UI = 0; /** * Indicates this link Context is associated with a link Display instance but should not * be handled UI components properly because it doesn t receive configuration changes * regardless of display property updates. */ private static final int CONTEXT TYPE DISPLAY CONTEXT = 1; /** * Indicates this link Context is an link Activity or link Activity derived * link Context . */ private static final int CONTEXT TYPE ACTIVITY = 2; /** * Indicates this link Context is a link WindowContext or link WindowContext derived * link Context . */ private static final int CONTEXT TYPE WINDOW CONTEXT = 3; // TODO b/170369943 : Remove after WindowContext migration /** * Indicates this link Context is created from link #createSystemContext ActivityThread * or link #createSystemUiContext ContextImpl, int or any link Context that system UI * uses. */ private static final int CONTEXT TYPE SYSTEM OR SYSTEM UI = 4; @ IntDef prefix CONTEXT TYPE , value CONTEXT TYPE NON UI, CONTEXT TYPE DISPLAY CONTEXT, CONTEXT TYPE ACTIVITY, CONTEXT TYPE WINDOW CONTEXT, CONTEXT TYPE SYSTEM OR SYSTEM UI @ Retention RetentionPolicy.SOURCE private interface ContextType ContextImpl.java 컨텍스트 생성 #4

Slide 162

Slide 162 text

TYPE SYSTEM OR SYSTEM UI 162 @ Override public boolean isUiContext switch mContextType case CONTEXT TYPE ACTIVITY : case CONTEXT TYPE WINDOW CONTEXT : case CONTEXT TYPE SYSTEM OR SYSTEM UI : return true; case CONTEXT TYPE DISPLAY CONTEXT : case CONTEXT TYPE NON UI : return false; ContextImpl.java 컨텍스트 생성 private boolean isAssociatedWithDisplay switch mContextType case CONTEXT TYPE DISPLAY CONTEXT : case CONTEXT TYPE ACTIVITY : case CONTEXT TYPE WINDOW CONTEXT : case CONTEXT TYPE SYSTEM OR SYSTEM UI : return true; default: return false; @ Override public IBinder getWindowContextToken switch mContextType case CONTEXT TYPE WINDOW CONTEXT : case CONTEXT TYPE SYSTEM OR SYSTEM UI : return mToken; default: return null; final void performFinalCleanup String who, String what //Log.i TAG, Cleanup up context: this ; mPackageInfo.removeContextRegistrations getOuterContext , who, what ; if mContextType = = CONTEXT TYPE SYSTEM OR SYSTEM UI mToken instanceof WindowTokenClient mMainThread.onSystemUiContextCleanup this ; #4

Slide 163

Slide 163 text

TYPE SYSTEM OR SYSTEM UI 163 ContextImpl.java 컨텍스트 생성 @ Override public boolean isUiContext switch mContextType case CONTEXT TYPE ACTIVITY : case CONTEXT TYPE WINDOW CONTEXT : case CONTEXT TYPE SYSTEM OR SYSTEM UI : return true; case CONTEXT TYPE DISPLAY CONTEXT : case CONTEXT TYPE NON UI : return false; private boolean isAssociatedWithDisplay switch mContextType case CONTEXT TYPE DISPLAY CONTEXT : case CONTEXT TYPE ACTIVITY : case CONTEXT TYPE WINDOW CONTEXT : case CONTEXT TYPE SYSTEM OR SYSTEM UI : return true; default: return false; @ Override public IBinder getWindowContextToken switch mContextType case CONTEXT TYPE WINDOW CONTEXT : case CONTEXT TYPE SYSTEM OR SYSTEM UI : return mToken; default: return null; final void performFinalCleanup String who, String what //Log.i TAG, Cleanup up context: this ; mPackageInfo.removeContextRegistrations getOuterContext , who, what ; if mContextType = = CONTEXT TYPE SYSTEM OR SYSTEM UI mToken instanceof WindowTokenClient mMainThread.onSystemUiContextCleanup this ; #4

Slide 164

Slide 164 text

TYPE SYSTEM OR SYSTEM UI 164 ContextImpl.java 컨텍스트 생성 @ Override public boolean isUiContext switch mContextType case CONTEXT TYPE ACTIVITY : case CONTEXT TYPE WINDOW CONTEXT : case CONTEXT TYPE SYSTEM OR SYSTEM UI : return true; case CONTEXT TYPE DISPLAY CONTEXT : case CONTEXT TYPE NON UI : return false; private boolean isAssociatedWithDisplay switch mContextType case CONTEXT TYPE DISPLAY CONTEXT : case CONTEXT TYPE ACTIVITY : case CONTEXT TYPE WINDOW CONTEXT : case CONTEXT TYPE SYSTEM OR SYSTEM UI : return true; default: return false; @ Override public IBinder getWindowContextToken switch mContextType case CONTEXT TYPE WINDOW CONTEXT : case CONTEXT TYPE SYSTEM OR SYSTEM UI : return mToken; default: return null; final void performFinalCleanup String who, String what //Log.i TAG, Cleanup up context: this ; mPackageInfo.removeContextRegistrations getOuterContext , who, what ; if mContextType = = CONTEXT TYPE SYSTEM OR SYSTEM UI mToken instanceof WindowTokenClient mMainThread.onSystemUiContextCleanup this ; #4

Slide 165

Slide 165 text

TYPE SYSTEM OR SYSTEM UI 165 ContextImpl.java 컨텍스트 생성 @ Override public boolean isUiContext switch mContextType case CONTEXT TYPE ACTIVITY : case CONTEXT TYPE WINDOW CONTEXT : case CONTEXT TYPE SYSTEM OR SYSTEM UI : return true; case CONTEXT TYPE DISPLAY CONTEXT : case CONTEXT TYPE NON UI : return false; private boolean isAssociatedWithDisplay switch mContextType case CONTEXT TYPE DISPLAY CONTEXT : case CONTEXT TYPE ACTIVITY : case CONTEXT TYPE WINDOW CONTEXT : case CONTEXT TYPE SYSTEM OR SYSTEM UI : return true; default: return false; @ Override public IBinder getWindowContextToken switch mContextType case CONTEXT TYPE WINDOW CONTEXT : case CONTEXT TYPE SYSTEM OR SYSTEM UI : return mToken; default: return null; final void performFinalCleanup String who, String what //Log.i TAG, Cleanup up context: this ; mPackageInfo.removeContextRegistrations getOuterContext , who, what ; if mContextType = = CONTEXT TYPE SYSTEM OR SYSTEM UI mToken instanceof WindowTokenClient mMainThread.onSystemUiContextCleanup this ; #4

Slide 166

Slide 166 text

TYPE SYSTEM OR SYSTEM UI 166 @ UnsupportedAppUsage static ContextImpl createSystemContext ActivityThread mainThread LoadedApk packageInfo new LoadedApk mainThread ; ContextImpl context new ContextImpl null, mainThread, packageInfo, ContextParams.EMPTY, null, null, null, null, null, 0, null, null ; context.setResources packageInfo.getResources ; context.mResources.updateConfiguration context.mResourcesManager.getConfiguration , context.mResourcesManager.getDisplayMetrics ; context.mContextType = CONTEXT TYPE SYSTEM OR SYSTEM UI; return context; 
 static ContextImpl createSystemUiContext ContextImpl systemContext, int displayId final WindowTokenClient token new WindowTokenClient ; final ContextImpl context systemContext.createWindowContextBase token, displayId ; token.attachContext context ; token.attachToDisplayContent displayId ; context.mContextType = CONTEXT TYPE SYSTEM OR SYSTEM UI; context.mOwnsToken true; return context; ContextImpl.java 컨텍스트 생성 #4

Slide 167

Slide 167 text

@ Override public Context createDisplayContext Display display // … context.mDisplay display; context.mContextType mContextType = = CONTEXT TYPE SYSTEM OR SYSTEM UI ? CONTEXT TYPE SYSTEM OR SYSTEM UI : CONTEXT TYPE DISPLAY CONTEXT; // … return context; TYPE SYSTEM OR SYSTEM UI 167 static ContextImpl createAppContext ActivityThread mainThread, LoadedApk packageInfo, String opPackageName // … context.setResources packageInfo.getResources ; context.mContextType isSystemOrSystemUI context ? CONTEXT TYPE SYSTEM OR SYSTEM UI : CONTEXT TYPE NON UI; return context; ContextImpl.java 컨텍스트 생성 #4

Slide 168

Slide 168 text

ConfigurationChangeItem ActivityThread.java 살펴보기 168 /** * App configuration change message. * hide */ public class ConfigurationChangeItem extends ClientTransactionItem private Configuration mConfiguration; @ Override public void preExecute android.app.ClientTransactionHandler client, IBinder token client.updatePendingConfiguration mConfiguration ; @ Override public void execute ClientTransactionHandler client, IBinder token, PendingTransactionActions pendingActions client.handleConfigurationChanged mConfiguration ; // … #5

Slide 169

Slide 169 text

생명주기 알아보기 ActivityThread.java 살펴보기 169 public IntArray getLifecyclePath int start, int finish, boolean excludeLastState if start = = UNDEFINED finish = = UNDEFINED throw new IllegalArgumentException Can t resolve lifecycle path for undefined state ; if start = = ON RESTART finish = = ON RESTART throw new IllegalArgumentException Can t start or finish in intermittent RESTART state if finish = = PRE ON CREATE start ! = finish throw new IllegalArgumentException Can only start in pre onCreate state ; mLifecycleSequence.clear ; if finish start if start = = ON START finish = = ON STOP mLifecycleSequence.add ON STOP ; else for int i start + 1; i finish; i mLifecycleSequence.add i ; else // finish start, can t just cycle down if start = = ON PAUSE finish = = ON RESUME // Special case when we can just directly go to resumed state. mLifecycleSequence.add ON RESUME ; else if start < = ON STOP finish > = ON START // Restart and go to required state. Go to stopped state first. for int i start + 1; i < = ON STOP; i mLifecycleSequence.add i ; // Restart mLifecycleSequence.add ON RESTART ; // Go to required state for int i = ON START; i finish; i mLifecycleSequence.add i ; else // Relaunch and go to required state. Go to destroyed state first. for int i start + 1; i < = ON DESTROY; i mLifecycleSequence.add i ; // Go to required state for int i = ON CREATE; i finish; i mLifecycleSequence.add i ; // Remove last transition in case we want to perform it with some specific params. if excludeLastState mLifecycleSequence.size ! = 0 mLifecycleSequence.remove mLifecycleSequence.size - 1 ; 
 return mLifecycleSequence; 다양한 케이스 #6

Slide 170

Slide 170 text

Context 란 Context.java 살펴보기 170 Context는 아래 기능을 수행하는 추상 클래스 입니다. 1. 어플리케이션에 관하여 시스템이 관리하고 있는 정보 접근 2. 안드로이드 시스템이 제공하는 시스템 api를 호출 제공 Interface to global information about an application environment. This is an abstract class whose implementation is provided by the Android system. It allows access to application specific resources and classes, as well as up calls for application level operations such as launching activities, broadcasting and receiving intents, etc.

Slide 171

Slide 171 text

우리가 알고 있는 컨텍스트 소스코드로 알아보는 안드로이드 Context 171 어플리케이션 상태 리소스 접근 ActivityContext와 ApplicationContext 잘못된 사용은 메모리 릭 유발

Slide 172

Slide 172 text

Caution 소스코드로 알아보는 안드로이드 Context 172 AOSP 소스 코드 JAVA 많은 양의 소스 코드 WHAT, HOW에 초점

Slide 173

Slide 173 text

소스 코드 Context의 서브 클래스 173

Slide 174

Slide 174 text

ContextImpl ContextImpl.java 컨텍스트 생성 174 Context를 직접 상속한 클래스

Slide 175

Slide 175 text

outerContext basePackageName packageInfo opPackageName mainThread params attributeSource splitName ContextImpl 175 token user flag classLoader resourceManager contentResolver 멤버변수 ContextImpl.java 컨텍스트 생성

Slide 176

Slide 176 text

/** * This manages the execution of the main thread in an * application process, scheduling and executing activities, * broadcasts, and other operations on it as the activity * manager requests. * * hide */ public final class ActivityThread extends ClientTransactionHandler implements ActivityThreadInternal /** hide */ public static final String TAG = ActivityThread ; private static final android.graphics.Bitmap.Config THUMBNAIL FORMAT = Bitmap.Config.RGB 565; static final boolean localLOGV = false; static final boolean DEBUG MESSAGES = false; /** hide */ public static final boolean DEBUG BROADCAST = false; private static final boolean DEBUG RESULTS = false; private static final boolean DEBUG BACKUP = false; public static final boolean DEBUG CONFIGURATION = false; private static final boolean DEBUG SERVICE = false; public static final boolean DEBUG MEMORY TRIM = false; private static final boolean DEBUG PROVIDER = false; public static final boolean DEBUG ORDER = false; private static final long MIN TIME BETWEEN GCS = 5 * 1000; ActivityThreadInternal ActivityThread.java 살펴보기 176 /** * ActivityThread internal interface. * It is a subset of ActivityThread and used for communicating with * link ConfigurationController . */ interface ActivityThreadInternal ContextImpl getSystemContext ; ContextImpl getSystemUiContextNoCreate ; boolean isInDensityCompatMode ; Application getApplication ; ArrayList ComponentCallbacks2 > collectComponentCallbacks boolean includeUiContexts ;

Slide 177

Slide 177 text

ClientTransactionItem ActivityThread.java 살펴보기 177 Activity 없어도 동작 Activity 관련 생명 주기 관련

Slide 178

Slide 178 text

Main 함수 ActivityThread.java 살펴보기 178 public static void main String args Trace.traceBegin Trace.TRACE TAG ACTIVITY MANAGER, ActivityThreadMain ; AndroidOs.install ; CloseGuard.setEnabled false ; Environment.initForCurrentUser ; // … Looper.prepareMainLooper ; // … long startSeq = 0; // … ActivityThread thread new ActivityThread ; thread.attach false, startSeq ; if sMainThreadHandler null sMainThreadHandler thread.getHandler ; // … Looper.loop ; throw new RuntimeException Main thread loop unexpectedly exited ;

Slide 179

Slide 179 text

Main 함수 ActivityThread.java 살펴보기 179 public static void main String args Trace.traceBegin Trace.TRACE TAG ACTIVITY MANAGER, ActivityThreadMain ; AndroidOs.install ; CloseGuard.setEnabled false ; Environment.initForCurrentUser ; // … Looper.prepareMainLooper ; // … long startSeq = 0; // … ActivityThread thread new ActivityThread ; thread.attach false, startSeq ; if sMainThreadHandler null sMainThreadHandler thread.getHandler ; // … Looper.loop ; throw new RuntimeException Main thread loop unexpectedly exited ; Main Looper를 준비

Slide 180

Slide 180 text

Main 함수 ActivityThread.java 살펴보기 180 public static void main String args Trace.traceBegin Trace.TRACE TAG ACTIVITY MANAGER, ActivityThreadMain ; AndroidOs.install ; CloseGuard.setEnabled false ; Environment.initForCurrentUser ; // … Looper.prepareMainLooper ; // … long startSeq = 0; // … 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

Slide 181

Slide 181 text

Main 함수 ActivityThread.java 살펴보기 181 public static void main String args Trace.traceBegin Trace.TRACE TAG ACTIVITY MANAGER, ActivityThreadMain ; AndroidOs.install ; CloseGuard.setEnabled false ; Environment.initForCurrentUser ; // … Looper.prepareMainLooper ; // … long startSeq = 0; // … ActivityThread thread new ActivityThread ; thread.attach false, startSeq ; if sMainThreadHandler null sMainThreadHandler thread.getHandler ; // … Looper.loop ; throw new RuntimeException Main thread loop unexpectedly exited ; loop를 통해서 무한 반복을 하면서 UI 메세지를 처리

Slide 182

Slide 182 text

Main 함수 ActivityThread.java 살펴보기 182 public static void main String args Trace.traceBegin Trace.TRACE TAG ACTIVITY MANAGER, ActivityThreadMain ; AndroidOs.install ; CloseGuard.setEnabled false ; Environment.initForCurrentUser ; // … Looper.prepareMainLooper ; // … long startSeq = 0; // … ActivityThread thread new ActivityThread ; thread.attach false, startSeq ; if sMainThreadHandler null sMainThreadHandler thread.getHandler ; // … Looper.loop ; throw new RuntimeException Main thread loop unexpectedly exited ; Main Looper를 준비

Slide 183

Slide 183 text

Main 함수 ActivityThread.java 살펴보기 183 public static void main String args Trace.traceBegin Trace.TRACE TAG ACTIVITY MANAGER, ActivityThreadMain ; AndroidOs.install ; CloseGuard.setEnabled false ; Environment.initForCurrentUser ; // … Looper.prepareMainLooper ; // … long startSeq = 0; // … 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

Slide 184

Slide 184 text

Main 함수 ActivityThread.java 살펴보기 184 public static void main String args Trace.traceBegin Trace.TRACE TAG ACTIVITY MANAGER, ActivityThreadMain ; AndroidOs.install ; CloseGuard.setEnabled false ; Environment.initForCurrentUser ; // … Looper.prepareMainLooper ; // … long startSeq = 0; // … ActivityThread thread new ActivityThread ; thread.attach false, startSeq ; if sMainThreadHandler null sMainThreadHandler thread.getHandler ; // … Looper.loop ; throw new RuntimeException Main thread loop unexpectedly exited ; loop를 통해서 무한 반복을 하면서 UI 메세지를 처리

Slide 185

Slide 185 text

Main 함수 ActivityThread.java 살펴보기 185 public static void main String args Trace.traceBegin Trace.TRACE TAG ACTIVITY MANAGER, ActivityThreadMain ; AndroidOs.install ; CloseGuard.setEnabled false ; Environment.initForCurrentUser ; // … Looper.prepareMainLooper ; // … long startSeq = 0; // … ActivityThread thread new ActivityThread ; thread.attach false, startSeq ; if sMainThreadHandler null sMainThreadHandler thread.getHandler ; // … Looper.loop ; throw new RuntimeException Main thread loop unexpectedly exited ; Main Looper를 준비

Slide 186

Slide 186 text

Main 함수 ActivityThread.java 살펴보기 186 public static void main String args Trace.traceBegin Trace.TRACE TAG ACTIVITY MANAGER, ActivityThreadMain ; AndroidOs.install ; CloseGuard.setEnabled false ; Environment.initForCurrentUser ; // … Looper.prepareMainLooper ; // … long startSeq = 0; // … 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

Slide 187

Slide 187 text

Main 함수 ActivityThread.java 살펴보기 187 public static void main String args Trace.traceBegin Trace.TRACE TAG ACTIVITY MANAGER, ActivityThreadMain ; AndroidOs.install ; CloseGuard.setEnabled false ; Environment.initForCurrentUser ; // … Looper.prepareMainLooper ; // … long startSeq = 0; // … ActivityThread thread new ActivityThread ; thread.attach false, startSeq ; if sMainThreadHandler null sMainThreadHandler thread.getHandler ; // … Looper.loop ; throw new RuntimeException Main thread loop unexpectedly exited ; loop를 통해서 무한 반복을 하면서 UI 메세지를 처리

Slide 188

Slide 188 text

ActivityManagerService 생성 까지 ActivityThread.java 살펴보기 188 frameworks/base/core/java/com/android/internal/os/ZygoteInit.java frameworks/base/services/java/com/android/server/SystemServer.java public static void main String args new SystemServer .run ; private void run TimingsTraceAndSlog t new TimingsTraceAndSlog ; // … // Create the system service manager. mSystemServiceManager new SystemServiceManager mSystemContext ; mSystemServiceManager.setStartInfo mRuntimeRestart, mRuntimeStartElapsedTime, mRuntimeStartUptime ; mDumper.addDumpable mSystemServiceManager ; // … try t.traceBegin StartServices ; startBootstrapServices t ; startCoreServices t ; startOtherServices t ; startApexServices t ; catch Throwable ex Slog.e System , ****************************************** ; Slog.e System , ************ Failure starting system services , ex ; throw ex; finally t.traceEnd ; // StartServices ???? #1

Slide 189

Slide 189 text

ActivityManagerService 생성 까지 ActivityThread.java 살펴보기 189 frameworks/base/services/java/com/android/server/SystemServer.java private void startBootstrapServices @ NonNull TimingsTraceAndSlog t t.traceBegin startBootstrapServices ; // … // Activity manager runs the show. t.traceBegin StartActivityManager ; // TODO : Might need to move after migration to WM. ActivityTaskManagerService atm mSystemServiceManager.startService ActivityTaskManagerService.Lifecycle.class .getService ; mActivityManagerService = ActivityManagerService.Lifecycle.startService mSystemServiceManager, atm ; mActivityManagerService.setSystemServiceManager mSystemServiceManager ; mActivityManagerService.setInstaller installer ; mWindowManagerGlobalLock atm.getGlobalLock ; t.traceEnd ; #1

Slide 190

Slide 190 text

ActivityThread::performLaunchActivity onCreate 호출 시점 애플리케이션//액티비티 190 private Activity performLaunchActivity ActivityClientRecord r, Intent customIntent ActivityInfo aInfo r.activityInfo; // … ContextImpl appContext createBaseContextForActivity r ; Activity activity null; // … activity mInstrumentation.newActivity cl, component.getClassName , r.intent ; // … try // … if activity ! = null // … appContext.setOuterContext activity ; activity.attach appContext, this, /* … */ ; // … int theme r.activityInfo.getThemeResource ; if theme ! = 0 activity.setTheme theme ; // … mInstrumentation.callActivityOnCreate activity, r.state, r.persistentState ; // … r.setState ON CREATE ; // … return activity;

Slide 191

Slide 191 text

Instrumentation::callActivityOnCreate onCreate 호출 시점 애플리케이션//액티비티 191 public class Instrumentation public void callActivityOnCreate Activity activity, Bundle icicle, PersistableBundle persistentState prePerformCreate activity ; activity.performCreate icicle, persistentState ; postPerformCreate activity ; final void performCreate Bundle icicle performCreate icicle, null ; final void performCreate Bundle icicle, PersistableBundle persistentState // … dispatchActivityPreCreated icicle ; // … if persistentState ! = null onCreate icicle, persistentState ; else onCreate icicle ; Activity::performCreate

Slide 192

Slide 192 text

Instrumentation::callActivityOnCreate onCreate 호출 시점 애플리케이션//액티비티 192 public class Instrumentation public void callActivityOnCreate Activity activity, Bundle icicle, PersistableBundle persistentState prePerformCreate activity ; activity.performCreate icicle, persistentState ; postPerformCreate activity ; final void performCreate Bundle icicle performCreate icicle, null ; final void performCreate Bundle icicle, PersistableBundle persistentState // … dispatchActivityPreCreated icicle ; // … if persistentState ! = null onCreate icicle, persistentState ; else onCreate icicle ; Activity::performCreate