android ui helper对象保持活动不被GCed

时间:2013-03-22 14:19:49

标签: java android garbage-collection

创建一个带有活动引用的UIHelper类是不是一个坏主意?我试图理解并避免内存泄漏,我读过的最大问题之一就是不能绕过上下文。我有这个UIHelper类,它接受一个活动的引用,并构建/返回TextView和EditView对象到我的活动。我认为这是让我的活动不受GC影响,但我不确定。有没有更合适的方法呢?

这是我的UIHelper类

public class UIHelper {

    private Activity activity;
    private LinearLayout.LayoutParams inputParms = new LinearLayout.LayoutParams(
            LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
    private LinearLayout.LayoutParams labelParms = new LinearLayout.LayoutParams(
            LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
    private LinearLayout.LayoutParams valueParms = new LinearLayout.LayoutParams(
            LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
    private static String[] USStates;

    public UIHelper(Activity activity){
        this.activity = activity;
        this.USStates = activity.getResources().getStringArray(R.array.USStates);

        labelParms.setMargins(5, 5, 0, 0);
        inputParms.setMargins(5, 2, 0, 12);
    }

    public View buildEditView(RecordItem recordItem){
        String type = recordItem.getType();

        if(type.equalsIgnoreCase("text") || type.equalsIgnoreCase("phone") || type.equalsIgnoreCase("integer")){

            EditText vTextInput = new EditText(activity);
            vTextInput.setTextSize(20);
            vTextInput.setLayoutParams(inputParms);

            if (type.equalsIgnoreCase("integer")) {
                vTextInput.setInputType(InputType.TYPE_CLASS_NUMBER);
            } else if (type.equalsIgnoreCase("phone")) {
                vTextInput.setInputType(InputType.TYPE_CLASS_PHONE);
            }

            if (!recordItem.getDisplay()) {
                vTextInput.setVisibility(View.GONE);
            }

            vTextInput.setSingleLine();
            recordItem.setEditView(vTextInput);

            return vTextInput;

        }else if(type.equalsIgnoreCase("USState")){

            Spinner vSpinnerInput = new Spinner(activity);
            ArrayAdapter<String> dataAdapter = new ArrayAdapter<String>(
                    activity,
                    android.R.layout.simple_spinner_item, USStates);
            dataAdapter
                    .setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
            vSpinnerInput.setAdapter(dataAdapter);
            recordItem.setEditView(vSpinnerInput);

            return vSpinnerInput;
        }else if(type.equalsIgnoreCase("keyword")){

            Spinner vSpinnerInput = new Spinner(activity);
            recordItem.setEditView(vSpinnerInput);

            return vSpinnerInput;
        }else if(type.equalsIgnoreCase("recordPicker")){
            TextView textView = new TextView(activity);

            textView.setTextSize(20);
            textView.setGravity(Gravity.LEFT);
            valueParms.topMargin = 17;
            textView.setLayoutParams(valueParms);
            //textView.setBackgroundColor(0xFFC2EAFF);
            textView.setBackgroundColor(0xFFFFFFD0);
            textView.setPadding(15, 7, 0, 7);

            recordItem.setEditView(textView);
            return textView;
        } 

        Log.i("C2_UIHelper", "returned a null editView!");
        return null;
    }

    public TextView buildLabelView(RecordItem recordItem){
        TextView vLabel = new TextView(activity);
        vLabel.setText(recordItem.getLabel());
        vLabel.setTextSize(12);
        vLabel.setLayoutParams(labelParms);
        vLabel.setTextColor(0xFF777777);
        return vLabel;
    }
}

2 个答案:

答案 0 :(得分:0)

您可以这样做,有时它会清理您的代码。重要的是,当调用activity的onDestroy时,需要在helper上调用一个cleanup方法,该方法将保存上下文的变量设置为null,因此不要在两个变量之间保留循环引用。

答案 1 :(得分:0)

只要您只在Activity中保留对UIHelper的引用,就应该没有问题。在这种情况下,它将与活动一起进行GCed。如果您在较长时间停留的地方保留引用,则只会遇到问题,例如:在静态变量,ThreadLocals或Application类和Services中的字段。