簡體   English   中英

在android中非常緩慢的布局膨脹

[英]Extremely slow layout inflating in android

我正在重構 android 應用程序。 在第一次開始之前,我做了很多改變,在某些地方它變得遲鈍。 這里是這樣的地方之一。

我有一個包含多個 Fragment 的選項卡布局。 一些 Fragments 工作正常,但這個是緩慢的。 它只是從 android 房間數據庫中獲取一些“品牌”並使用 Adapter 填充 ListView。

片段 onCreateView 方法:

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_item_list_ll, container, false);
        LinearLayout linearLayout = view.findViewById(R.id.fragment_layout);
        mListView = linearLayout.findViewById(android.R.id.list);
        mListView.setAdapter(mAdapter);
        mListView.setOnItemClickListener((adapterView, view1, i, l) -> {
            Brand brand = mAdapter.getItem(i);
            if(brand == null) return;
            brand.setSelected(!brand.isSelected());
            mBrandsViewModel.upsertBrand(brand);
        });
        return view;
    }

適配器獲取視圖:

    @Override
    public View getView(final int position, View convertView, @NonNull ViewGroup parent) {
        Logger.i(getClass().getName(), "Called getView");
        if (convertView == null) {
            LayoutInflater inflater = context.getLayoutInflater();
            Logger.i(getClass().getName(), "Got inflater");
            convertView = inflater.inflate(R.layout.brand_list_item, parent, false);
        }
        Logger.i(getClass().getName(), "View inflated");
        TextView brandNameTextView = convertView.findViewById(R.id.brandNameTextView);
        CheckBox brandCheckBox = convertView.findViewById(R.id.brandCheckBox);
        Brand brand = brands.get(position);
        brandNameTextView.setText(brand.getBrandName());
        brandCheckBox.setChecked(brand.isSelected());
        brandNameTextView.setGravity(Gravity.CENTER);
        return convertView;

//        if (convertView == null) {
//            LayoutInflater inflater = context.getLayoutInflater();
//            convertView = inflater.inflate(android.R.layout.simple_list_item_checked, null, true);
//
//        }
//        Brand brand = brands.get(position);
//        CheckedTextView textView = convertView.findViewById(android.R.id.text1);
//        textView.setText(brand.getBrandName());
//        textView.setChecked(brand.isSelected());
//        return convertView;
    }

R.layout.brand_list_item 的 XML

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:descendantFocusability="blocksDescendants"
    android:orientation="horizontal">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:baselineAligned="false"
        android:orientation="horizontal"
        android:textAppearance="?android:attr/textAppearanceMedium"
        android:weightSum="1">

        <TextView
            android:id="@+id/brandNameTextView"
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:textAppearance="?android:attr/textAppearanceMedium" />

        <CheckBox
            android:id="@+id/brandCheckBox"
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:layout_marginLeft="10dp"
            android:layout_marginRight="10dp"
            android:layout_weight="1" />
    </LinearLayout>
</LinearLayout>

這是創建 Fragment 時的 logcat

