Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
149 views
in Technique[技术] by (71.8m points)

Android recyclerview poor performance after API 27 to 29 Migration

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.

enter image description here

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>
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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>

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...