Android TextView 프 리 렌 더 링 연구
TextView 렌 더 링 기본 원리
먼저 TextView 의 기본 렌 더 링 원 리 를 소개 합 니 다.전체적으로 보면 TextView 에서 렌 더 링 문 자 를 담당 하 는 것 은 주로 이 세 가지 유형 입 니 다.
BoringLayout
주로 한 줄 의 텍스트 를 표시 하고 isBoring 방법 을 제공 하여 한 줄 의 텍스트 조건 을 만족 시 키 는 지 판단 합 니 다.
DynamicLayout
텍스트 가 Spannable 일 때 TextView 는 텍스트 디 스 플레이 를 담당 하기 위해 이 를 사용 하고,내부 에 SpanWatcher 를 설정 하 며,span 변경 사항 이 감지 되면 reflow 를 해서 레이아웃 을 다시 계산 합 니 다.
StaticLayout
텍스트 가 한 줄 이 아 닌 텍스트 이 고 Spannable 이 아 닐 때 StaticLayout 를 사용 합 니 다.내부 에 span 의 변 화 를 감청 하지 않 기 때문에 효율 적 으로 DynamicLayout 보다 높 습 니 다.레이아웃 을 한 번 만 만 들 면 됩 니 다.그러나 내부 에 도 SpannableString 이 표 시 됩 니 다.span 이 변 한 후에 레이아웃 을 다시 할 수 없 을 뿐 입 니 다.
또한 상기 세 가지 유형 은 모두 Layout 류 에 계승 되 어 있 습 니 다.이러한 과정 에서 텍스트 의 구체 적 인 그립 니 다.Layout.draw 방법 에서 텍스트 한 줄 한 줄 을 렌 더 링 합 니 다.
TextLine tl = TextLine.obtain();
// Draw the lines, one at a time.
// The baseline is the top of the following line minus the current line's descent.
for (int i = firstLine; i <= lastLine; i++) {
....
Directions directions = getLineDirections(i);
if (directions == DIRS_ALL_LEFT_TO_RIGHT && !mSpannedText && !hasTabOrEmoji) {
// XXX: assumes there's nothing additional to be done
canvas.drawText(buf, start, end, x, lbaseline, paint);
} else {
tl.set(paint, buf, start, end, dir, directions, hasTabOrEmoji, tabStops);
tl.draw(canvas, x, ltop, lbaseline, lbottom);
}
}
TextLine.recycle(tl);
Spannble 이나 emoji 가 포 함 된 텍스트 를 알 수 있다 면 실제 렌 더 링 작업 은 TextLine 에 맡 겨 그립 니 다.그렇지 않 으 면 canvas.drawText 를 직접 사용 합 니 다.TextLine 은 한 줄 의 복잡 한 텍스트 를 그립 니 다.그 중에서 Spannable,Emoji 와 같은 그리 기 논 리 는 모두 포함 되 어 있 고 TextLine 의 그리 기 논리 도 효율 적 이지 않 습 니 다.여기 서 후속 적 으로 그것 이 어떻게 최적화 되 어야 하 는 지 계속 설명 할 것 이다.TextLayoutCache
Canvas 는 drawText 를 사용 할 때 글꼴 의 크기,여백 등 을 매번 계산 해 야 할 경우 시간 이 많이 걸 려 drawText 시간 이 길 어 집 니 다.효율 성 을 높이 기 위해 안 드 로 이 드 는 4.0 이후 TextLayoutCache 를 도 입 했 고 LRU Cache 를 사용 하여 글꼴,여백 등 데 이 터 를 캐 시 하여 drawText 의 속 도 를 높 였 습 니 다.4.4 에서 이 cache 의 크기 는 0.5M 입 니 다.전역 적 으로 사용 되 며,Activity 의 configurationChanged,onResume,lowMemory,updateVisibility 등 시기 에 Canvas.freeTextLayoutCache 를 호출 하여 이 메모 리 를 방출 합 니 다.이 부분의 cache 는 시스템 의 하부 통제 이기 때문에 우 리 는 구체 적 인 통 제 를 할 수 없다.
TextView 의 프 리 렌 더 링 최적화
TextView 의 렌 더 링 원 리 를 보면 단순히 텍스트 를 표시 하 는 것 이 라면 SpanWatcher 를 따로 설정 하여 span 의 변 화 를 감청 할 필요 가 없습니다.따라서 저 희 는 BoringLayout 나 StaticLayout 를 직접 사용 하여 텍스트 내용 을 직접 표시 할 수 있 습 니 다.그러나 BoringLayout 는 한 줄 의 텍스트 만 표시 할 수 있 기 때문에 여기 서 가장 좋 은 선택 은 StaticLayout 을 직접 사용 하 는 것 입 니 다.
사용자 정의 View 를 선 택 했 습 니 다.마지막 으로 이러한 인터페이스 가 있 기 를 바 랍 니 다.
public class StaticLayoutView extends View {
private Layout layout = null;
public void setLayout(Layout layout) {
this.layout = layout;
requestLayout();
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.save();
if (layout != null) {
layout.draw(canvas, null, null, 0);
}
canvas.restore();
}
}
이 view 의 Layout 를 설정 하여 텍스트 를 직접 그 릴 수 있 으 며,onDraw 방법 에서 이 Layout 대상 을 직접 사용 하여 텍스트 를 그 릴 수 있 습 니 다.여기 서 우 리 는 setText 방법 을 버 리 고 Layout 를 통 해 텍스트 를 직접 그립 니 다.여기 있 는 Layout 대상 은 미리 만 든 후에 설정 할 수 있 습 니 다.(여 기 는 하나의 스 레 드 에 넣 어서 만 들 수 있 습 니 다)일반 TextView 의 setText 방법 보다 setText 의 많은 소 모 를 줄 이 고 효율 을 크게 향상 시 킬 수 있 습 니 다.Static Layout 의 생 성 은 매우 간단 합 니 다.주어진 텍스트,너비 등 만 있 으 면 바로 만 들 수 있 습 니 다.또한,TextLayoutCache 를 미리 채 우기 위해 서 는 StaticLayout 대상 을 만 든 후에 미리 Dummy canvas 에서 draw 할 수 있 습 니 다.
StaticLayout layout = new StaticLayout(TestSpan.getSpanString(i), textPaint, hardCodeWidth, alignment, 1.0f, 0f, true);
layout.draw(dummyCanvas);
성능 대비
다음은 구체 적 인 성능 을 테스트 해 보 겠 습 니 다.여기 testcase 는 Github 에 올 렸 습 니 다StaticLayoutView
testcase 의 내용 은 하나의 ListView 에 300 개의 Item 을 표시 합 니 다.각 item 은 순수한 텍스트 입 니 다.그 안에 대량의 ImageSpan 이 포 함 된 SpannableString 이 포함 되 어 있 습 니 다.양쪽 을 비교 하면 StaticLayout 를 직접 사용 하고 일반 TextView 를 사용 합 니 다.또한 이 300 개의 텍스트 는 모두 같 지 않 고 길이 가 다 르 며 무 작위 로 생 성 됩 니 다.StaticLayout 의 testcase 에서...Static Layout 는 다른 스 레 드 가 만들어 진 후에 미리 설정 되 어 있 으 며,또한 SpannableString 도 미리 생 성 되 어 있 습 니 다.
또한 실제 app 의 힘 든 배경 작업 을 모 의 하기 위해 3 개의 스 레 드 를 만 들 었 고 CPU 자원 을 선점 하기 위해 부동 소수점 예산 을 계속 만 들 었 습 니 다.
성능 을 측정 하 는 지 표 는 ListView 가 연속 적 으로 아래로 굴 러 가 고 평균 프레임 율 이 얼마 인지 측정 하 며 각각 다섯 번 측정 하여 평균 치 를 계산 하 며 최종 성능 테스트 결 과 는 다음 과 같다.
여기 서 테스트 하 는 기 계 는 MX3 이 고 왼쪽 은 Static Layout 를 직접 사용 하 는 방안 이 며 오른쪽 은 시스템 의 기본 방안 이 며 Y 축 은 FPS 로 최적화 된 방안 을 사용 하여 프레임 율 이 많이 향상 되 었 음 을 알 수 있다.
References
Improving Comment Rendering on Android
이 글 은 인 스타 그램 이 TextView 렌 더 링 의 효율 을 어떻게 최적화 하 는 지 를 소개 했다.이것 도 이곳 의 최적화 방법의 원천 이다.인 스타 그램 도 Static Layout 를 직접 사용 하고 Layout 를 미리 만 드 는 방법 으로 ListView 스크롤 과정 에서 프레임 이 떨 어 지 는 확률 을 줄 이 고 효과 가 매우 현저 하 다.이 글 은 이곳 의 원리 해석 과 간단 한 실현 을 제시 한 셈 이다.
이상 은 Android TextView 에 미리 보 여 준 자 료 를 정리 하고 관련 자 료 를 계속 보충 하 는 것 입 니 다.본 사이트 에 대한 지원 에 감 사 드 립 니 다!
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Bitrise에서 배포 어플리케이션 설정 테스트하기이 글은 Bitrise 광고 달력의 23일째 글입니다. 자체 또는 당사 등에서 Bitrise 구축 서비스를 사용합니다. 그나저나 며칠 전 Bitrise User Group Meetup #3에서 아래 슬라이드를 발표했...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.