保存,将可扩展列表视图复选框状态加载到共享首选项 - 必须有更好的方法

时间:2012-09-30 12:51:06

标签: android arraylist sharedpreferences performance

基本上,我有一个带有复选框的可扩展列表视图,我希望将其状态保存到共享首选项。我正在实施的方法有效,但我觉得它并非完全可能。看到它崩溃我不会感到惊讶。基本上用我的方法,我使用序列化加载并保存我的活动类中的状态。

SharedPreferences settings3 = getSharedPreferences("MYPREFS", 0);    
        try {
            check_states = (ArrayList<ArrayList<Integer>>) ObjectSerializer.deserialize(settings3.getString("CBSTATES", ObjectSerializer.serialize(new ArrayList<ArrayList<Integer>>())));
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }

介于两者之间的更多代码。

protected void onStop() {
            SharedPreferences settings3 = getSharedPreferences("MYPREFS", 0);
            SharedPreferences.Editor editor3 = settings3.edit();
            try {
                editor3.putString("CBSTATES", ObjectSerializer.serialize(check_states));
            } catch (IOException e) {
                e.printStackTrace();
            }
            editor3.commit();
        }

为了从我的实际可扩展适配器中获取arraylist,我将它实例化为静态变量并进行转换。在我的espandablelistadpater类中 - &gt;

//  set checkbox states
    static ArrayList<ArrayList<Integer>> check_states = new ArrayList<ArrayList<Integer>>();
    public void setChildrenAndValues() {
        //initialize the states to all 0;
        for(int i = 0; i < children.length; i++) {
            ArrayList<Integer> tmp = new ArrayList<Integer>();
            for(int j = 0; j < children[i].length; j++) {
                tmp.add(0);
            }
            check_states.add(tmp);
        }
    }

这是getChildView

public View getChildView(final int groupPosition, final int childPosition, boolean isLastChild,
            View convertView, ViewGroup parent) {
        LayoutInflater childInflate = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        View childView = childInflate.inflate(R.layout.mtopics_childview, parent, false);

        TextView childtxt = (TextView)childView.findViewById(R.id.mtopicschildtv);
        childtxt.setText(getChild(groupPosition, childPosition).toString());

        //      Load the checkbox states        
        setChildrenAndValues();

        final CheckBox childcb = (CheckBox)childView.findViewById(R.id.mtopicchildchkbox);

        if (check_states.get(groupPosition).get(childPosition) == 1) {
            childcb.setChecked(true);
        }else{ childcb.setChecked(false);
        }

        childcb.setOnClickListener(new OnClickListener() {  
            public void onClick(View v) {
                if (childcb.isChecked()) {
                    check_states.get(groupPosition).set(childPosition, 1);
                }else{ check_states.get(groupPosition).set(childPosition, 0);
                }
            }
        });

        return childView;

我只是想知道我是否正在做好一切,或者如果我错过了一步,我实际上可以感觉到减速,特别是在反序列化时。也许我应该在另一个线程中执行此操作(无论这意味着什么)。我是否以正确的方式使用静态变量导致我在两个方向上改变它们。也许我错过了一个if null语句。

1 个答案:

答案 0 :(得分:0)

ArrayLists具有CAPACITY,您可以在声明/初始化实例时明确设置;如果您未指定容量,则适用默认值。

每当元素数量超出容量时,该容量将被重置。我没有使用过ArrayLists,但假设它们的行为与类似的集合一样,超出容量的结果会导致将容量增加到更大的值,然后为新容量分配空间,然后从“旧”容器中复制所有值存储到新的。

我想,这会减慢您的代码速度:每次增加容量时,都会反复复制大量数据。

验证(和补救):尝试初始化你的arraylists - 使用构造函数作为初始容量的参数 - 使用它们最终将采用的大小,即children.length