17. “Well, that’s: user input, networking, data
processing, database/disk I/O, view inflation,
layout, drawing,… Thwre also other
applications, cpus are slow, memories are too,
everything takes forever. And then you are
supposed to save battery.”
25. ViewHolder
Best practice from ListView
Lightweight view wrapper for list items
Recycler holds a limited amount of them and reuses them
One ViewHolder is used for more items (not at a time)
It has it’s own lifecyle
26. ViewHolder Lifecycle
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {}
@Override
public void onBindViewHolder(ViewHolder holder, int position) {}
@Override
public void onViewAttachedToWindow(ViewHolder holder) {}
@Override
public void onViewDetachedFromWindow(ViewHolder holder) {}
@Override
public void onViewRecycled(ViewHolder holder) {}
@Override
public boolean onFailedToRecycleView(ViewHolder holder) {}
27. ViewHolder Lifecycle
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {}
@Override
public void onBindViewHolder(ViewHolder holder, int position) {}
@Override
public void onViewAttachedToWindow(ViewHolder holder) {}
@Override
public void onViewDetachedFromWindow(ViewHolder holder) {}
@Override
public void onViewRecycled(ViewHolder holder) {}
@Override
public boolean onFailedToRecycleView(ViewHolder holder) {}
29. What not to do?
Disk I/O - SQLite, SharedPreferences, Content Providers
for (Comment comment : item.getComments()) {}
Parsing of text, JSONu,…, complicated formatting,..
Html.fromHtml()
Complicated layouts 🙂
“I can go home, it’s runs smooth on my phone.”
Critical code can be hidden (deep) in the abstraction
30. What to do?
Everything expensive has to run in background
…,or it has to be preprocessed
You don’t have to show it right away → use tmp placeholders
void onScrollStateChanged(…, int newState)
mHandler.postDelayed(deferredBind, DELAY }
☝ it’s crucial to keep this balanced
Test on various devices (low-end, tablets)
…and with various data
StrictMode
33. Guess what’s wrong?
//ViewHolder code called in onBindViewHolder()
@Override
public void bindData(Object data, final int position) {
mImageView.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
mClickHandler.onItemClicked(v, position, photo);
}
});
}
34. Guess what’s wrong?
//ViewHolder code called in onBindViewHolder()
@Override
public void bindData(Object data, final int position) {
mImageView.setOnClickListener(mClickListener); // use member var instead
}
35. Guess what’s wrong?
//ViewHolder code called in onBindViewHolder()
@Override
public void bindData(Object data, final int position, ItemClickListener listener) {
mImageView.setOnClickListener(listener); // even better..
}
36. Guess what’s wrong?
//ViewHolder code called in onBindViewHolder()
@Override
public void bindData(Object data, final int position) {
mImageView.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
mClickHandler.onItemClicked(v, position, photo);
}
});
}
37. Guess what’s wrong?
//ViewHolder code called in onBindViewHolder()
@Override
public void bindData(Object data, final int position) {
mImageView.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
mClickHandler.onItemClicked(v, getAdapterPosition(), photo);
}
});
}
40. AsyncTask
Runs tasks in serial → super slow
Hm…
executeOnExecutor(THREAD_POOL_EXECUTOR);
Big operational overhead
Tricky and unreliable task cancelling
56. Prefetch
Create and bind “up front”
Estimates how long it will run to make sure it won’t cause delays
Lollipop+ (RenderThread), support lib 25.1
setItemPrefetchEnabled(true)
Supported by built-in LayoutManageres (API for custom ones)
Watch out for onBindViewHolder - no animations,…
setInitialPrefetchItemCount(N)
You can see the difference with your naked eye 👀