Android Recycleer View 스크롤 성능
리스트 및 카드 작성 가이드에 따라 RecycleerView의 예를 작성했습니다.어댑터는 레이아웃을 부풀리기 위한 패턴 실장만을 갖추고 있습니다.
스크롤 퍼포먼스의 저하에 문제가 있다.이것은 8개의 항목만 있는 RecycleView에서 확인할 수 있습니다.
일부 테스트에서 Android L에서는 이 문제가 발생하지 않음을 확인했습니다.그러나 KitKat 버전에서는 성능 저하가 뚜렷합니다.
최근에 같은 문제에 직면했기 때문에 최신 RecycleerView 지원 라이브러리를 사용하여 다음과 같은 작업을 수행했습니다.
복잡한 레이아웃(내포된 뷰, RelativeLayout)을 최적화된 새로운 ConstraintLayout으로 바꿉니다.Android Studio에서 활성화:SDK Manager -> SDK Tools 탭 -> Support Repository -> Constraint Layout for Android 및 Solver for Constraint Layout 순으로 선택합니다.종속성에 추가:
compile 'com.android.support.constraint:constraint-layout:1.0.2'
가능하면 RecycleerView의 모든 요소를 동일한 높이로 만듭니다.추가:
recyclerView.setHasFixedSize(true);
기본 RecycerView 도면 캐시 방법을 사용하여 상황에 따라 조정합니다.서드파티 라이브러리는 필요 없습니다.
recyclerView.setItemViewCacheSize(20); recyclerView.setDrawingCacheEnabled(true); recyclerView.setDrawingCacheQuality(View.DRAWING_CACHE_QUALITY_HIGH);
많은 이미지를 사용하는 경우 크기와 압축이 최적의지 확인하십시오.영상의 배율이 퍼포먼스에 영향을 줄 수도 있습니다.이 문제에는 사용된 소스 이미지와 디코딩된 비트맵의 두 가지 측면이 있습니다.다음으로 웹에서 다운로드한n개의 이미지를 디코딩하는 예를 나타냅니다.
InputStream is = (InputStream) url.getContent(); BitmapFactory.Options options = new BitmapFactory.Options(); options.inPreferredConfig = Bitmap.Config.RGB_565; Bitmap image = BitmapFactory.decodeStream(is, null, options);
입니다.inPreferredConfig
- 이미지의 각 픽셀에 사용되는 바이트 수를 정의합니다.이것은 권장되는 옵션입니다.소스 이미지의 색상이 많아도 다른 설정으로 디코딩됩니다.
onBindView 확인Holder()는 가능한 한 저렴합니다.OnClickListener는 다음 중 한 번 설정할 수 있습니다.
onCreateViewHolder()
인터페이스를 통해 어댑터 외부의 청취자를 호출하여 클릭된 항목을 전달합니다.이렇게 하면 항상 추가 개체를 만들 필요가 없습니다.또한 여기서 보기를 변경하기 전에 플래그와 상태를 확인하십시오.viewHolder.itemView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { Item item = getItem(getAdapterPosition()); outsideClickListener.onItemClicked(item); } });
데이터가 변경되면 해당 항목만 업데이트하십시오.예를 들어 전체 데이터 세트를 무효화하는 대신
notifyDataSetChanged()
과 같이 사용합니다 , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , .adapter.notifyItemRangeInserted(rangeStart, rangeEnd); adapter.notifyItemRemoved(position); adapter.notifyItemChanged(position); adapter.notifyItemInserted(position);
Android 개발자 웹 사이트:
마지막 수단으로 notifyDataSetChanged()를 사용합니다.
그러나 사용해야 하는 경우 고유한 ID로 항목을 유지 관리하십시오.
adapter.setHasStableIds(true);
RecycleerView는 이 메서드를 사용할 때 안정적인 ID를 가지고 있다고 보고하는 어댑터에 대해 가시적인 구조 변경 이벤트를 통합하려고 합니다.이렇게 하면 애니메이션 및 시각적 객체의 지속성을 위해 도움이 되지만 개별 항목 보기는 여전히 리바운드하고 다시 표시해야 합니다.
모든 것을 올바르게 실행해도 RecycleerView가 원하는 만큼 원활하게 작동하지 않을 수 있습니다.
다음 플래그를 추가하여 이 문제를 해결했습니다.
당신의 퍼포먼스를 망칠 수 있는 패턴을 하나라도 발견했어요.하세요.onBindViewHolder()
자주 전화해요.따라서 이 코드로 수행하는 모든 작업은 성능을 중단시킬 수 있습니다.RecycleerView에서 커스터마이즈할 경우 이 메서드에 실수로 느린 코드가 삽입되기 쉽습니다.
위치에 따라 각 RecycleerView의 배경 이미지를 변경하고 있었습니다.그러나 이미지 로딩에는 약간의 작업이 필요하기 때문에 RecycleerView가 느려지고 흔들립니다.
은 놀라운 효과가 .onBindViewHolder()
이제 캐시된 이미지에 대한 참조를 처음부터 로드하지 않고 변경합니다.「RecyclerView」 「RecycleerView」 「RecycleerView」.
모든 사람이 이 문제를 가지고 있는 것은 아니라는 것을 알고 있기 때문에 굳이 코드를 로드할 필요가 없습니다.단, 고객님의 고객님의 고객님의 고객님의onBindViewHolder()
RecycleerView 。
@Galya의 자세한 답변 외에 최적화 문제일 수도 있지만 디버거를 활성화하면 속도가 많이 느려지는 것도 사실입니다.
하기 위해 노력하겠습니다.RecyclerView
되지 를 '빌드 베리에이션'으로 전환해 . ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★release
비개발 환경(디버거가 비활성화되어 있는 경우)에서의 동작을 확인합니다.
갑자기 내 앱이 느린 속도로 동작하고 있었다.debug
바리안트입니다만, 「」로 ,release
바리안트 그것은 부드럽게 작동했다.아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아,release
하지만 앱을 발송할 준비가 되면 언제든지 정상적으로 작동한다는 것을 알아두면 좋습니다.
RecyclerView
퍼포먼스여기 영어로 된 슬라이드와 러시아어로 된 녹화된 비디오가 있습니다.
일련의 테크닉이 포함되어 있습니다(일부 테크닉은 이미 @Darya의 답변에 포함되어 있습니다).
다음은 간단한 요약입니다.
if
Adapter
항목의 크기가 고정된 후 설정됩니다.
recyclerView.setHasFixedSize(true);
를 long긴')으로 수 .
hashCode()
예를 들면, 다음과 같이 설정합니다.
adapter.hasStableIds(true);
및 구현:
// YourAdapter.java
@Override
public long getItemId(int position) {
return items.get(position).hashcode(); //id()
}
이 경우Item.id()
동작하지 않을 것입니다.설령 그 일이 일어나도 그대로이기 때문입니다.Item
내용이 변경되었습니다.
추신: DiffUtil을 사용하는 경우에는 필요하지 않습니다!올바른 크기의 비트맵을 사용합니다.시간을 낭비하지 말고 도서관을 이용하세요.
선택 방법에 대한 자세한 내용은 여기를 참조하십시오.항상 최신 버전 사용
RecyclerView
예를 들어, 에서는 퍼포먼스가 크게 향상되었습니다.25.1.0
(프리페치).
자세한 것은 이쪽.DiffUtill을 사용합니다.
DiffUtil은 필수입니다.
공식 문서아이템 레이아웃을 심플하게!
TextView를 풍부하게 하는 작은 라이브러리 - TextViewRichDrawable
자세한 내용은 슬라이드를 참조하십시오.
의 용도는 잘 모르겠습니다.setHasStableId
플래그를 사용하면 문제가 해결됩니다.사용자가 제공한 정보에 따라 성능 문제가 메모리 문제와 관련이 있을 수 있습니다.사용자 인터페이스와 메모리 측면에서 애플리케이션 성능은 매우 관련이 있습니다.
지난 주에 나는 내 앱에서 메모리 누수를 발견했어.앱을 사용한 지 20분이 지나자 UI의 동작이 매우 느리다는 것을 알게 되었습니다.액티비티를 닫거나 열거나 여러 요소가 있는 RecycleerView를 스크롤하는 것은 매우 느렸습니다.http://flowup.io/을 사용하여 실제 가동 중인 일부 사용자를 모니터링한 결과 다음과 같은 사실을 발견했습니다.
프레임 시간은 정말 길고 초당 프레임 수는 정말 낮았습니다.일부 프레임은 :S를 렌더링하는 데 약 2초가 걸린 것을 알 수 있습니다.
이 불량 프레임 시간/fps의 원인을 파악하려고 했는데, 여기 보시는 것처럼 메모리 문제가 있었습니다.
평균 메모리 소비량이 15MB에 가까웠을 때에도 앱은 프레임을 떨어뜨렸습니다.
그렇게 UI의 문제를 발견하게 되었습니다.내 앱에서 메모리 누수가 발생하여 많은 가비지 컬렉터 이벤트가 발생했는데, Android VM이 내 앱을 중지하고 모든 프레임에 메모리를 수집해야 했기 때문에 UI 성능이 저하되었습니다.
코드를 보니 Android 안무가 인스턴스에서 청취자를 등록 해제하지 않았기 때문에 커스텀 뷰에서 누수가 발생했습니다.수정 릴리스 후 모든 것이 정상적으로 되었습니다. : )
메모리 문제로 인해 앱에서 프레임이 손실되는 경우 다음 두 가지 일반적인 오류를 검토해야 합니다.
애플리케이션이 초당 여러 번 호출되는 메서드 내에서 개체를 할당하는지 검토합니다.애플리케이션이 느려지는 다른 장소에서 이 할당을 수행할 수 있는 경우에도 마찬가지입니다.예를 들어 onBindView의 onDraw 커스텀 뷰 메서드 내에 객체의 새 인스턴스를 생성하는 경우가 있습니다.리사이클러 뷰 홀더의 홀더.앱이 인스턴스를 Android SDK에 등록하지만 릴리스하지 않는지 검토합니다.버스 이벤트에 청취자를 등록하는 것도 누출 가능성이 있습니다.
면책사항:앱을 감시하기 위해 사용하고 있는 툴이 개발 중입니다.저는 개발자 중 한 명이기 때문에 이 툴에 액세스 할 수 있습니다. :) 이 툴에 액세스 하고 싶다면 베타 버전을 곧 출시합니다.저희 웹사이트 http://flowup.io/에 가입하실 수 있습니다.
Travelview, dmtracedump, 시스템 트레이스 또는 Android Studio에 통합된 Andorid 성능 모니터 등 다양한 도구를 사용할 수 있습니다.그러나 이 도구는 연결된 장치를 모니터링하며 나머지 사용자 장치나 Android OS 설치는 모니터링하지 않습니다.
나는 이 코드로 그것을 해결했다.
recyclerView.setNestedScrollingEnabled(false);
또한 Recycerview에 넣을 상위 레이아웃을 확인하는 것도 중요합니다.nestedscroll View에서 recycleer View를 테스트할 때도 같은 스크롤 문제가 있었습니다.스크롤 중에 성능이 저하될 수 있는 다른 보기를 스크롤하는 보기
제 경우, 지연의 주요 원인은 내부에 드로잉 가능한 로딩이 자주 발생한다는 것을 알게 되었습니다.#onBindViewHolder()
방법.뷰 내에서 이미지를 비트맵으로 로드하는 것만으로 해결했습니다.상기 방법으로 홀더하여 접근합니다.그게 내가 한 전부야.
RecycleerView에서는 비트맵 이미지를 사용하여 item_layout의 배경을 만듭니다.
@Galya가 말한 것은 모두 진실이다(그리고 나는 그의 훌륭한 답변에 감사한다).하지만 그들은 나를 위해 일하지 않았다.
이것이 제 문제를 해결한 것입니다.
BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = 2;
Bitmap bitmap = BitmapFactory.decodeStream(stream, null, options);
내 경우엔 복잡한 재활용품을 가진 아이들이 있다.따라서 액티비티 로드 시간(액티비티 렌더링의 경우 약 5초)에 영향을 미칩니다.
post Delayed() -> 를 사용하여 어댑터를 로드하면 액티비티 렌더링에 좋은 결과를 얻을 수 있습니다.액티비티 후에 recycerview 로드가 부드럽게 됩니다.
이 답을 시도해 보세요.
recyclerView.postDelayed(new Runnable() {
@Override
public void run() {
recyclerView.setAdapter(mAdapter);
}
},100);
코멘트에는, 이미 실장하고 있는 것을 알 수 있습니다.ViewHolder
패턴입니다만, 여기에, 예를 들면, 이 어댑터를 사용해 주세요.RecyclerView.ViewHolder
패턴을 사용하면, 같은 방법으로 통합하고 있는 것을 확인할 수 있습니다.또한 컨스트럭터는 필요에 따라 다를 수 있습니다.다음은 예를 제시하겠습니다.
public class RecyclerAdapter extends RecyclerView.Adapter<RecyclerAdapter.ViewHolder> {
Context mContext;
List<String> mNames;
public RecyclerAdapter(Context context, List<String> names) {
mContext = context;
mNames = names;
}
@Override
public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {
View view = LayoutInflater.from(viewGroup.getContext())
.inflate(android.R.layout.simple_list_item_1, viewGroup, false);
return new ViewHolder(view);
}
@Override
public void onBindViewHolder(ViewHolder viewHolder, int position) {
//Populate.
if (mNames != null) {
String name = mNames.get(position);
viewHolder.name.setText(name);
}
}
@Override
public int getItemCount() {
if (mNames != null)
return mNames.size();
else
return 0;
}
/**
* Static Class that holds the RecyclerView views.
*/
static class ViewHolder extends RecyclerView.ViewHolder {
TextView name;
public ViewHolder(View itemView) {
super(itemView);
name = (TextView) itemView.findViewById(android.R.id.text1);
}
}
}
작업하는 데 문제가 있으면RecyclerView.ViewHolder
Gradle에서 항상 확인할 수 있는 적절한 의존관계가 있는지 확인하십시오.
이것으로 문제가 해결되기를 바랍니다.
이것에 의해, 보다 부드럽게 스크롤 할 수 있게 되었습니다.
어댑터의 onFailedToRecycleView(ViewHolder 홀더)를 덮어쓰다
진행 중인 애니메이션 홀더가 있으면 "animateview".clearAnimation()을 중지합니다.
잊지 말고 진실하게 돌아가라.
바인드 뷰에서 @Galya의 답변에 추가홀더, 저는 Html.fromHtml() 메서드를 사용하고 있었습니다.이것은 퍼포먼스에 영향을 주는 것 같습니다.
나는 피카소 도서관의 유일한 선을 사용하여 이 문제를 해결한다.
.fit()
Picasso.get().load(currentItem.getArtist_image())
.fit()//this wil auto get the size of image and reduce it
.placeholder(R.drawable.ic_doctor)
.into(holder.img_uploaderProfile, new Callback() {
@Override
public void onSuccess() {
}
@Override
public void onError(Exception e) {
Toast.makeText(context, "Something Happend Wrong Uploader Image", Toast.LENGTH_LONG).show();
}
});
언급URL : https://stackoverflow.com/questions/27188536/android-recyclerview-scrolling-performance
'sourcecode' 카테고리의 다른 글
텐서플로우의 tf.nn.max_pool의 'SAME' 패딩과 'VALID' 패딩의 차이점은 무엇입니까? (0) | 2022.10.27 |
---|---|
부모 페이지에서 iframe 내의 JavaScript 코드 호출 (0) | 2022.10.27 |
Java에서 URL 또는 URI를 구성하는 관용적인 방법은 무엇입니까? (0) | 2022.10.27 |
"pip install --user..."의 목적은 무엇입니까? (0) | 2022.10.27 |
PDO:: 날짜의 PARAM? (0) | 2022.10.27 |