java.lang.***Error:在 ListView 适配器中启用/禁用 TextView#setTextIsSelectable 时堆栈大小为 8MB

Posted

技术标签:

【中文标题】java.lang.***Error:在 ListView 适配器中启用/禁用 TextView#setTextIsSelectable 时堆栈大小为 8MB【英文标题】:java.lang.***Error: stack size 8MB while Enabling/Disabling TextView#setTextIsSelectable in ListView Adapter 【发布时间】:2016-09-01 05:00:36 【问题描述】:

我有一个 ListView 的活动。在每个列表项中显示TextView。使用这些方法 EditText#setTextIsSelectableEditText#setEllipsizeEditText#setSingleLine 切换所选位置的属性。单击第一项效果很好。但是当我点击另一个项目时,我得到了***Error

以下是我的代码示例。如果我做错了,请告诉我。

import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.text.TextUtils;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.BaseAdapter;
import android.widget.ListView;
import android.widget.TextView;

public class SelectableTextListActivity extends Activity 
    private static final String TAG = "HistoryActivity";

    private ListView listView;

    @Override
    protected void onCreate(Bundle savedInstanceState) 
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);//only ListView present in this layout
        listView = (ListView) findViewById(R.id.myList);

        String items[] = "Some Information Some Information Some Information", "Some Information Some Information Some Information", "Some Information Some Information Some Information", "Some Information Some Information Some Information",
                "Some Information Some Information Some Information", "Some Information Some Information Some Information", "Some Information Some Information Some Information", "Some Information Some Information Some Information";
        final MyAdapter myAdapter = new MyAdapter(this, items);
        listView.setAdapter(myAdapter);
        listView.setOnItemClickListener(new AdapterView.OnItemClickListener() 
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) 
                Log.d(TAG, "onItemClick: position=" + position);
                myAdapter.setSelectedPosition(position);
                myAdapter.notifyDataSetChanged();
            
        );
    

    private static class MyAdapter extends BaseAdapter 
        private static final String TAG = "HistoryAdapter";
        private final LayoutInflater inflater;
        private int mSelectedPosition = -1;
        private String[] mItems;

        public MyAdapter(Context context, String[] items) 
            mItems = items;
            inflater = LayoutInflater.from(context);
        

        public void setSelectedPosition(int mSelectedPosition) 
            this.mSelectedPosition = mSelectedPosition;
        

        @Override
        public View getView(final int position, View convertView, ViewGroup parent) 
            ViewHolder viewHolder;
            if (convertView == null) 
                convertView = inflater.inflate(R.layout.selectable_text_layout, null, false);
                viewHolder = new ViewHolder(convertView);
                convertView.setTag(viewHolder);
             else 
                viewHolder = (ViewHolder) convertView.getTag();
            
            String item = getItem(position);

            viewHolder.selectableTV.setText(item);


            if (position == mSelectedPosition) 
                Log.d(TAG, "getView() called with: " + "position = [" + position + "], selected = " + true);
                viewHolder.selectableTV.setTextIsSelectable(true);
                viewHolder.selectableTV.setSingleLine(false);
                viewHolder.selectableTV.setEllipsize(null);
             else 
                Log.d(TAG, "getView() called with: " + "position = [" + position + "], selected = " + false);
                viewHolder.selectableTV.setTextIsSelectable(false);
                viewHolder.selectableTV.setSingleLine(true);
                viewHolder.selectableTV.setEllipsize(TextUtils.TruncateAt.END);
            
            return convertView;
        


        @Override
        public String getItem(int position) 
            return mItems[position];
        

        @Override
        public long getItemId(int position) 
            return 0;
        

        @Override
        public int getCount() 
            return mItems.length;
        

        private class ViewHolder 
            public final TextView selectableTV;

            ViewHolder(View convertView) 
                selectableTV = (TextView) convertView.findViewById(R.id.selectableTextView);
            
        
    

布局文件: selectable_text_layout.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_
    android:layout_
    android:focusable="false"
    android:focusableInTouchMode="false"
    android:orientation="vertical"
    android:padding="5dp">

    <TextView
        android:id="@+id/selectableTextView"
        android:layout_
        android:layout_
        android:clickable="true"
        android:ellipsize="end"
        android:focusable="false"
        android:text="My app name"
        android:textAppearance="?android:textAppearanceMedium" />

</LinearLayout>

堆栈跟踪是