03-17 07:25:55.249 4181-4181/some.package.here D/AbsListView: onDetachedFromWindow
03-17 07:25:55.309 4181-4181/some.package.here D/AbsListView: Get MotionRecognitionManager
03-17 07:25:55.449 4181-4181/some.package.here I/some.package.here.preference.adapters.BrandAdapter: Called getView
03-17 07:25:55.449 4181-4181/some.package.here I/some.package.here.preference.adapters.BrandAdapter: Got inflater
03-17 07:25:55.729 4181-4181/some.package.here D/dalvikvm: GC_FOR_ALLOC freed 1461K, 33% free 9585K/14264K, paused 36ms, total 36ms
03-17 07:25:56.359 4181-4181/some.package.here W/Resources: Converting to boolean: TypedValue{t=0x3/d=0x4e4 "res/layout/dialog_title_holo.xml" a=2 r=0x109004d}
03-17 07:25:56.909 4181-4181/some.package.here W/Resources: Converting to boolean: TypedValue{t=0x3/d=0x4e4 "res/layout/dialog_title_holo.xml" a=2 r=0x109004d}
03-17 07:25:56.919 4181-4181/some.package.here I/some.package.here.preference.adapters.BrandAdapter: View inflated
03-17 07:25:56.979 4181-4181/some.package.here I/some.package.here.preference.adapters.BrandAdapter: Called getView
03-17 07:25:56.979 4181-4181/some.package.here I/some.package.here.preference.adapters.BrandAdapter: Got inflater
03-17 07:25:57.749 4181-4181/some.package.here W/Resources: Converting to boolean: TypedValue{t=0x3/d=0x4e4 "res/layout/dialog_title_holo.xml" a=2 r=0x109004d}
03-17 07:25:58.289 4181-4181/some.package.here W/Resources: Converting to boolean: TypedValue{t=0x3/d=0x4e4 "res/layout/dialog_title_holo.xml" a=2 r=0x109004d}
03-17 07:25:58.299 4181-4181/some.package.here I/some.package.here.preference.adapters.BrandAdapter: View inflated
03-17 07:25:58.359 4181-4181/some.package.here I/some.package.here.preference.adapters.BrandAdapter: Called getView
03-17 07:25:58.359 4181-4181/some.package.here I/some.package.here.preference.adapters.BrandAdapter: Got inflater
03-17 07:25:58.979 4181-4181/some.package.here D/dalvikvm: GC_FOR_ALLOC freed 3488K, 43% free 8144K/14264K, paused 34ms, total 34ms
03-17 07:25:59.119 4181-4181/some.package.here W/Resources: Converting to boolean: TypedValue{t=0x3/d=0x4e4 "res/layout/dialog_title_holo.xml" a=2 r=0x109004d}
03-17 07:25:59.659 4181-4181/some.package.here W/Resources: Converting to boolean: TypedValue{t=0x3/d=0x4e4 "res/layout/dialog_title_holo.xml" a=2 r=0x109004d}
03-17 07:25:59.669 4181-4181/some.package.here I/some.package.here.preference.adapters.BrandAdapter: View inflated
03-17 07:25:59.739 4181-4181/some.package.here I/some.package.here.preference.adapters.BrandAdapter: Called getView
03-17 07:25:59.739 4181-4181/some.package.here I/some.package.here.preference.adapters.BrandAdapter: Got inflater
03-17 07:26:00.499 4181-4181/some.package.here W/Resources: Converting to boolean: TypedValue{t=0x3/d=0x4e4 "res/layout/dialog_title_holo.xml" a=2 r=0x109004d}
03-17 07:26:01.049 4181-4181/some.package.here W/Resources: Converting to boolean: TypedValue{t=0x3/d=0x4e4 "res/layout/dialog_title_holo.xml" a=2 r=0x109004d}
03-17 07:26:01.059 4181-4181/some.package.here I/some.package.here.preference.adapters.BrandAdapter: View inflated
03-17 07:26:01.089 4181-4181/some.package.here I/some.package.here.preference.adapters.BrandAdapter: Called getView
03-17 07:26:01.089 4181-4181/some.package.here I/some.package.here.preference.adapters.BrandAdapter: Got inflater
03-17 07:26:01.669 4181-4181/some.package.here W/Resources: Converting to boolean: TypedValue{t=0x3/d=0x4e4 "res/layout/dialog_title_holo.xml" a=2 r=0x109004d}
03-17 07:26:02.079 4181-4181/some.package.here D/dalvikvm: GC_FOR_ALLOC freed 1523K, 40% free 8669K/14264K, paused 33ms, total 33ms
03-17 07:26:02.399 4181-4181/some.package.here W/Resources: Converting to boolean: TypedValue{t=0x3/d=0x4e4 "res/layout/dialog_title_holo.xml" a=2 r=0x109004d}
03-17 07:26:02.419 4181-4181/some.package.here I/some.package.here.preference.adapters.BrandAdapter: View inflated
03-17 07:26:02.479 4181-4181/some.package.here I/some.package.here.preference.adapters.BrandAdapter: Called getView
03-17 07:26:02.479 4181-4181/some.package.here I/some.package.here.preference.adapters.BrandAdapter: Got inflater
03-17 07:26:03.239 4181-4181/some.package.here W/Resources: Converting to boolean: TypedValue{t=0x3/d=0x4e4 "res/layout/dialog_title_holo.xml" a=2 r=0x109004d}
03-17 07:26:03.789 4181-4181/some.package.here W/Resources: Converting to boolean: TypedValue{t=0x3/d=0x4e4 "res/layout/dialog_title_holo.xml" a=2 r=0x109004d}
03-17 07:26:03.799 4181-4181/some.package.here I/some.package.here.preference.adapters.BrandAdapter: View inflated
03-17 07:26:03.869 4181-4181/some.package.here I/some.package.here.preference.adapters.BrandAdapter: Called getView
03-17 07:26:03.869 4181-4181/some.package.here I/some.package.here.preference.adapters.BrandAdapter: Got inflater
03-17 07:26:04.449 4181-4181/some.package.here W/Resources: Converting to boolean: TypedValue{t=0x3/d=0x4e4 "res/layout/dialog_title_holo.xml" a=2 r=0x109004d}
03-17 07:26:05.039 4181-4181/some.package.here W/Resources: Converting to boolean: TypedValue{t=0x3/d=0x4e4 "res/layout/dialog_title_holo.xml" a=2 r=0x109004d}
03-17 07:26:05.059 4181-4181/some.package.here I/some.package.here.preference.adapters.BrandAdapter: View inflated
03-17 07:26:05.099 4181-4181/some.package.here D/dalvikvm: GC_FOR_ALLOC freed 1536K, 36% free 9142K/14264K, paused 35ms, total 35ms
03-17 07:26:05.239 4181-4181/some.package.here I/some.package.here.preference.adapters.BrandAdapter: Called getView
03-17 07:26:05.239 4181-4181/some.package.here I/some.package.here.preference.adapters.BrandAdapter: Got inflater
03-17 07:26:06.019 4181-4181/some.package.here W/Resources: Converting to boolean: TypedValue{t=0x3/d=0x4e4 "res/layout/dialog_title_holo.xml" a=2 r=0x109004d}
03-17 07:26:06.559 4181-4181/some.package.here W/Resources: Converting to boolean: TypedValue{t=0x3/d=0x4e4 "res/layout/dialog_title_holo.xml" a=2 r=0x109004d}
03-17 07:26:06.569 4181-4181/some.package.here I/some.package.here.preference.adapters.BrandAdapter: View inflated
03-17 07:26:06.679 4181-4181/some.package.here I/Choreographer: Skipped 679 frames!  The application may be doing too much work on its main thread.

我注意到在通貨膨脹期間會發生一些事情,但我無法弄清楚究竟是什么以及如何解決緩慢的性能。 另外我不明白為什么res/layout/dialog_title_holo.xml被調用。

需要了解的重要事項:

  • 應用程序中每個緩慢的地方都有W/Resources: Converting to boolean: TypedValue...
  • 當我在適配器的 getView 方法(注釋掉的部分)中使用內置項目android.R.layout.simple_list_item_checked而不是我自己的項目時,一切都像魅力一樣。

編輯: ViewHolder 模式不能解決問題。 我在 logcat 中觀察到相同的消息: W/Resources: Converting to boolean: TypedValue...感謝任何幫助。

您的代碼的問題是您正在為每個列表項初始化視圖。 您可以使用回收器視圖替換列表視圖,也可以在列表適配器中使用視圖持有者。

@Override
public View getView(final int position, View convertView, @NonNull ViewGroup parent) {
    ViewHolder viewHolder;

    if (convertView == null) {
            LayoutInflater inflater = context.getLayoutInflater();
            Logger.i(getClass().getName(), "Got inflater");
            convertView = inflater.inflate(R.layout.brand_list_item, parent, false);
            viewHolder = new ViewHolder(convertView);
            convertView.setTag(viewHolder);
    }else{
        viewHolder = (ViewHolder) convertView.getTag();
    }

    Brand brand = brands.get(position);
    viewHolder.brandNameTextView.setText(brand.getBrandName());
    viewHolder.brandCheckBox.setChecked(brand.isSelected());
    viewHolder.brandNameTextView.setGravity(Gravity.CENTER);
    return convertView;
}

public static class ViewHolder{
    public TextView brandNameTextView;
    public CheckBox brandCheckBox;

    public ViewHolder(View view){
        brandNameTextView = view.findViewById(R.id.brandNameTextView);
        brandCheckBox = view.findViewById(R.id.brandCheckBox);
    }
}

好的。 我想我找到了原因。

在重構期間,我將應用程序從 android.support libs 移到了 androidx lib,這顯然對舊平台設備不友好(我的已經很舊了)

我是如何得出這個結論的:

  1. 從接過演示項目文章(使用android.support庫)
  2. 編譯,運行,一切正常
  3. 將 gradle 從 android.support 更改為 androidx 和 voi là:
