AsyncLayoutInflater "비동기 로드 레이아웃" 구현
AsyncLayoutInflater
은 비동기 적 으로 레이아웃 을 초기 화 하 는 Helper
클래스 입 니 다.그것 의 본질은 레이아웃 파일
inflate
을 하위 스 레 드 에 넣 고 초기 화 에 성공 한 후에 인 터 페 이 스 를 통 해 메 인 스 레 드 로 던 지 는 것 이다.Activity
에서 간단 한 코드 는 다음 과 같 습 니 다. // xml, Activity.onCreate(xxx)
AsyncLayoutInflater(this).inflate(R.layout.activity_try_everything, null, object : AsyncLayoutInflater.OnInflateFinishedListener {
override fun onInflateFinished(view: View, p1: Int, p2: ViewGroup?) {
setContentView(view)
}
})
일반적으로 우 리 는
setContentView(R.layout.xxx)
의 형식 으로 로드 xml
한다.사실은 세 가지 서로 다른 방법 매개 변수
setContentView()
함수 가 있 는데 다음 과 같다. public void setContentView(@LayoutRes int layoutResID) {
this.getDelegate().setContentView(layoutResID);
}
public void setContentView(View view) {
this.getDelegate().setContentView(view);
}
public void setContentView(View view, LayoutParams params) {
this.getDelegate().setContentView(view, params);
}
우 리 는
inflate
을 통 해 나 와 layoutResID
대응 하 는 view
을 한 다음 에 호출 setContentView(View view)
을 통 해 이렇게 전달 할 수 있다.그렇다면
AsyncLayoutInflater
어떻게 일 했 을 까?다음 내용 은 다음 과 같은 부분 으로 나 뉜 다.AsyncLayoutInflater
의 간단 한 소개 와 창설 request
AsyncLayoutInflater.inflate(xxx)
에서 보 낸 메 시 지 를 처리 하고 결 과 를 Handler
스 레 드 Message
의 간단 한 소개 와 창설1.1
UI
에 대한 간단 한 소개AsyncLayoutInflater
의 실현 은 주로 세 개의 구성원 변수 와 하나의 내부 유형 이 있다.AsyncLayoutInflater
포석 AsyncLayoutInflater
LayoutInflater
메 인 스 레 드 까지 post inflate
는 하나의 Handler
이 고 하나의 스 레 드 로 안에서 완성 InflateThread
과정 Thread
정적 내부 류 는 필요 한 정 보 를 담 는 데 사용 된다 inflate
외부 에 누 출 된 인 터 페 이 스 를 외부 에 알 리 는 데 사용 하고 초기 화 InflateRequest
완료 OnInflateFinishedListener
의 생 성View
의 생 성 은 코드 에서 볼 수 있 습 니 다.public AsyncLayoutInflater(@NonNull Context context) {
// AsyncLayoutInflater , inflater, handler, thread
mInflater = new BasicInflater(context);
mHandler = new Handler(mHandlerCallback);
mInflateThread = InflateThread.getInstance();
}
그 중에서 코드 분석 은 다음 과 같다.
AsyncLayoutInflater
는 후속 용 AsyncLayoutInflater
구조 mInflater
는 하나의 사례 대상 으로 획득 할 때 이 inflate
은 이미 작업 을 시작 했다 mInflateThread
코드 는 다음 과 같다. private static final InflateThread sInstance;
// ,
static {
sInstance = new InflateThread();
//
sInstance.start();
}
thread
는 start
에서 보 낸 메 시 지 를 받 고 mHandler
스 레 드 thread
로 돌아 가 메 시 지 를 보 내 는 위치 입 니 다. Message.obtain(request.inflater.mHandler, 0, request).sendToTarget()
그리고 주요 정보 인 '즉 UI
' 을 Message
에 넣 습 니 다. request
위의 준 비 를 마 친 후, 이때 Message
안 에는 실행 할 요청 이 없 으 며, 그 대열 에 object
이 있 으 면 대응 하 는 논 리 를 집행 할 것 이다.2. 레이아웃 초기 화 요청 추가
mInflateThread
이 방법 을 호출 할 때 일련의 절차 가 있 습 니 다.request
요청;request
하위 스 레 드 에 넣 기 @UiThread
public void inflate(@LayoutRes int resid, @Nullable ViewGroup parent,
@NonNull OnInflateFinishedListener callback) {
if (callback == null) {
throw new NullPointerException("callback argument may not be null!");
}
InflateRequest request = mInflateThread.obtainRequest();
request.inflater = this;
request.resid = resid;
request.parent = parent;
request.callback = callback;
mInflateThread.enqueue(request);
}
코드 에서 볼 수 있 듯 이 호출
AsyncLayoutInflater.inflate(xxx)
방법 마다 InflateRequest
을 새로 만 들 고 이 mInflateThread.enqueue(request)
을 mInflateThread
대기 열 에 추가 합 니 다.2.1 창설
inflate(xxx)
요청InflateRequest
에 요청 을 저장 하기 위 한 대기 열 request
이 있 습 니 다.private ArrayBlockingQueue mQueue = new ArrayBlockingQueue<>(10);
mInflateThread
스 레 드 는 InflateRequest
이후 호출 InflateThread
을 시도 하여 mQueue
를 가 져 온 다음 에 대응 하 는 논 리 를 집행 합 니 다.@Override
public void run() {
while (true) {
runInner();
}
}
주: 여 기 는 결코 사순환 이 아 닙 니 다. 왜냐하면
InflateRequest
방법 때 문 입 니 다.InflateThread
는 차단 이 발생 하 는 대열 로 start()
방법 에서 runInner()
하면 계속 빠 져 든다 inflateRequest
.mQueue.take()
의 ArrayBlockingQueue
방법 소스 코드:public E take() throws InterruptedException {
final ReentrantLock lock = this.lock;
lock.lockInterruptibly();
try {
// ,
while (count == 0)
notEmpty.await();
return dequeue();
} finally {
lock.unlock();
}
}
2.2
take()
을 통 해 요청 을 추가 한 후 count == 0
비어 있 지 않 음이
notEmpty.await()
에서 ArrayBlockingQueue
를 얻 을 수 있 습 니 다. take()
를 통 해 하위 스 레 드 mInflateThread.enqueue(request)
구축 을 완료 하고 mQueue
를 통 해 해당 하 는 mQueue
에 게 메 시 지 를 보 냅 니 다.코드 는 다음 과 같 습 니 다:public void runInner() {
InflateRequest request;
try {
//
request = mQueue.take();
} catch (InterruptedException ex) {
// Odd, just continue
Log.w(TAG, ex);
return;
}
//
try {
request.view = request.inflater.mInflater.inflate(
request.resid, request.parent, false);
} catch (RuntimeException ex) {
// Probably a Looper failure, retry on the UI thread
Log.w(TAG, "Failed to inflate resource in the background! Retrying on the UI" + " thread", ex);
}
Message.obtain(request.inflater.mHandler, 0, request).sendToTarget();
}
3.
request
에서 보 낸 메 시 지 를 처리 하고 결 과 를 inflater.inflate(xxx)
스 레 드 에 되 돌려 줍 니 다.view
을 통 해 메 시 지 를 보 낸 후에 진정 으로 메 시 지 를 받 는 곳 은 Message
의 handler
방법 안에 있 습 니 다. 이때 이미 Handler
스 레 드 로 잘 랐 습 니 다.@Override
public boolean handleMessage(Message msg) {
InflateRequest request = (InflateRequest) msg.obj;
if (request.view == null) {
request.view = mInflater.inflate(request.resid, request.parent, false);
}
request.callback.onInflateFinished(request.view, request.resid, request.parent);
mInflateThread.releaseRequest(request);
return true;
}
코드 논리:
Message
에서 UI
Message
여부 Handler
handleMessage(xxx)
합 니 다. 이 때 는 UI
스 레 드 에서 진행 되 며 일반적인 초기 화 와 같 습 니 다.msg.obj
를 통 해 외부 에 알 리 고 받 은 것 InflateRequest
을 전달 합 니 다 request.view
에서 실 패 를 방지 하고 판단 을 했 습 니 다.대외 폭 루 의 인터페이스:
null
가장 간단 한 inflate
과 마찬가지 로 인 터 페 이 스 를 통 해 일 을 외부 호출 자 에 게 던 지 는 것 과 비슷 하 다.4. 소결
상기 부분 에서 간단하게
UI
의 내부 실현 을 소개 했다.마음속 에 약간의 의문 이 생 길 수 있 습 니 다. 이것 은 쉽게 말 하면
OnInflateFinishedListener
새로운 서브 스 레 드 를 만 든 다음 view
좋 은 inflate
을 다시 AsyncLayoutInflater.OnInflateFinishedListener
스 레 드 에 넣 으 면 큰 도움 이 되 지 않 습 니까?확실히
View.OnClickListener
쉽게 말 하면 상술 한 표현 을 실현 한 것 이다.그리고 단점 도 많 습 니 다. 공식 문 서 는 명확 하 게 쓰 여 있 습 니 다.
This inflater does not support setting a LayoutInflater.Factory nor LayoutInflater.Factory2. Similarly it does not support inflating layouts that contain fragments.
한계 가 있다. 이것 도 우리 가 일반적으로 이런 방식 을 사용 하지 않 는 큰 원인 이다.
그런데?하나의
AsyncLayoutInflater
가 비동기 new
를 지원 할 수 있다 면 inflate
할 수 있 습 니까?하위 스 레 드 에서 미리 배치 할 수 있 습 니까?그리고 이런 것들
view
이 진정 으로 필요 할 때 레이아웃 을 불 러 오 는 시간 을 절약 할 수 있 습 니까?물론 입 니 다. 구체 적 으로 어떻게 실현 되 는 지 는 다음 에 다시 정리 해 야 합 니 다.
이번 에는 간단 한 소개
UI
일 뿐이다.추 후 정리 가 잘 되 기 를 기대한다.
AsyncLayoutInflater
글 은 공중 번호 에서 왔 다. XML
inflate
후속 회 의 는 이어서 정리 지식 을 정리 할 것 이다.참고:
PreInflate
inflate
view
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
다양한 언어의 JSONJSON은 Javascript 표기법을 사용하여 데이터 구조를 레이아웃하는 데이터 형식입니다. 그러나 Javascript가 코드에서 이러한 구조를 나타낼 수 있는 유일한 언어는 아닙니다. 저는 일반적으로 '객체'{}...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.