Android/안드로이드 프로그래밍 Next Step
[Next Step] 4. Context 클래스
Diane_KIM
2023. 8. 25. 22:52
Context의 하위클래스는 Activity, Service, Application (BroadcastReceiver와 ContentProvider는 Context를 상속X)
- Activity, Service, Application 은 ActivityThread에서 컴포넌트가 시작된다
- 이때 각 컴포넌트의 attach() 메서드에서 attachBaseContect()를 호출
- 컴포넌트 별로 생성한 ContextImpl 를 하나씩 래핑하고 있고, getBaseContext()는 ContextImpl 인스턴스를 리턴 (싱글톤X)
- getApplication()는 Application 인스턴스를 리턴하는 것으로 단 한개만 존재
ContextImpl 메서드
- 헬퍼 메서드 : 앱 패키지 정보를 제공하거나 내/외부 파일, SharedPreferences, 데이터베이스 등을 사용
- 퍼미션 메서드 : Activity, BR, Service 같은 컴포넌트를 시작하는 메서드와 퍼미션 체크해줌. 이 메서드는 system_server 프로세스의 ActivityManagerService 의 메서드를 다시 호출
- 시스템 서비스 접근 메서드
- 시스템 서비스에 접근하기 위한 getSystemService() 메서드
- ContextImpl의 정적 초기화 블록에서 클래스가 최초 로딩될 때 시스템 서비스를 매핑하고, getSystemService()에서 사용
- ex) getSystemService(Context.ALARM_SERVICE)
사용 가능한 Context 3개
- Activity 인스턴스 자신(this)
- getBaseContext()를 통해 가져오는 ContextImpl 인스턴스
- getApplicationContext()를 통해 가져오는 Application 인스턴스
1. setContentView()에게 레이아웃의 리소스 ID 를 넘겨준다
2. inflate() 를 수행하여 XML 마크업 코드를 View 객체로 만드는 동작을 수행
=> View - inflate() 메소드가 해당작업 진행
/**
* Inflate a view from an XML resource. This convenience method wraps the {@link
* LayoutInflater} class, which provides a full range of options for view inflation.
*
* @param context The Context object for your activity or application.
* @param resource The resource ID to inflate
* @param root A view group that will be the parent. Used to properly inflate the
* layout_* parameters.
* @see LayoutInflater
*/
public static View inflate(Context context, @LayoutRes int resource, ViewGroup root) {
LayoutInflater factory = LayoutInflater.from(context);
return factory.inflate(resource, root);
}
// LayoutInflater.java - from method
/**
* Obtains the LayoutInflater from the given context.
*/
public static LayoutInflater from(Context context) {
LayoutInflater LayoutInflater =
(LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
if (LayoutInflater == null) {
throw new AssertionError("LayoutInflater not found.");
}
return LayoutInflater;
}
결과적으로 setContentView() => View - inflate() => LayoutInflater - from() 내부에서는 다음과 같은 일을 함.
val inflater : LayoutInflater = getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater
val view = inflater.inflate(R.layout.activity_home, linearLayout, true)
좀 더 줄여보면
val view = LayoutInflater.from(this).inflate(R.layout.activity_home, linearLayout, false)
=> View는 Activity 인스턴스가 전달됨
View에 Context가 전달되는 루트
- Activity에 setContentView() 내부에서 사용되는 LayoutInflater에 Activity인스턴스가 전달됨
- View생성자의 Context파라미터에 Activity 인스턴스가 전달됨