简体   繁体   English

android ui helper对象防止活动被GC

[英]android ui helper object keeping activities from being GCed

Is it a bad idea to create a UIHelper class that takes an activity reference? 创建一个带有活动引用的UIHelper类是一个坏主意吗? I'm trying to understand and avoid memory leaks and one of the biggest problems I've read is to not pass around contexts. 我正在尝试理解并避免内存泄漏,而我读过的最大问题之一是不要传递上下文。 I have this UIHelper class that takes a reference to an activity and builds/returns TextView and EditView objects to my activity. 我有这个UIHelper类,该类对活动进行引用,并为我的活动构建/返回TextView和EditView对象。 I'm thinking this is keeping my activities from being GC'ed but i'm not sure. 我以为这可以防止我的活动被垃圾收集,但我不确定。 Is there a more appropriate way of doing this? 有更合适的方法吗?

Here is my UIHelper class 这是我的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;
    }
}

You can do this, and sometimes it cleans up your code. 您可以执行此操作,有时它可以清理您的代码。 The important thing is that when the activity's onDestroy is called, you need to call a cleanup method on the helper that sets the variable holding the context to null, so you don't keep a circular reference between the two variables. 重要的是,当调用活动的onDestroy时,您需要在帮助程序上调用清除方法,该方法会将保存上下文的变量设置为null,因此您不必在两个变量之间保持循环引用。

As long as you only keep a reference to your UIHelper inside the Activity, there should be no problem. 只要您仅在Activity中保留对UIHelper的引用,就不会有问题。 In that case it will be GCed together with the Activity. 在这种情况下,它将与活动一起被GC。 You only run into problems if you keep references around in places that hang around longer, eg in static variables, ThreadLocals or fields in your Application class and Services. 如果将引用保留在较长的位置,例如静态变量,ThreadLocals或Application类和Services中的字段,则只会遇到问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM