android SaveInstance в действии и сборщик мусора - PullRequest
0 голосов
/ 26 декабря 2018

В настоящее время я работаю над второй версией моего словарного приложения.Первая версия не предоставляет столько документации для расширения приложения.поэтому я решил начать с нуля.

У меня есть действие, каждый раз, когда я отправляю его в фоновый режим, а затем возвращаю обратно на передний план, некоторые объекты становятся нулевыми, и действие перезапускается.В onResume я записал значение нулевого объекта.

Старая активность (версия 1) не имеет этой проблемы.

Я пытался избежать этой нулевой проблемы, сохраняя состояния действий и объекты вSaveInstanceState и восстановить их.но RestoreInstance никогда не вызывался.

вот мой код

 @Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_query);


    Log.e(TAG, "onCreate");

    /* Initialize DATA */
    data = new DataHandler(this);


    /* Initialize VIEWS */
    btnPhase  = findViewById(R.id.query_voc_phase);
    cardPath  = findViewById(R.id.query_voc_path);
    queryView = findViewById(R.id.query_view);
    btnShow   = findViewById(R.id.query_btn_show_answer);
    btnRight  = findViewById(R.id.query_btn_mark_right);
    btnWrong  = findViewById(R.id.query_btn_mark_wrong);
    btnNext   = findViewById(R.id.query_btn_show_next);
}

@Override
protected void onStart() {
    super.onStart();

    Log.e(TAG, "onStart");
    /* set OnClickListener */
    btnShow.setOnClickListener(this);
    btnRight.setOnClickListener(this);
    btnWrong.setOnClickListener(this);
    btnNext.setOnClickListener(this);


    //init Variables
    queryList       = new ArrayList<>();
    idList           = new ArrayList<>();
    listGroupings   = new ArrayList<>();
    answeredList    = new ArrayList<>();


    //init Preferences
    preferences = PreferenceManager.getDefaultSharedPreferences(this);

    //set Visibility of view items based on Preferences
    if (!preferences.getBoolean(Preferences.SHOW_CARD_PATH_ENABLED, true))
        cardPath.setVisibility(View.GONE);

    //load preferences
    userID = preferences.getInt(Preferences.CURRENT_USER, -1);

    //check if flashing card is enabled and get time
    flash_time = preferences.getBoolean(Preferences.FLASH_CARD_ENABLED, false) ? preferences.getInt(Preferences.FLASH_TIME, flash_time) : -1;


    //get data from intent
    Intent intent = getIntent();
    if (intent.hasExtra(QUERY_CONTAINER_LIST)) {
        //get data into the list
        HashMap<String, ArrayList<Integer>> queryData = data.getCardsToQuery(intent.getStringArrayListExtra(QUERY_CONTAINER_LIST));

        idList = queryData.get("iList");
        listGroupings = queryData.get("listGroupings");
    }


    // change active Fragment to initial fragment
    changeFragment(QueryViews.Simple);
}

@Override
protected void onResume() {
    super.onResume();

    Log.e(TAG, "onResume");
    Log.e(TAG, "current card is null " + (currentCard == null));

    //loads a new card if there is none
    if(currentCard == null) loadNext();
}

/*
    InstanceState
 */

@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
    super.onRestoreInstanceState(savedInstanceState);

    Log.e(TAG, "RESTORE");

    queryList = savedInstanceState.getParcelableArrayList("queryList");
    idList = savedInstanceState.getIntegerArrayList("iList");
    listGroupings = savedInstanceState.getIntegerArrayList("listGroupings");
    answeredList = savedInstanceState.getParcelableArrayList("answeredList");

    currentCard = (VocabularyCard)savedInstanceState.getSerializable("currentCard");
    lastCard =  (VocabularyCard)savedInstanceState.getSerializable("lastCard");
}

@Override
protected void onSaveInstanceState(Bundle outState) {
    Log.e(TAG, "SAVE");

    outState.putParcelableArrayList("queryList", queryList);
    outState.putIntegerArrayList("idList", idList);
    outState.putIntegerArrayList("listGroupings", listGroupings);
    outState.putParcelableArrayList("answeredList", answeredList);

    outState.putParcelable("currentCard", currentCard);
    outState.putParcelable("lastCard", lastCard);

    super.onSaveInstanceState(outState);
}

Ответы [ 2 ]

0 голосов
/ 26 декабря 2018

Я нашел решение.Я узнал, что onRestoreInstanceState будет вызываться, если устройство вращается.Прежде всего, если что-то стало нулевым, вы должны сначала проверить, было ли объекту присвоено значение.в этом случае я упустил из виду, что объекту никогда не присваивалось значение.

0 голосов
/ 26 декабря 2018

Обнаружение ошибки ниже, может быть, это ошибка опечатки, но может быть причиной вашей проблемы с нулевым объектом.Вы восстанавливаете iList внутри onRestoreInstanceState,

@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
    super.onRestoreInstanceState(savedInstanceState);

    Log.e(TAG, "RESTORE");

    idList = savedInstanceState.getIntegerArrayList("iList");

}

Но внутри onSaveInstanceState вы кладете idList,

@Override
protected void onSaveInstanceState(Bundle outState) {
    Log.e(TAG, "SAVE");

    ...
    outState.putIntegerArrayList("idList", idList);
    ...

    super.onSaveInstanceState(outState);
}
...