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

时间:2016-05-06 07:42:21

标签: android listview textview

我有ListView的活动。在每个列表项中显示TextView。使用这些方法切换所选位置的属性EditText#setTextIsSelectableEditText#setEllipsize& EditText#setSingleLine。点击第1项工作正常。但是点击另一个项目我正在StackOverFlowError

以下是我的代码示例。如果我有任何错误,请告诉我。

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_width="match_parent"
    android:layout_height="match_parent"
    android:focusable="false"
    android:focusableInTouchMode="false"
    android:orientation="vertical"
    android:padding="5dp">

    <TextView
        android:id="@+id/selectableTextView"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        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.StackOverflowError: 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)

提前致谢。

编辑:

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

5 个答案:

答案 0 :(得分:3)

最后,我得到了解决问题的方法。我在ViewHolder中删除了MyAdapter模式,如

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模式时仍然没有找到问题的原因。如果有人找到原因让我知道。

答案 1 :(得分:1)

我递归地打电话给onBackPressed(),这给了我StackOverFlowError

答案 2 :(得分:0)

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

  1. 删除MyAdapter构造函数中的inflater = LayoutInflater.from(context);
  2. 按照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);
    }
    

答案 3 :(得分:0)

对于列表滚动的大部分迭代都会产生此错误。避免...

答案 4 :(得分:0)

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