D/Error: ERR: stack=java.lang.***Error: stack size 8MB
at java.lang.Class.isInstance(Class.java:1484)
at android.text.SpannableStringInternal.getSpans(SpannableStringInternal.java:217)
at android.text.SpannedString.getSpans(SpannedString.java:25)
at android.text.SpannableStringInternal.<init>(SpannableStringInternal.java:40)
at android.text.SpannableString.<init>(SpannableString.java:30)
at android.widget.TextView.removeSuggestionSpans(TextView.java:4200)
at android.widget.TextView.setText(TextView.java:3926)
at android.widget.TextView.setText(TextView.java:3911)
at android.widget.TextView.getIterableTextForAccessibility(TextView.java:9047)
at android.view.View.onInitializeAccessibilityEventInternal(View.java:5450)
at android.view.View.onInitializeAccessibilityEvent(View.java:5422)
at android.widget.TextView.onInitializeAccessibilityEvent(TextView.java:8402)
at android.view.View.sendAccessibilityEventUncheckedInternal(View.java:5293)
at android.view.View.sendAccessibilityEventUnchecked(View.java:5280)
at android.view.View.sendAccessibilityEventInternal(View.java:5257)
at android.view.View.sendAccessibilityEvent(View.java:5226)
at android.widget.TextView.sendAccessibilityEvent(TextView.java:8571)
at android.widget.TextView.onSelectionChanged(TextView.java:7584)
at android.widget.TextView.spanChange(TextView.java:7784)
at android.widget.TextView$ChangeWatcher.onSpanAdded(TextView.java:9478)
at android.text.SpannableStringInternal.sendSpanAdded(SpannableStringInternal.java:314)
at android.text.SpannableStringInternal.setSpan(SpannableStringInternal.java:138)
at android.text.SpannableString.setSpan(SpannableString.java:46)
at android.text.SpannableStringInternal.<init>(SpannableStringInternal.java:52)
at android.text.SpannableString.<init>(SpannableString.java:30)
at android.widget.TextView.removeSuggestionSpans(TextView.java:4200)
at android.widget.TextView.setText(TextView.java:3926)
at android.widget.TextView.setText(TextView.java:3911)
at android.widget.TextView.getIterableTextForAccessibility(TextView.java:9047)
at android.view.View.onInitializeAccessibilityEventInternal(View.java:5450)
at android.view.View.onInitializeAccessibilityEvent(View.java:5422)
at android.widget.TextView.onInitializeAccessibilityEvent(TextView.java:8402)
at android.view.View.sendAccessibilityEventUncheckedInternal(View.java:5293)
at android.view.View.sendAccessibilityEventUnchecked(View.java:5280)
at android.view.View.sendAccessibilityEventInternal(View.java:5257)
at android.view.View.sendAccessibilityEvent(View.java:5226)
at android.widget.TextView.sendAccessibilityEvent(TextView.java:8571)
at android.widget.TextView.onSelectionChanged(TextView.java:7584)
at android.widget.TextView.spanChange(TextView.java:7784)
at android.widget.TextView$ChangeWatcher.onSpanAdded(TextView.java:9478)
at android.text.SpannableStringInternal.sendSpanAdded(SpannableStringInternal.java:314)
at android.text.SpannableStringInternal.setSpan(SpannableStringInternal.java:138)
at android.text.SpannableString.setSpan(SpannableString.java:46)
at android.text.SpannableStringInternal.<init>(SpannableStringInternal.java:52)
at android.text.SpannableString.<init>(SpannableString.java:30)
at android.widget.TextView.removeSuggestionSpans(TextView.java:4200)
at android.widget.TextView.setText(TextView.java:3926)
at android.widget.TextView.setText(TextView.java:3911)
at android.widget.TextView.getIterableTextForAccessibility(TextView.java:9047)
at android.view.View.onInitializeAccessibilityEventInternal(View.java:5450)
at android.view.View.onInitializeAccessibilityEvent(View.java:5422)
at android.widget.TextView.onInitializeAccessibilityEvent(TextView.java:8402)
at android.view.View.sendAccessibilityEventUncheckedInternal(View.java:5293)
at android.view.View.sendAccessibilityEventUnchecked(View.java:5280)
at android.view.View.sendAccessibilityEventInternal(View.java:5257)
at android.view.View.sendAccessibilityEvent(View.java:5226)
at android.widget.TextView.sendAccessibilityEvent(TextView.java:8

09-13 00:48:45.483 8705-8705/club.apptu.edittextlocalhistory D/Error: ERR: TOTAL BYTES WRITTEN: 16156172
09-13 00:48:45.483 8705-8705/club.apptu.edittextlocalhistory E/JavaBinder: !!! FAILED BINDER TRANSACTION !!!
09-13 00:48:45.484 8705-8705/club.apptu.edittextlocalhistory E/AndroidRuntime: Error reporting crash android.os.TransactionTooLargeException
at android.os.BinderProxy.transactNative(Native Method)
at android.os.BinderProxy.transact(Binder.java:496)
at android.app.ActivityManagerProxy.handleApplicationCrash(ActivityManagerNative.java:4144)
at com.android.internal.os.RuntimeInit$UncaughtHandler.uncaughtException(RuntimeInit.java:89)
at java.lang.ThreadGroup.uncaughtException(ThreadGroup.java:693)
at java.lang.ThreadGroup.uncaughtException(ThreadGroup.java:690)

提前致谢。

编辑:

ListView#onItemClickListener 中调用notifyDatasetChanged 时遇到问题。

【问题讨论】:

【参考方案1】:

我终于找到了解决问题的方法。我删除了MyAdapter 中的ViewHolder 模式

private static class MyAdapter extends BaseAdapter 
    private static final String TAG = "HistoryAdapter";
    private final LayoutInflater inflater;
    private int mSelectedPosition = -1;
    private String[] mItems;

    public MyAdapter(Context context, String[] mItems) 
        this.mItems = mItems;
        inflater = LayoutInflater.from(context);
    



    public void setSelectedPosition(int mSelectedPosition) 
        this.mSelectedPosition = mSelectedPosition;
    

    @Override
    public View getView(final int position, View convertView, ViewGroup parent) 

        convertView = inflater.inflate(R.layout.selectable_text_layout, null, false);
        TextView selectableTV = (TextView) convertView.findViewById(R.id.selectableTextView);

        selectableTV.setText(getItem(position));

        if (position == mSelectedPosition) 
            Log.d(TAG, "getView() called with: " + "position = [" + position + "], selected = " + true);
            selectableTV.setTextIsSelectable(true);
            selectableTV.setSingleLine(false);
            selectableTV.setEllipsize(null);
         else 
            Log.d(TAG, "getView() called with: " + "position = [" + position + "], selected = " + false);
            selectableTV.setTextIsSelectable(false);
            selectableTV.setSingleLine(true);
            selectableTV.setEllipsize(TextUtils.TruncateAt.END);
        

        return convertView;
    


    @Override
    public String getItem(int position) 
        return mItems[position];
    

    @Override
    public long getItemId(int position) 
        return 0;
    

    @Override
    public int getCount() 
        return mItems.length;
    

但是在使用ViewHolder模式时仍然没有找到问题的原因。如果有人找到原因,请告诉我。

【讨论】:

【参考方案2】:

我正在递归调用onBackPressed(),这导致了***Error

【讨论】:

类似的问题。谢谢。【参考方案3】:

查找错误的最佳方法是在您的代码中使用大量logcat 并找到logcat 未显示的位置。 但是您可以尝试像这样更改您的代码:

    删除 MyAdapter 构造函数中的inflater = LayoutInflater.from(context);

    将它移动到getview 方法中,如下所示:

    if (convertView == null) 
        LayoutInflater inflater = ((Activity) context).getLayoutInflater();
        convertView=inflater.inflate(R.layout.selectable_text_layout, null,false);</br>
        viewHolder = new ViewHolder(convertView);
        convertView.setTag(viewHolder);
    
    

【讨论】:

感谢您的回复。这不是实际问题。虽然我试过了但是问题还是没有解决。 调用 notifyDatasetChanged() 时出错,但找不到问题。 如果您发表评论会发生什么:myAdapter.notifyDataSetChanged();?第一个解决方案:替换 myAdapter.notifyDataSetChanged();到 ((MyAdapter)listView.getAdapter()).notifyDataSetChanged();如果它不起作用:尝试第二种解决方案:runOnUIThread(new Runnable() myAdapter.notifyDataSetChanged(); )【参考方案4】:

列表滚动的迭代次数过多会产生此错误。避免这种情况...

【讨论】:

【参考方案5】:

我的 log.i 语句太多,其中 gson 用于将数组转换为字符串以进行日志记录。当我删除所有日志时,***Error 消失了。

【讨论】:

以上是关于java.lang.***Error:在 ListView 适配器中启用/禁用 TextView#setTextIsSelectable 时堆栈大小为 8MB的主要内容,如果未能解决你的问题,请参考以下文章

JSON parse error: Cannot deserialize instance of `java.util.ArrayList<java.lang.Long>` out of START_

何时捕获 java.lang.Error?

springdatarepository ElasticSearch 在保存时工作,但在更新时失败 java.lang.***Error: null

如何解决 java.lang.***Error [重复]

是啥导致 java.lang.***Error

线程“主”java.lang.***Error actionListeners 中的异常