У меня есть собственный класс для динамического создания просмотра с помощью моего метода generate () , но когда я вызываю метод fini sh () в своей деятельности g c не работает, а память до 10 МБ для каждого вызова активности (с использованием проверки в Profiler), мне нужно исправить это с помощью ручного удаления представления из памяти с помощью g c , я знаю g c делать это, когда у меня нет сильной ссылки на мои представления, и я следовал этим правилам и сохранял все свои представления в коллекцию как WeakHashMap но g c не освобождает для моих представлений:
public class CustomQuestionAdapter {
public ArrayList<Question> items;
private Context mActivity;
private boolean isDisabled = false;
private String TAG = "CUSTOM_QUESTION_ADAPTER";
private OnProgressViewChanged onProgressViewChanged;
private WeakHashMap<String, View> boxReferences = new WeakHashMap<>();
private SparseArray<EditTextPlus> textViewsReferences = new SparseArray<>();
public CustomQuestionAdapter(Context context) {
this.mActivity = context;
}
public void setItems(ArrayList<Question> items) {
this.items = items;
}
public void generate(int index) {
int total = items.size();
generateBoxes(index);
this.onProgressViewChanged.onChanged((int) ((index * 1.0 / total) * 100));
if ( index < total - 1){
this.onProgressViewChanged.onFinish(boxReferences.get(items.get(index).getQId().toString()), false);
}else{
this.onProgressViewChanged.onChanged(100);
this.onProgressViewChanged.onFinish(boxReferences.get(items.get(index).getQId().toString()), true);
}
}
public void removeAllView(ViewGroup v){
for (View view: boxReferences.values()){
try{
view.setVisibility(View.VISIBLE);
((ViewGroup) view).removeAllViews();
Log.d(TAG, "removeAllView: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ removed ");
}catch (Exception e){
Log.d(TAG, "removeAllView: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ occured error" );
}
}
if (v != null){
v.removeAllViews();
}
boxReferences = null;
textViewsReferences = null;
items.clear();
}
public void setDisabled(boolean isDisabled) {
this.isDisabled = isDisabled;
}
@Nullable
private View generateBoxes(final int position) {
final Question item = items.get(position);
final HashMap<String, String> options = item.getOptionsHashMap();
item.setQText(String.format("(%d) %s", position + 1, item.getQText()));
if (item.getQType().equals("Text")) {
// final View layoutView = LayoutInflater.from(mActivity).inflate(R.layout.adapter_question_text, null, false);
View layoutView = LayoutInflater.from(mActivity).inflate(R.layout.adapter_question_text, null, false);
try {
((TextViewPlus) layoutView.findViewById(R.id.question)).setText(String.format("%s%s", item.getQText(), Boolean.valueOf(options.get("required")) ? " (الزامی)" : ""));
} catch (Exception e) {
e.printStackTrace();
}
EditTextPlus answerText = layoutView.findViewById(R.id.answer);
textViewsReferences.put(position, answerText);
answerText.setText(item.getAnswer());
if (isDisabled)
answerText.setEnabled(false);
layoutView.setVisibility(item.getShouldHide() ? View.GONE : View.VISIBLE);
boxReferences.put(item.getQId().toString(), layoutView);
return layoutView;
} else if (item.getQType().equals("Checkbox")) {
View layoutView = LayoutInflater.from(mActivity).inflate(R.layout.adapter_question_radio, null, false);
LinearLayout optionsLayout = layoutView.findViewById(R.id.options);
try {
((TextViewPlus) layoutView.findViewById(R.id.question)).setText(String.format("%s%s", item.getQText(), Boolean.valueOf(options.get("required")) ? " (الزامی)" : ""));
} catch (Exception e) {
e.printStackTrace();
}
// new Thread(new Runnable() {
// @Override
// public void run() {
optionsLayout.removeAllViews();
final List<CheckBox> checkBoxes = new ArrayList<>();
for (int i = 0; i < item.getFields().size(); i++) {
Field field = item.getFields().get(i);
View view = LayoutInflater.from(mActivity).inflate(R.layout.template_checkbox, null);
CheckBox checkBox = view.findViewById(R.id.radio);
TextViewPlus titleText = view.findViewById(R.id.title);
if (isDisabled)
checkBox.setEnabled(false);
checkBox.setChecked(item.getAnswer().contains(field.getName() + "|"));
checkBox.setTag(field.getName());
titleText.setText(field.getTitle());
optionsLayout.addView(view);
checkBoxes.add(checkBox);
checkBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
StringBuilder answer = new StringBuilder();
for (CheckBox checkBox1 : checkBoxes) {
if (checkBox1.isChecked()) {
answer.append(checkBox1.getTag()).append("|");
}
}
// answers.set(position, answer);
item.setAnswer(answer.toString());
}
});
}
// }
// }).start();
boxReferences.put(item.getQId().toString(), layoutView);
layoutView.setVisibility(item.getShouldHide() ? View.GONE : View.VISIBLE);
return layoutView;
} else if (item.getQType().equals("Input")) {
View layoutView = LayoutInflater.from(mActivity).inflate(R.layout.adapter_question_input, null, false);
try {
((TextViewPlus) layoutView.findViewById(R.id.question)).setText(String.format("%s%s", item.getQText(), Boolean.valueOf(options.get("required")) ? " (الزامی)" : ""));
EditTextPlus answerText = layoutView.findViewById(R.id.answer);
switch (options.get("type")) {
case "text": {
answerText.setInputType(InputType.TYPE_CLASS_TEXT);
break;
}
case "number": {
answerText.setInputType(InputType.TYPE_NUMBER_FLAG_DECIMAL);
break;
}
case "date": {
answerText.setInputType(InputType.TYPE_CLASS_DATETIME);
break;
}
}
textViewsReferences.put(position, answerText);
answerText.setText(item.getAnswer());
if (isDisabled)
answerText.setEnabled(false);
} catch (Exception e) {
e.printStackTrace();
}
boxReferences.put(item.getQId().toString(), layoutView);
layoutView.setVisibility(item.getShouldHide() ? View.GONE : View.VISIBLE);
return layoutView;
} else if (item.getQType().equals("Radio Button")) {
View layoutView = LayoutInflater.from(mActivity).inflate(R.layout.adapter_question_radio_with_group, null, false);
LinearLayout textGroup = layoutView.findViewById(R.id.textGroup);
RadioGroup radioGroup = layoutView.findViewById(R.id.radioGroup);
try {
((TextViewPlus) layoutView.findViewById(R.id.question)).setText(String.format("%s%s", item.getQText(), Boolean.valueOf(options.get("required")) ? " (الزامی)" : ""));
} catch (Exception e) {
e.printStackTrace();
}
textGroup.removeAllViews();
radioGroup.removeAllViews();
for (int i = 0; i < item.getFields().size(); i++) {
final Field field = item.getFields().get(i);
final RadioButton radioButton = new RadioButton(mActivity);
radioButton.setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, 70));
radioButton.setGravity(Gravity.CENTER);
radioButton.setChecked(false);
radioButton.setId(View.generateViewId());
TextViewPlus titleText = new TextViewPlus(mActivity) {{
setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, 70) {{
rightMargin = 10;
}});
setEllipsize(TextUtils.TruncateAt.MARQUEE);
setFont(mActivity, "fonts/IRANYekanWebLight.ttf");
setTextSize(Dimension.SP, 14f);
setGravity(Gravity.CENTER | Gravity.RIGHT);
setTextColor(mActivity.getResources().getColor(R.color.gray));
}};
radioButton.setChecked(item.getAnswer().equals(field.getName()));
radioButton.setTag(field.getName());
if (isDisabled) {
radioButton.setEnabled(false);
}
titleText.setText(field.getTitle());
textGroup.addView(titleText);
radioGroup.addView(radioButton);
radioButton.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
if (b) {
item.setAnswer(field.getName());
// items.set(position, item);
}
//
}
});
}
if (isDisabled) {
radioGroup.setEnabled(false);
}
// }
// }).start();
boxReferences.put(item.getQId().toString(), layoutView);
layoutView.setVisibility(item.getShouldHide() ? View.GONE : View.VISIBLE);
return layoutView;
} else if (item.getQType().equals("OPTCheckbox")) {
View layoutView = LayoutInflater.from(mActivity).inflate(R.layout.adapter_question_radio, null, false);
LinearLayout optionsLayout = layoutView.findViewById(R.id.options);
// new Thread(new Runnable() {
// @Override
// public void run() {
try {
((TextViewPlus) layoutView.findViewById(R.id.question)).setText(String.format("%s%s", item.getQText(), Boolean.valueOf(options.get("required")) ? " (الزامی)" : ""));
} catch (Exception e) {
e.printStackTrace();
}
optionsLayout.removeAllViews();
Field field = item.getFields().get(0);
View view = LayoutInflater.from(mActivity).inflate(R.layout.template_checkbox, null);
final CheckBox checkBox = view.findViewById(R.id.radio);
TextViewPlus titleText = view.findViewById(R.id.title);
if (isDisabled)
checkBox.setEnabled(false);
Log.e("~~~~~~~", item.getAnswer());
if (item.getAnswer().contains(field.getName() + "|")) {
checkBox.setChecked(true);
} else {
checkBox.setChecked(false);
}
checkBox.setTag(field.getName());
checkBox.setId((int) 123);
titleText.setText(field.getTitle());
optionsLayout.addView(view);
checkBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
item.setAnswer(b ? checkBox.getTag() + "|" : "");
// items.set(position, item);
try {
JSONArray toToggleItems = new JSONArray(item.getOptionsHashMap().get("hidden_ls"));
for (int i = 0; i < toToggleItems.length(); i++) {
for (int j = 0; j < items.size(); j++) {
if (items.get(j).getQId().toString().equals(toToggleItems.getString(i))) {
items.get(j).setShouldHide(!b);
try {
boxReferences.get(items.get(j).getQId().toString()).setVisibility(!b ? View.GONE : View.VISIBLE);
} catch (Exception ignored) {
}
if (!b && items.get(j).getOptionsHashMap().containsKey("hidden_ls")) {
try {
((CheckBox) boxReferences.get(items.get(j).getQId().toString()).findViewById((int) 123)).setChecked(false);
} catch (Exception ignored) {
}
}
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
});
// }
// }).start();
boxReferences.put(item.getQId().toString(), layoutView);
layoutView.setVisibility(item.getShouldHide() ? View.GONE : View.VISIBLE);
return layoutView;
}
return null;
}
public void prepareItemsForValidation(int position) {
try {
items.get(position).setAnswer(textViewsReferences.get(position).getText().toString());
} catch (Exception ignored) {
}
}
public int getItemViewType(int position) {
final Question item = items.get(position);
// Log.e(TAG, "type:"+item.type);
switch (item.getQType()) {
case "Text":
return VIEW_TYPE_TEXT;
case "Checkbox":
return VIEW_TYPE_CHECKBOX;
case "Input":
return VIEW_TYPE_INPUT;
case "Radio Button":
return VIEW_TYPE_RADIO;
case "OPTCheckbox":
return VIEW_TYPE_OPTCHECKBOX;
}
return VIEW_TYPE_TEXT;
// return super.getItemViewType(position);
}
public void setOnProgressViewChanged(OnProgressViewChanged onProgressViewChanged) {
this.onProgressViewChanged = onProgressViewChanged;
}
public interface OnProgressViewChanged {
void onChanged(int progress);
void onFinish(View view, Boolean lastIndex);
}
}
Даже во время активности я вызвал метод removeAll () в методе destroy ():
@Override
protected void onDestroy() {
adapter.removeAllView(insideContainer);
System.gc();
super.onDestroy();
}