0

アクティビティ参照を取る UIHelper クラスを作成するのは悪い考えですか? 私はメモリ リークを理解し、回避しようとしています。私が読んだ最大の問題の 1 つは、コンテキストを渡さないことです。アクティビティへの参照を取得し、TextView および EditView オブジェクトをアクティビティにビルド/返すこの UIHelper クラスがあります。これにより、私のアクティビティが 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;
    }
}
4

2 に答える 2

0

これを行うことができ、場合によってはコードがクリーンアップされます。重要なことは、アクティビティの onDestroy が呼び出されたときに、コンテキストを保持する変数を null に設定するヘルパーでクリーンアップ メソッドを呼び出す必要があるため、2 つの変数の間で循環参照を保持しないことです。

于 2013-03-22T14:26:32.133 に答える
0

アクティビティ内で UIHelper への参照のみを保持している限り、問題はありません。その場合、Activity と一緒に GCed されます。静的変数、ThreadLocals、または Application クラスとサービスのフィールドなど、参照が長く続く場所に参照を保持している場合にのみ、問題が発生します。

于 2013-03-22T14:26:46.633 に答える