Collectives™ on Stack Overflow
Find centralized, trusted content and collaborate around the technologies you use most.
Learn more about Collectives
Teams
Q&A for work
Connect and share knowledge within a single location that is structured and easy to search.
Learn more about Teams
I have been working on developing application. While building my application I'm getting onLayout time too long ANR warning on logcat. So my question is what exactly could be the problem?
ANR Warning]onLayout time too long, this =android.widget.FrameLayout{b7ebc83 V.E...... ......ID 0,0-720,1200 #7f0b005f app:id/content}time =651 ms
D/View: [ANR Warning]onLayout time too long, this =android.widget.LinearLayout{2b85e00 V.E...... ......ID 0,0-720,1200}time =652 ms
D/View: [ANR Warning]onLayout time too long, this =android.widget.FrameLayout{9243639 V.E...... ......ID 0,96-720,1296 #7f0b0065 app:id/view_content}time =652 ms
D/View: [ANR Warning]onLayout time too long, this =android.widget.LinearLayout{606a47e V.E...... ......ID 0,0-720,1296}time =654 ms
D/View: [ANR Warning]onLayout time too long, this =android.support.v7.widget.ContentFrameLayout{e669ddf V.E...... ......ID 0,0-720,1296 #1020002 android:id/content}time =654 ms
D/View: [ANR Warning]onLayout time too long, this =android.support.v7.widget.FitWindowsLinearLayout{f455a2c V.E...... ......ID 0,0-720,1296 #7f0b004b app:id/action_bar_root}time =655 ms
D/View: [ANR Warning]onLayout time too long, this =android.widget.FrameLayout{c08fcf5 V.E...... ......ID 0,48-720,1344}time =655 ms
D/View: [ANR Warning]onLayout time too long, this =android.widget.LinearLayout{7648a8a V.E...... ......ID 0,0-720,1344}time =656 ms
D/View: [ANR Warning]onLayout time too long, this =DecorView@23d1963[MainActivity]time =656 ms
Here are my application layout file which encounters above problem
fragment_video_browser.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/fragment_video"
android:layout_width="match_parent"
android:layout_height="fill_parent"
android:orientation="vertical">
<android.support.v7.widget.RecyclerView
android:id="@+id/recycler_view1_video"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scrollbars="vertical" />
<!--/>-->
<!--android:background="@color/novided_bg"-->
</LinearLayout>
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/content"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"/>
activity_title_base.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="@dimen/toolbar_height"
android:background="?attr/colorPrimary"
android:fitsSystemWindows="true"
app:contentInsetEnd="0dp"
app:contentInsetStart="0dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="@dimen/toolbar_height"
android:gravity="center_vertical"
android:orientation="horizontal">
<ImageView
android:id="@+id/back"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/toolbar_backmenu_margin_start"
android:background="?android:attr/actionBarItemBackground"
android:clickable="true"
android:src="@mipmap/back"
android:visibility="invisible" />
<TextView
android:id="@+id/title_text"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:lines="1"
android:textColor="@color/toolbar_title_color"
android:textDirection="locale"
android:textSize="@dimen/toolbar_title_size" />
<ImageView
android:id="@+id/menu"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_marginEnd="@dimen/toolbar_menu_marginend"
android:background="?android:attr/actionBarItemBackground"
android:clickable="true"
android:paddingEnd="@dimen/toolbar_menu_padding"
android:paddingStart="@dimen/toolbar_menu_padding"
android:src="@drawable/ic_more"
android:visibility="gone"/>
<ImageView
android:id="@+id/edit"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_marginEnd="@dimen/toolbar_menu_marginend"
android:background="?android:attr/actionBarItemBackground"
android:clickable="true"
android:paddingEnd="@dimen/toolbar_menu_padding"
android:paddingStart="@dimen/toolbar_menu_padding"
android:src="@drawable/ic_btn_edit"
android:visibility="gone" />
<TextView
android:id="@+id/all_select"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="@dimen/toolbar_selectall_margin_end"
android:background="?android:attr/selectableItemBackgroundBorderless"
android:textColor="@color/toolbar_selectall_color"
android:textDirection="locale"
android:textSize="@dimen/toolbar_selectall_textsize"
android:visibility="gone" />
</LinearLayout>
</android.support.v7.widget.Toolbar>
<FrameLayout
android:id="@+id/view_content"
android:layout_width="fill_parent"
android:layout_height="0dp"
android:layout_weight="1"/>
</LinearLayout>
fragment.java
public class VideoBrowserFragment extends BaseFragment implements LoaderManager.LoaderCallbacks<Cursor>,
VideoBrowserAdapter.OnRecyclerViewItemClickListener,
VideoBrowserAdapter.OnItemLongClickListener,
EditionMode.OnEditionModeListener {
public final static String TAG = "Video/VideoBrowserFragment";
private int defaultSort = MediaInfoComparator.SORT_BY_NAME;
protected VideoBrowserAdapter mAdapter;
private VideoBrowserData videoMedia;
private View view;
private String bucketID;
private String bucketName;
private UiHanlder uiHanlder = new UiHanlder();
private class UiHanlder extends Handler {
@Override
public void handleMessage(final Message msg) {
((BaseActivity) getActivity()).onBackPressed();
@Override
public boolean onBackPressed() {
if (editionMode != null) {
if (editionMode.inEdionModle) {
editionMode.leaveEdition();
if (videoMedia != null && videoMedia.videoArrayList.size() == 0) {
return false;
} else {
return true;
} else {
this.onDestroy();
return false;
@Override
public boolean inEditModel() {
if (editionMode == null) {
return false;
if (editionMode.inEdionModle) {
if (editionMode.selectionManager.getCheckedItemsCount() == mAdapter.getItemCount()) {
editionMode.allNotSelect();
} else {
editionMode.allSelect((ArrayList<VideoInfoBean>) videoMedia.videoArrayList.clone());
} else {
editionMode.inEdition();
return false;
@Override
public boolean sortByType(int type) {
if (videoMedia == null) {
return false;
sortData(type);
defaultSort = type;
return false;
private void sortData(int type) {
Collections.sort(videoMedia.videoArrayList, MediaInfoComparator.getInstance(type));
mAdapter.setData(videoMedia.videoArrayList);
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Bundle bundle = getArguments();
if (bundle != null) {
bucketID = bundle.getString(FileBrowserFragment.BUCKETID);
bucketName = bundle.getString(FileBrowserFragment.BUCKETNAME);
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
Log.d("MY_LOG", "vdo FRAGMENT started");
super.onCreateView(inflater, container, savedInstanceState);
view = inflater.inflate(R.layout.fragment_video_browser, container, false);
init();
Log.d("MY_LOG", "vdo FRAGMENT ended");
return view;
private void init() {
((BaseActivity) getActivity()).setTitleText(bucketName);
((BaseActivity) getActivity()).setBackVisible();
((BaseActivity) getActivity()).setAllSelectVisible(View.GONE);
((BaseActivity) getActivity()).setEditVisible(View.GONE);
((BaseActivity) getActivity()).setMenuVisible(View.VISIBLE);
RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(this.getContext());
layoutManager.setAutoMeasureEnabled(false);
mRecyclerView = (RecyclerView) view.findViewById(R.id.recycler_view1_video);
mRecyclerView.setHasFixedSize(true);
mRecyclerView.setItemViewCacheSize(20);
mRecyclerView.setDrawingCacheEnabled(true);
mRecyclerView.setDrawingCacheBackgroundColor(View.DRAWING_CACHE_QUALITY_HIGH);
mRecyclerView.setLayoutManager(layoutManager);
mAdapter = new VideoBrowserAdapter(this.getContext());
mAdapter.mThumbnailCache = new ThumbnailCache(getContext());
mRecyclerView.setAdapter(mAdapter);
// mRecyclerView.addItemDecoration(new DividerItemDecoration(getContext(), DividerItemDecoration.VERTICAL_LIST));
// mRecyclerView.setItemAnimator(new DefaultItemAnimator());
mAdapter.setOnItemClickListener(this);
mAdapter.setOnItemClickLongListener(this);
getLoaderManager().initLoader(1, null, this);
editionMode = new EditionMode(this, (BaseVideoActivity) this.getActivity(), mAdapter, getContext(), view, R.id.fragment_video);
editionMode.setOnEditionModeListener(this);
mAdapter.mActionMode = editionMode;
mAdapter.mThumbnailCache.addListener(mAdapter);
@Override
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
videoMedia = new VideoBrowserData(this.getContext());
return videoMedia.getCursorLoader(bucketID);
@Override
public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
if (videoMedia == null) {
videoMedia = new VideoBrowserData(this.getContext());
if (data != null && videoMedia != null) {
videoMedia.queryAllVideo(data);
setPlayInfo();
sortData(defaultSort);
if (editionMode.inEdionModle) {
editionMode.refreshCheckedItem((ArrayList<VideoInfoBean>) videoMedia.videoArrayList.clone());
editionMode.updateAllSize();
if (videoMedia.videoArrayList.size() == 0) {
uiHanlder.sendEmptyMessage(0);
@Override
public void onLoaderReset(Loader<Cursor> loader) {
@Override
public void onResume() {
super.onResume();
if (videoMedia == null) {
getLoaderManager().restartLoader(0, null, this);
return;
setPlayInfo();
mAdapter.notifyDataSetChanged();
@Override
public void onDestroy() {
Log.d("onDestroy", "onDestroy");
if (mAdapter != null) {
mAdapter.clearCachedHolder();
if (mAdapter.mThumbnailCache != null) {
mAdapter.mThumbnailCache.clear();
mAdapter.mThumbnailCache = null;
getLoaderManager().destroyLoader(1);
super.onDestroy();
@Override
public void onItemClick(View view, RecyclerView.ViewHolder data) {
Log.i(TAG, "onItemClick video : inEdionModle:" + editionMode.inEdionModle);
final Object obj = view.getTag();
int index = 0;
if (obj == null || !(obj instanceof RecyclerView.ViewHolder)) {
return;
if (editionMode.inEdionModle) {
editionMode.select((VideoBrowserAdapter.VideoViewHolder) obj);
} else {
for (int i = 0; i < videoMedia.videoArrayList.size(); i++) {
if (((BaseAdapter.VideoViewHolder) data).mId == videoMedia.videoArrayList.get(i).mediaID) {
index = i;
break;
VideoActivity.startPlayVideoList(getActivity(), index, videoMedia.videoArrayList);
@Override
public void onItemLongClick(View view, RecyclerView.ViewHolder data) {
final Object obj = view.getTag();
if (obj == null || !(obj instanceof RecyclerView.ViewHolder)) {
return;
editionMode.inEditionSelect((VideoBrowserAdapter.VideoViewHolder) obj);
public void setPlayInfo() {
for (int i = 0; i < videoMedia.videoArrayList.size(); i++) {
VideoInfoBean videoInfoBean = videoMedia.videoArrayList.get(i);
float index = VideoActivity.getLastPlayedVidePosition(videoInfoBean.mediaPath);
if (index == 0.0) {
videoInfoBean.playIndex = null;
} else {
videoInfoBean.playIndex = Utils.getIndex(index);
if (VideoActivity.getLastPlayedVideo() != null) {
if (VideoActivity.getLastPlayedVideo().equals(String.valueOf(videoInfoBean.mediaPath))) {
videoInfoBean.isLastPlay = true;
} else {
videoInfoBean.isLastPlay = false;
@Override
public int getAllSize() {
return videoMedia.videoArrayList.size();
Edit: On decreasing layout height of recycler view to 300dp I'm not getting warning.
–
–
–
From your layouts, all seems well except fill_parent in LinearLayout of fragment_video_browser.
That's the source of all your problems, fill_parent, now replaced by match_parent has this description in android docs;
FILL_PARENT (renamed MATCH_PARENT in API Level 8 and higher), which means that the view wants to be as big as its parent (minus padding)
When you have your linear layout expanding it's height continuously, and it's child which is recyclerView having match_parent as it's height property, the race to reach maximum available height never reaches the end until all the items in a recyclerView have been prepared - although not displayed.
At this level, the point of having a recyclerView becomes pointless because it's main feature is to recycle items as the user scrolls, but when it prepares all the items at once, it just remains as a static view that takes some time to be prepared.
From your edit,
On decreasing layout height of recycler view to 300dp I'm not getting warning.
It clearly illustrates that, if you limit the height to that value, the recyclerView adapter just prepares items enough to be displayed within that viewport, which is quick, then when the you scroll, more items are prepared based on the direction of scrolling.
A quick fix would be to eliminate the chase for maximum available height and use wrap_content in the recycler.
Other causes includes nesting a recyclerView inside a NestedScrollView, and anything else that has expandable/scrollable view without paying attention to the height param that has been provided for the recyclerView.
Here's an example from the docs on how the recyclerView can be harnessed for it's power.
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="@dimen/list_item_height"
android:layout_marginLeft="@dimen/margin_medium"
android:layout_marginRight="@dimen/margin_medium"
android:gravity="center_vertical">
<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/element_text"/>
This ANR issue won't be experienced with few items, but as the list grows, say towards 100 items or more, you will start to experience this.
A simple test to determine if this has been fixed after adjusting your layout parameters is to log the items being bound in your onBindViewHolder, inside that override, have something like:
Log.d("TAG", "Binding item at position $position")
If all is well, the function will print out in bits as you scroll, but if it prints all the items at once, then you haven't fixed your issue - assuming all your items cannot be shown in one screen and needs to be scrolled for more.
Read more on the docs.
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.