【问题标题】:android SaveInstance in activity and garbage collectorandroid 在活动和垃圾收集器中保存实例
【发布时间】:2018-12-25 21:19:55
【问题描述】:

目前我正在开发我的词汇应用程序的第二个版本。第一个版本没有提供太多的文档来扩展应用程序。所以我决定从头开始。

我有一个活动,每次我将它发送到后台然后将其返回到前台时,一些对象变为空并且活动重新启动。在 onResume 中,我记录了 null 对象的值。

旧的活动(版本 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);
}

【问题讨论】:

    标签: java android android-activity garbage-collection


    【解决方案1】:

    发现以下错误,可能是拼写错误,但可能是您的空对象问题的罪魁祸首。你在onRestoreInstanceState里面恢复iList,

    @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);
    }
    

    【讨论】:

    • iList 只是一个拼写错误。我试图重命名 iList。重构不起作用,必须手动重命名。我错过了。添加 saveinstancestate 之前出现 null 问题
    【解决方案2】:

    我找到了解决方案。我发现如果设备旋转,就会调用 onRestoreInstanceState。首先,如果某些内容变为空,您应该首先检查该对象是否被分配了一个值。在这种情况下,我忽略了该对象从未被赋值。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-01-10
      • 1970-01-01
      • 1970-01-01
      • 2013-08-24
      • 2012-12-19
      • 2011-06-19
      • 1970-01-01
      相关资源
      最近更新 更多