从API 27迁移到29后,Android recyclerview的性能不佳 [英] Android recyclerview poor performance after API 27 to 29 Migration

查看:91
本文介绍了从API 27迁移到29后,Android recyclerview的性能不佳的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

已迁移的应用程序支持最新的API29.一切进展顺利,除了一个令人困惑的问题外,应用程序功能正常.使用SQLite查询填充了 recyclerview ,该查询可以检索500多个记录,并在如下所示的详细活动中显示结果.

在打开详细信息活动&的API 27上,此操作一直很好sql调用,活动代码和布局在5年内没有发生变化,几乎可以立即填充.但是,在 API 29 版本上,使用相同的代码,该应用需要 3+秒才能显示相同的数据

经过大量测试并阅读了慢速渲染,我想已将其固定在API 29中的 androidx.recyclerview:recyclerview:1.0.0 上,花费了更长的时间为活动UI构建输出,这可能是由于我的编码和/或布局结构不良所致./p>

这是由.java填充的我的 R.layout.msgh_detail

 <?xml version ="1.0" encoding ="utf-8"?>< androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android ="http://schemas.android.com/apk/res/android"xmlns:app ="http://schemas.android.com/apk/res-auto"android:id ="@ + id/main_content"android:layout_width ="match_parent"android:layout_height ="match_parent">< com.google.android.material.appbar.AppBarLayoutandroid:id ="@ + id/appbar"android:layout_width ="match_parent"android:layout_height ="wrap_content"android:theme ="@ style/ThemeOverlay.AppCompat.Dark.ActionBar">< androidx.appcompat.widget.Toolbarandroid:id ="@ + id/toolbar"android:layout_width ="match_parent"android:layout_height =?attr/actionBarSize"app:popupTheme ="@ style/ThemeOverlay.AppCompat.Light"app:layout_collapseMode ="pin"/></com.google.android.material.appbar.AppBarLayout>< androidx.core.widget.NestedScrollViewandroid:layout_width ="match_parent"android:layout_height ="wrap_content"android:layout_marginBottom ="75dp"app:layout_behavior ="@ string/appbar_scrolling_view_behavior">< LinearLayoutandroid:layout_width ="match_parent"android:layout_height ="match_parent"android:gravity ="center_vertical"android:orientation ="vertical"><包括android:layout_width ="match_parent"android:layout_height ="match_parent"layout ="@ layout/msgh_detail_list"/></LinearLayout></androidx.core.widget.NestedScrollView>< androidx.cardview.widget.CardViewandroid:layout_width ="match_parent"android:layout_height ="wrap_content"android:id ="@ + id/replyCard"android:layout_marginBottom ="2dp"android:layout_marginLeft ="@ dimen/card_margin"android:layout_marginRight ="@ dimen/card_margin"android:layout_gravity ="bottom"android:layout_alignParentBottom ="true"android:touchscreenBlocksFocus ="false">< LinearLayoutstyle ="@ style/Widget.CardContent"android:layout_width ="match_parent"android:layout_height ="wrap_content">< EditTextandroid:layout_width ="match_parent"android:layout_height ="wrap_content"android:inputType ="textMultiLine | textCapSentences"android:maxLength ="250"android:ems ="10"android:imeOptions ="actionDone"android:id ="@ + id/msg_reply"android:hint ="@ string/msg_reply_hint"/></LinearLayout></androidx.cardview.widget.CardView>< com.google.android.material.floatingactionbutton.FloatingActionButtonandroid:id ="@ + id/fab3"android:layout_width ="wrap_content"android:layout_height ="wrap_content"app:layout_anchor ="@ id/replyCard"app:layout_anchorGravity ="top | right | end"android:layout_margin ="8dp"android:src ="@ drawable/ic_send_white_24dp"/></androidx.coordinatorlayout.widget.CoordinatorLayout> 

这是通过.java ViewHolder