03-18 07:34:48.789 20235-20235/de.jakobulbrich.preferences D/dalvikvm: VFY: replacing opcode 0x1f at 0x0006
03-18 07:34:49.359 20235-20235/de.jakobulbrich.preferences W/Resources: Converting to boolean: TypedValue{t=0x3/d=0x4e4 "res/layout/dialog_title_holo.xml" a=2 r=0x109004d}
03-18 07:34:49.899 20235-20235/de.jakobulbrich.preferences W/Resources: Converting to boolean: TypedValue{t=0x3/d=0x4e4 "res/layout/dialog_title_holo.xml" a=2 r=0x109004d}
03-18 07:34:49.909 20235-20235/de.jakobulbrich.preferences I/dalvikvm: Could not find method android.widget.CompoundButton.getButtonDrawable, referenced from method androidx.core.widget.CompoundButtonCompat.getButtonDrawable
03-18 07:34:49.909 20235-20235/de.jakobulbrich.preferences W/dalvikvm: VFY: unable to resolve virtual method 2762: Landroid/widget/CompoundButton;.getButtonDrawable ()Landroid/graphics/drawable/Drawable;
03-18 07:34:49.909 20235-20235/de.jakobulbrich.preferences D/dalvikvm: VFY: replacing opcode 0x6e at 0x0006
03-18 07:34:49.909 20235-20235/de.jakobulbrich.preferences I/dalvikvm: Could not find method android.widget.CompoundButton.getButtonTintList, referenced from method androidx.core.widget.CompoundButtonCompat.getButtonTintList
03-18 07:34:49.909 20235-20235/de.jakobulbrich.preferences W/dalvikvm: VFY: unable to resolve virtual method 2763: Landroid/widget/CompoundButton;.getButtonTintList ()Landroid/content/res/ColorStateList;
03-18 07:34:49.909 20235-20235/de.jakobulbrich.preferences D/dalvikvm: VFY: replacing opcode 0x6e at 0x0006
03-18 07:34:49.909 20235-20235/de.jakobulbrich.preferences I/dalvikvm: Could not find method android.widget.CompoundButton.getButtonTintMode, referenced from method androidx.core.widget.CompoundButtonCompat.getButtonTintMode
03-18 07:34:49.909 20235-20235/de.jakobulbrich.preferences W/dalvikvm: VFY: unable to resolve virtual method 2764: Landroid/widget/CompoundButton;.getButtonTintMode ()Landroid/graphics/PorterDuff$Mode;
03-18 07:34:49.909 20235-20235/de.jakobulbrich.preferences D/dalvikvm: VFY: replacing opcode 0x6e at 0x0006
03-18 07:34:49.909 20235-20235/de.jakobulbrich.preferences I/dalvikvm: Could not find method android.widget.CompoundButton.setButtonTintList, referenced from method androidx.core.widget.CompoundButtonCompat.setButtonTintList
03-18 07:34:49.909 20235-20235/de.jakobulbrich.preferences W/dalvikvm: VFY: unable to resolve virtual method 2780: Landroid/widget/CompoundButton;.setButtonTintList (Landroid/content/res/ColorStateList;)V
03-18 07:34:49.909 20235-20235/de.jakobulbrich.preferences D/dalvikvm: VFY: replacing opcode 0x6e at 0x0006
03-18 07:34:49.909 20235-20235/de.jakobulbrich.preferences I/dalvikvm: Could not find method android.widget.CompoundButton.setButtonTintMode, referenced from method androidx.core.widget.CompoundButtonCompat.setButtonTintMode
03-18 07:34:49.909 20235-20235/de.jakobulbrich.preferences W/dalvikvm: VFY: unable to resolve virtual method 2781: Landroid/widget/CompoundButton;.setButtonTintMode (Landroid/graphics/PorterDuff$Mode;)V
03-18 07:34:49.909 20235-20235/de.jakobulbrich.preferences D/dalvikvm: VFY: replacing opcode 0x6e at 0x0006
03-18 07:34:50.209 20235-20235/de.jakobulbrich.preferences I/dalvikvm: Could not find method android.view.View.setTooltipText, referenced from method androidx.appcompat.widget.TooltipCompat.setTooltipText
03-18 07:34:50.209 20235-20235/de.jakobulbrich.preferences W/dalvikvm: VFY: unable to resolve virtual method 2127: Landroid/view/View;.setTooltipText (Ljava/lang/CharSequence;)V
03-18 07:34:50.209 20235-20235/de.jakobulbrich.preferences D/dalvikvm: VFY: replacing opcode 0x6e at 0x0006
03-18 07:34:50.219 20235-20235/de.jakobulbrich.preferences I/Choreographer: Skipped 130 frames!  The application may be doing too much work on its main thread.

相同的W/Resources: Converting to boolean:和來自 Choreographer 的相同消息

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM