You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SearchableSpinner弹窗未关闭按Home键重启APP崩溃求助

解决SearchableSpinner后台恢复崩溃问题

问题根源

崩溃核心原因是com.toptoche.searchablespinnerlibrary.SearchableSpinner类实现了Serializable接口,但内部持有PopupWindow、Context等无法序列化的对象。当APP打开弹窗时进入后台,系统尝试序列化Activity状态时,会触发这些非序列化对象的写入异常,抛出BadParcelableException。

解决方案

方案1:后台前自动关闭弹窗(最简单有效)

在Activity进入后台时强制关闭Spinner弹窗,避免序列化时持有弹窗引用:

@Override
protected void onPause() {
    super.onPause();
    if (niceSpinner_word1 != null && niceSpinner_word1.isPopupShowing()) {
        niceSpinner_word1.dismissPopup();
    }
}

该方法无需修改库源码,直接在业务代码中处理,可快速解决问题。

方案2:修改库源码修复序列化问题

若需保留弹窗在后台恢复时的状态,可修改库中SearchableSpinner类的实现:
将类中无法序列化的成员(如PopupWindow、Context、View相关引用)用transient关键字标记,序列化时忽略这些字段:

public class SearchableSpinner extends AppCompatSpinner implements Serializable {
    private transient PopupWindow mPopupWindow;
    private transient Context mContext;
    // 其他非序列化成员都添加transient标记
}

若依赖远程库,需fork原仓库修改后,改为依赖自己的fork版本。

方案3:替换为自定义搜索弹窗

放弃使用问题库,用DialogFragment实现带搜索功能的选择弹窗,完全控制状态管理:

// 自定义带搜索的选择弹窗
public class SearchSelectDialog extends DialogFragment {
    private RecyclerView recyclerView;
    private EditText searchEt;
    private List<String> dataList;
    private SearchSelectAdapter adapter;
    private OnItemSelectedListener listener;

    public interface OnItemSelectedListener {
        void onItemSelected(String item);
    }

    @NonNull
    @Override
    public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) {
        View view = LayoutInflater.from(getContext()).inflate(R.layout.dialog_search_select, null);
        recyclerView = view.findViewById(R.id.recycler_view);
        searchEt = view.findViewById(R.id.search_et);

        // 初始化列表和搜索逻辑
        dataList = getArguments().getStringArrayList("data");
        adapter = new SearchSelectAdapter(dataList);
        recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
        recyclerView.setAdapter(adapter);

        searchEt.addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {}

            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {
                adapter.filter(s.toString());
            }

            @Override
            public void afterTextChanged(Editable s) {}
        });

        adapter.setOnItemClickListener(item -> {
            if (listener != null) {
                listener.onItemSelected(item);
            }
            dismiss();
        });

        AlertDialog.Builder builder = new AlertDialog.Builder(getContext());
        builder.setView(view)
               .setTitle("select word from spinner")
               .setNegativeButton("close", (dialog, which) -> dismiss());
        return builder.create();
    }

    // 设置选择回调
    public void setOnItemSelectedListener(OnItemSelectedListener listener) {
        this.listener = listener;
    }
}

使用时在Activity中调用:

// 打开自定义搜索弹窗
SearchSelectDialog dialog = new SearchSelectDialog();
Bundle args = new Bundle();
args.putStringArrayList("data", new ArrayList<>(dataset1));
dialog.setArguments(args);
dialog.setOnItemSelectedListener(item -> {
    refword1 = item;
});
dialog.show(getSupportFragmentManager(), "search_select");

内容的提问来源于stack exchange,提问作者Mahdi H

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.12 13:18:36