【问题标题】:Android customlistview crashes after scrolling repeatedlyAndroid customlistview 反复滚动后崩溃
【发布时间】:2019-02-12 07:08:10
【问题描述】:

我使用自定义布局创建了一个列表视图,但每次快速滚动时,应用程序都会崩溃,并在 Logcat 中出现以下错误。

我还没有真正尝试过任何东西,因为我还不熟悉 Android。 我尝试将android:hardwareAccelerated="false"android:largeHeap="true" 添加到AndroidManifest.xml 中,但仍然没有。

public View getView(int position, View convertView, ViewGroup parent) {

            LayoutInflater inflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            convertView = inflater.inflate(R.layout.list_view_switch_account,null);
            TextView first = (TextView)convertView.findViewById(R.id.full_name);
            ImageView img = (ImageView)convertView.findViewById(R.id.profile_picture);

            Account account = accountList.get(position);
            first.setText(account.getName());
            byte[] imgs = account.getImage();
            Bitmap bitmap = BitmapFactory.decodeByteArray(imgs,0,imgs.length);
            img.setImageBitmap(bitmap);
//            status.setText(account.getStatus());

        return convertView;
    }
}

java.lang.OutOfMemoryError: Failed to allocate a 3481968 byte allocation with 1143504 free bytes and 1116KB until OOM
        at dalvik.system.VMRuntime.newNonMovableArray(Native Method)
        at android.graphics.BitmapFactory.nativeDecodeByteArray(Native Method)
        at android.graphics.BitmapFactory.decodeByteArray(BitmapFactory.java:622)
        at android.graphics.BitmapFactory.decodeByteArray(BitmapFactory.java:645)
        at com.example.mgimoro.dietgo.AccountAdapter.getView(AccountAdapter.java:51)
        at android.widget.AbsListView.obtainView(AbsListView.java:2497)
        at android.widget.ListView.makeAndAddView(ListView.java:1930)
        at android.widget.ListView.fillDown(ListView.java:722)
        at android.widget.ListView.fillGap(ListView.java:686)
        at android.widget.AbsListView.trackMotionScroll(AbsListView.java:5792)
        at android.widget.AbsListView.scrollIfNeeded(AbsListView.java:3705)
        at android.widget.AbsListView.onTouchMove(AbsListView.java:4221)
        at android.widget.AbsListView.onTouchEvent(AbsListView.java:3991)
        at android.view.View.dispatchTouchEvent(View.java:9480)
        at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2662)
        at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2304)
        at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2668)
        at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2318)
        at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2668)
        at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2318)
        at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2668)
        at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2318)
        at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2668)
        at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2318)
        at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2668)
        at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2318)
        at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2668)
        at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2318)

【问题讨论】:

  • 你在AndroidManifest.xml文件中的application标签里试过android:largeHeap="true"吗?
  • 是的,我也试过了,但它仍然崩溃
  • 可能你的位图很大,尝试异步加载位图或者使用像glide或者picasso这样的库

标签: android android-bitmap


【解决方案1】:

OutOfMemoryError 是 android 在处理位图时最常见的问题。当由于内存空间不足而无法分配对象并且垃圾收集器无法释放一些空间时,Java 虚拟机 (JVM) 会引发此错误。

正如 Aleksey 所说,您可以在清单文件中添加以下实体 android:hardwareAccelerated="false" , android:largeHeap="true" 它适用于某些环境。

<application
android:allowBackup="true"
android:hardwareAccelerated="false"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:largeHeap="true"
android:supportsRtl="true"
android:theme="@style/AppTheme">

如果您从模拟器收到此错误,请 VM Heap

【讨论】:

  • 对不起,我忘了编辑我已经尝试添加这些但仍然崩溃。
【解决方案2】:

您正在尝试解码 ListView 中的大位图。尝试DownSample 您的位图,或者更好的是使用Glide 或毕加索为您完成。

更新:您仍在使用ListView,现在已被RecyclerView 取代。 RecyclerView 是显示项目列表的更好工具。
如果您决定坚持使用ListView,则应实施ViewHolder 模式以最大限度地减少视图膨胀,从而提高代码的性能。

【讨论】:

    【解决方案3】:

    我会建议你使用RecyclerView 而不是ListView。因为它比ListView更先进。

    这是官方链接: https://developer.android.com/guide/topics/ui/layout/recyclerview

    还尝试在您的RecyclerView 中使用分页概念。简单来说,首先加载部分数据,即 1-10 个项目,然后在用户滚动列表时加载下一个数据,即 11-20 个项目。这样的过程会增加您的加载时间并减少内存负载。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-10-12
      • 2011-04-24
      • 1970-01-01
      • 2014-02-24
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多