包含的 R.layout.msgh_detail_list_item

 <?xml version ="1.0" encoding ="utf-8"?>< LinearLayout xmlns:android ="http://schemas.android.com/apk/res/android"android:layout_width ="match_parent"android:layout_height ="wrap_content"xmlns:app ="http://schemas.android.com/apk/res-auto"android:paddingTop ="4dp"android:paddingBottom ="4dp"android:layout_marginLeft ="8dp"android:layout_marginRight ="8dp"android:gravity ="center_vertical"android:orientation ="vertical">< LinearLayoutandroid:layout_width ="match_parent"android:layout_height ="24dp"android:orientation ="horizo​​ntal">< TextViewandroid:layout_width ="match_parent"android:layout_height ="wrap_content"android:layout_marginLeft ="8dp"android:layout_weight ="0.97"android:id ="@ + id/DayMMdd"android:ellipsize ="end"android:maxLines ="1"android:hint ="@ string/day_mth_dte"/>< TextViewandroid:layout_width ="wrap_content"android:layout_height ="wrap_content"android:id ="@ + id/arrivaltime"android:layout_marginLeft ="8dp"android:hint ="@ string/Hour_min"/>< ImageViewandroid:layout_width ="24dp"android:layout_height ="24dp"android:id ="@ + id/avatar"android:src ="@ drawable/status_1"android:layout_marginLeft ="8dp"android:layout_marginRight ="8dp"android:longClickable ="false"/></LinearLayout>< androidx.cardview.widget.CardViewandroid:id ="@ + id/detail_cardview"android:layout_width ="match_parent"android:layout_height ="wrap_content"app:cardBackgroundColor =#ccecf9">< LinearLayoutstyle ="@ style/Widget.CardContent"android:layout_width ="match_parent"android:layout_height ="wrap_content">< TextViewandroid:id ="@ + id/text2"android:layout_width ="match_parent"android:layout_height ="wrap_content"android:textAppearance =?attr/textAppearanceListItem"android:autoLink ="web"android:textColorLink =#009933"android:layout_weight ="0.97"android:text ="@ string/test_msg"/></LinearLayout></androidx.cardview.widget.CardView></LinearLayout> 

很明显,这里发生了很多事情,坦率地说,我很惊讶它能如此好地工作,或者至少直到androidx和API版本29出现时,它才起作用..

问题:问题在于该应用在300多个记录集上的运行速度非常慢,我对如何解决它有些困惑……

最新修复!:@ martin-zeitler提出的修订后的 R.layout.msgh_detail 现在似乎可以正常工作,并且可以立即加载大量数据.

从包含布局(现已丢弃)中删除了整个 androidx.core.widget.NestedScrollView 块,并替换为 androidx.recyclerview.widget.RecyclerView .

 <?xml version ="1.0" encoding ="utf-8"?>< androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android ="http://schemas.android.com/apk/res/android"xmlns:app ="http://schemas.android.com/apk/res-auto"android:id ="@ + id/main_content"android:layout_width ="match_parent"android:layout_height ="match_parent">< com.google.android.material.appbar.AppBarLayoutandroid:id ="@ + id/appbar"android:layout_width ="match_parent"android:layout_height ="wrap_content"android:theme ="@ style/ThemeOverlay.AppCompat.Dark.ActionBar">< androidx.appcompat.widget.Toolbarandroid:id ="@ + id/toolbar"android:layout_width ="match_parent"android:layout_height =?attr/actionBarSize"app:popupTheme ="@ style/ThemeOverlay.AppCompat.Light"app:layout_collapseMode ="pin"/></com.google.android.material.appbar.AppBarLayout>< androidx.recyclerview.widget.RecyclerViewandroid:id ="@ + id/detail_recyclerview"android:layout_width ="match_parent"android:layout_height ="match_parent"android:layout_marginBottom ="70dp"app:layout_behavior ="@ string/appbar_scrolling_view_behavior"/>< androidx.cardview.widget.CardViewandroid:layout_width ="match_parent"android:layout_height ="wrap_content"android:id ="@ + id/replyCard"android:layout_marginBottom ="2dp"android:layout_marginLeft ="@ dimen/card_margin"android:layout_marginRight ="@ dimen/card_margin"android:layout_gravity ="bottom"android:layout_alignParentBottom ="true"android:touchscreenBlocksFocus ="false">< LinearLayoutstyle ="@ style/Widget.CardContent"android:layout_width ="match_parent"android:layout_height ="wrap_content">< EditTextandroid:layout_width ="match_parent"android:layout_height ="wrap_content"android:inputType ="textMultiLine | textCapSentences"android:maxLength ="250"android:ems ="10"android:imeOptions ="actionDone"android:id ="@ + id/msg_reply"android:hint ="@ string/msg_reply_hint"/></LinearLayout></androidx.cardview.widget.CardView>< com.google.android.material.floatingactionbutton.FloatingActionButtonandroid:id ="@ + id/fab3"android:layout_width ="wrap_content"android:layout_height ="wrap_content"app:layout_anchor ="@ id/replyCard"app:layout_anchorGravity ="top | right | end"android:layout_margin ="8dp"android:src ="@ drawable/ic_send_white_24dp"/></androidx.coordinatorlayout.widget.CoordinatorLayout> 

解决方案

也注意到,曾经,它变得相当缓慢...

问题可能出在 NestedScrollView > LinearLayout > RecyclerView .

此外, include 几乎没有用,只包含一个节点....您必须像这样嵌套它:

 < androidx.core.widget.NestedScrollViewandroid:layout_width ="match_parent"android:layout_height ="wrap_content"android:isScrollContainer ="true"android:longClickable ="false"android:measureAllChildren ="true"app:layout_behavior ="@ string/appbar_scrolling_view_behavior">< androidx.recyclerview.widget.RecyclerViewandroid:id ="@ + id/recyclerview"工具:listitem ="@ layout/cardview"android:layout_width ="match_parent"android:layout_height ="match_parent"android:color =?android:colorControlHighlight"android:fastScrollEnabled ="true"android:gravity ="start"android:scrollbarStyle ="insideInset"android:scrollbars ="vertical"android:splitMotionEvents ="false"android:verticalScrollbarPosition ="right"/></androidx.core.widget.NestedScrollView> 

Migrated app to support latest API 29. All has gone very well, app functions correctly, except for one perplexing issue; A recyclerview is populated using a SQLite query, which may retrieve 500+ records, and displays the result in a detail activity that looks like this.

This has always worked fine on API 27 with the detail activity opened & populated almost instantly, while the sql call, activity code and layout hasn't changed in 5 years. However, on the API 29 version, using the same code, the app takes 3+ seconds to display the same data

After much testing and reading Slow Rendering, I think I've nailed it down to androidx.recyclerview:recyclerview:1.0.0 in API 29 taking much longer to build the output for the activity UI, possibly due to my poor coding and/or layout structure.

This is my R.layout.msgh_detail populated by the .java

<?xml version="1.0" encoding="utf-8"?>

<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/main_content"
android:layout_width="match_parent"
android:layout_height="match_parent">

<com.google.android.material.appbar.AppBarLayout
    android:id="@+id/appbar"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">

    <androidx.appcompat.widget.Toolbar
        android:id="@+id/toolbar"
        android:layout_width="match_parent"
        android:layout_height="?attr/actionBarSize"
        app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
        app:layout_collapseMode="pin" />

</com.google.android.material.appbar.AppBarLayout>

<androidx.core.widget.NestedScrollView
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_marginBottom="75dp"
    app:layout_behavior="@string/appbar_scrolling_view_behavior">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:gravity="center_vertical"
        android:orientation="vertical">

        <include
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            layout="@layout/msgh_detail_list" />

    </LinearLayout>

</androidx.core.widget.NestedScrollView>

<androidx.cardview.widget.CardView
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:id="@+id/replyCard"
    android:layout_marginBottom="2dp"
    android:layout_marginLeft="@dimen/card_margin"
    android:layout_marginRight="@dimen/card_margin"
    android:layout_gravity="bottom"
    android:layout_alignParentBottom="true"
    android:touchscreenBlocksFocus="false">

    <LinearLayout
        style="@style/Widget.CardContent"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
        <EditText
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:inputType="textMultiLine|textCapSentences"
            android:maxLength="250"
            android:ems="10"
            android:imeOptions="actionDone"
            android:id="@+id/msg_reply"
            android:hint="@string/msg_reply_hint" />
    </LinearLayout>

</androidx.cardview.widget.CardView>

<com.google.android.material.floatingactionbutton.FloatingActionButton
        android:id="@+id/fab3"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:layout_anchor="@id/replyCard"
        app:layout_anchorGravity="top|right|end"
        android:layout_margin="8dp"
        android:src="@drawable/ic_send_white_24dp" />

</androidx.coordinatorlayout.widget.CoordinatorLayout>

Here is the include R.layout.msgh_detail_list_item via .java ViewHolder

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:paddingTop="4dp"
android:paddingBottom="4dp"
android:layout_marginLeft="8dp"
android:layout_marginRight="8dp"
android:gravity="center_vertical"
android:orientation="vertical">
<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="24dp"
    android:orientation="horizontal">

    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginLeft="8dp"
        android:layout_weight="0.97"
        android:id="@+id/DayMMdd"
        android:ellipsize="end"
        android:maxLines="1"
        android:hint="@string/day_mth_dte" />

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/arrivaltime"
        android:layout_marginLeft="8dp"
        android:hint="@string/Hour_min" />

    <ImageView
        android:layout_width="24dp"
        android:layout_height="24dp"
        android:id="@+id/avatar"
        android:src="@drawable/status_1"
        android:layout_marginLeft="8dp"
        android:layout_marginRight="8dp"
        android:longClickable="false" />

</LinearLayout>


<androidx.cardview.widget.CardView
    android:id="@+id/detail_cardview"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    app:cardBackgroundColor="#ccecf9">

    <LinearLayout
        style="@style/Widget.CardContent"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <TextView
            android:id="@+id/text2"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:textAppearance="?attr/textAppearanceListItem"
            android:autoLink="web"
            android:textColorLink="#009933"
            android:layout_weight="0.97"
            android:text="@string/test_msg" />

    </LinearLayout>

</androidx.cardview.widget.CardView>

</LinearLayout>

Clearly, there's quite a lot going on here and, frankly, I'm amazed it works so well, or at least it did until androidx and API version 29 came along..!

QUESTION: The issue is that the app gets exceedingly slow on a 300+ recordset and I'm a bit stumped on how to fix it...

LATER FIXED!: Revised R.layout.msgh_detail subsequent to tip by @martin-zeitler that now seems to work properly and load data pretty much instantly.

Removed entire androidx.core.widget.NestedScrollView block and replaced with androidx.recyclerview.widget.RecyclerView from the include layout (now discarded).

<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/main_content"
android:layout_width="match_parent"
android:layout_height="match_parent">

<com.google.android.material.appbar.AppBarLayout
    android:id="@+id/appbar"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">

    <androidx.appcompat.widget.Toolbar
        android:id="@+id/toolbar"
        android:layout_width="match_parent"
        android:layout_height="?attr/actionBarSize"
        app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
        app:layout_collapseMode="pin" />

</com.google.android.material.appbar.AppBarLayout>

<androidx.recyclerview.widget.RecyclerView
    android:id="@+id/detail_recyclerview"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_marginBottom="70dp"
    app:layout_behavior="@string/appbar_scrolling_view_behavior"/>

<androidx.cardview.widget.CardView
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:id="@+id/replyCard"
    android:layout_marginBottom="2dp"
    android:layout_marginLeft="@dimen/card_margin"
    android:layout_marginRight="@dimen/card_margin"
    android:layout_gravity="bottom"
    android:layout_alignParentBottom="true"
    android:touchscreenBlocksFocus="false">

    <LinearLayout
        style="@style/Widget.CardContent"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
        <EditText
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:inputType="textMultiLine|textCapSentences"
            android:maxLength="250"
            android:ems="10"
            android:imeOptions="actionDone"
            android:id="@+id/msg_reply"
            android:hint="@string/msg_reply_hint" />
    </LinearLayout>

</androidx.cardview.widget.CardView>

<com.google.android.material.floatingactionbutton.FloatingActionButton
        android:id="@+id/fab3"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:layout_anchor="@id/replyCard"
        app:layout_anchorGravity="top|right|end"
        android:layout_margin="8dp"
        android:src="@drawable/ic_send_white_24dp" />

</androidx.coordinatorlayout.widget.CoordinatorLayout>

解决方案

Also noticed that once, that it became quite sluggish ...

The problem is likely that NestedScrollView > LinearLayout > RecyclerView.

Also that include is pretty useless, with one single node contained.... you have to nest it like this:

<androidx.core.widget.NestedScrollView
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:isScrollContainer="true"
    android:longClickable="false"
    android:measureAllChildren="true"
    app:layout_behavior="@string/appbar_scrolling_view_behavior">

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/recyclerview"
        tools:listitem="@layout/cardview"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:color="?android:colorControlHighlight"
        android:fastScrollEnabled="true"
        android:gravity="start"
        android:scrollbarStyle="insideInset"
        android:scrollbars="vertical"
        android:splitMotionEvents="false"
        android:verticalScrollbarPosition="right"/>

</androidx.core.widget.NestedScrollView>

这篇关于从API 27迁移到29后,Android recyclerview的性能不佳的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