Android переработчик видят низкую производительность после API 27 - 29 Миграция - PullRequest
0 голосов
/ 08 июля 2019

Мигрированное приложение для поддержки новейшего API 29. Все прошло очень хорошо, приложение работает правильно, за исключением одной сложной проблемы;

A recyclerview заполняется с помощью запроса SQLite, который может получить более 500 записейи отображает результат в подробном действии, которое выглядит следующим образом.

enter image description here

Это всегда хорошо работало на API 27 с подробным действием, которое открывалось и заполнялось практически мгновенно, в то время как вызов SQL, код действия и макет не сохранилит изменилось за 5 лет.Однако в версии API 29 , использующей тот же код , приложению требуется 3 + секунд для отображения тех же данных (крошечный набор записей все еще быстр).

Миграция, включая «Миграция в AndroidX», казалось, прошла гладко, пока приложение синхронизирует / строит без ошибок.Требуется очень мало редактирования, Android Studio выполнила всю работу.

СТАРЫЙ API 27 build.gradle (Модуль: приложение) ниже

dependencies {
compile fileTree(include: ['*.jar'], dir: 'libs')
compile 'com.android.support:design:27.0.2'
compile 'com.android.support:appcompat-v7:27.0.2'
compile 'com.android.support:cardview-v7:27.0.2'
compile 'com.android.support:recyclerview-v7:27.0.2'
}

НОВЫЙ API 29 build.gradle (Модуль: приложение)ниже

dependencies {
implementation fileTree(include: ['*.jar'], dir: 'libs')
implementation 'com.google.android.material:material:1.0.0'
implementation 'androidx.appcompat:appcompat:1.0.2'
implementation 'androidx.cardview:cardview:1.0.0'
implementation 'androidx.recyclerview:recyclerview:1.0.0'
}

API 29 gradle.properties ниже

android.enableJetifier=true
android.useAndroidX=true

После длительного тестирования и чтения Медленный рендеринг , я думаю, я прибил его к androidx.recyclerview:recyclerview:1.0.0 в API 29 заняло гораздо больше времени для создания выходных данных для пользовательского интерфейса действия, возможно, из-за моей плохой структуры кода и / или структуры.

Вот действие .java (без импорта и объявления), вызываемое из MainActivity

public class SenderDetailActivity extends AppCompatActivity {

SQLActivity db3;
List<TXTF> dlist = new ArrayList<>();

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.msgh_detail);

    db3 = new SQLActivity(getApplicationContext());

    dlist.addAll(db3.arrayMSGHmsgsndrdetail("SENT"));

    RecyclerView rv = (RecyclerView) findViewById(R.id.detail_recyclerview);
    setupRecyclerView(rv);

private void setupRecyclerView(RecyclerView recyclerView) {
    recyclerView.setLayoutManager(new LinearLayoutManager(recyclerView.getContext()));
    recyclerView.setAdapter(new SimpleStringRecyclerViewAdapter(getApplicationContext(), dlist));
}

public static class SimpleStringRecyclerViewAdapter
        extends RecyclerView.Adapter<SimpleStringRecyclerViewAdapter.ViewHolder> {

    private final TypedValue mTypedValue = new TypedValue();
    private int mBackground;
    private List<TXTF> mValues;

    public static class ViewHolder extends RecyclerView.ViewHolder {
        public String mBoundString;
        public String mTxtsndrString;
        public String mTxtntwkString;
        public String mTxtaddrString;
        public String mTxtstsfString;
        public String mTxtgrpcString;
        public String mTxtacknString;

        public final View mView;
        public final ImageView mImageView;
        public final TextView mTextView;
        public final TextView mDayView;
        public final TextView mTimeView;
        public final CardView mCardView;

        public ViewHolder(View view) {
            super(view);
            mView = view;
            mImageView = (ImageView) view.findViewById(R.id.avatar);
            mDayView = (TextView) view.findViewById(R.id.DayMMdd);
            mTextView = (TextView) view.findViewById(R.id.text2);
            mTimeView = (TextView) view.findViewById(R.id.arrivaltime);
            mCardView = (CardView) itemView.findViewById(R.id.detail_cardview);
        }
    }

    public SimpleStringRecyclerViewAdapter(Context context, List<TXTF> items) {
        context.getTheme().resolveAttribute(R.attr.selectableItemBackground, mTypedValue, true);
        mBackground = mTypedValue.resourceId;
        mValues = items;
    }

    @Override
    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.msgh_detail_list_item, parent, false);
        view.setBackgroundResource(mBackground);
        return new ViewHolder(view);
    }

    @Override
    public void onBindViewHolder(final ViewHolder holder, int position) {
        holder.mBoundString = mValues.get(position).getMSGSRCE();
        holder.mBoundString = mValues.get(position).getsMSGSTSC();
        holder.mTxtsndrString = mValues.get(position).getMSGSNDR();
        holder.mTxtntwkString = mValues.get(position).getsMSGNTWK();
        holder.mTxtaddrString = mValues.get(position).getsMSGADDR();
        holder.mTxtgrpcString = mValues.get(position).getsMSGGRPC();
        holder.mTxtstsfString = mValues.get(position).getsMSGSTSF();
        holder.mTxtacknString = mValues.get(position).getsMSGACKN();
        if (mValues.get(position).getMSGRSTAT() != null && mValues.get(position).getMSGRSTAT().equals("M")){
            holder.mCardView.setCardBackgroundColor(Color.parseColor("#ffff99"));
            if (holder.mTxtstsfString.equals("1")){
                holder.mImageView.setImageResource(R.drawable.status_1);
            } else if (holder.mTxtstsfString.equals("2")){
                holder.mImageView.setImageResource(R.drawable.ic_forum_blu_24dp);
            } else {
                holder.mImageView.setImageResource(R.drawable.status_0);
            }

        } else { holder.mCardView.setCardBackgroundColor(Color.parseColor("#ccecf9"));
                 holder.mImageView.setImageResource(R.drawable.status_3);
        }
        holder.mDayView.setText(mValues.get(position).getsMSGDATE().substring(0,10));
        holder.mTimeView.setText(mValues.get(position).getsMSGDATE().substring(11,16));
        holder.mTextView.setText(mValues.get(position).getMSGTEXT());

        holder.mView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Context context = v.getContext();
                Intent intent = new Intent(context, MessageDetailActivity.class);
                intent.putExtra("MSGSRCE", holder.mBoundString);
                intent.putExtra("MSGSNDR", holder.mTxtsndrString);
                intent.putExtra("MSGNTWK", holder.mTxtntwkString);
                intent.putExtra("MSGADDR", holder.mTxtaddrString);
                intent.putExtra("MSGSTSF", holder.mTxtstsfString);
                intent.putExtra("MSGGRPC", holder.mTxtgrpcString);
                ((Activity) context).startActivityForResult(intent, 62);

            }
        });
    }

    @Override
    public int getItemCount() {
        return mValues.size();
    }
}
}

Это R.layout.msgh_detail, упомянутое в .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>

Теперь msgh_detail_list упоминается как R.id.detail_recyclerview в .java

<?xml version="1.0" encoding="utf-8"?>
<androidx.recyclerview.widget.RecyclerView xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/detail_recyclerview"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />

Инаконец, R.layout.msgh_detail_list_item в .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>

Очевидно, что здесь происходит довольно много, и, честно говоря, я поражен, что это работает так хорошо, или, по крайней мере, доПришли androidx и API версии 29 ..!

Не так много пользователей logcat, хотя я заметил компаниюuple строк из приложения.На самом деле не поняли, что они имеют в виду, за исключением + 2s860 мс для загрузки пользовательского интерфейса дисплея;

...
07-11 14:39:04.170  7758  7758 I Choreographer: Skipped 156 frames!  The application may be doing too much work on its main thread.
...
07-11 14:39:04.353  2810  2834 I ActivityManager: Displayed com.abc.def.pow/com.support.android.pow.DetailActivity: +2s860ms
...

ВОПРОС: Проблема в том, что приложение работает очень медленно на наборе записей 300+, и я 'Я немного озадачен тем, как это исправить. Может ли кто-нибудь помочь мне разобраться с этим? ..

ПОСЛЕДНЕЕ ИСПРАВЛЕНИЕ!: Исправлено R.layout.msgh_detail после подсказки @ martin-zeitlerтеперь это работает нормально и загружает данные практически мгновенно.

Удален весь блок 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.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>

1 Ответ

1 голос
/ 13 июля 2019

Также заметил, что однажды это стало довольно вялым ...

Проблема, вероятно, в том, что NestedScrollView> LinearLayout> RecyclerView.

Также, что includeдовольно бесполезно, с одним единственным узлом, содержащимся .... вы должны вложить его так:

<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>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...