首页 > 解决方案 > 为什么按下后退按钮后 Intent Extra NULL?

问题描述

问题

我有一个主要活动“HomeActivity”,它是一个日历。

当您单击一个单元格时,您将进入下一个活动WorkoutButtonsActivity

来自第一个活动的数据被传递到第二个活动中,在该方法中用于锻炼所选单元格的一周日期 (MON - SUN)。

我遇到的问题是,当我从WorkoutButtonsActivity下一个活动 ( ExerciseListViewActivity) 转到菜单栏中的后退按钮时,我传递的意图之一EXTRA_VISIBLE_DATES为空。

但是,当我按下默认的android后退按钮时(在模拟器底部,不会出现此问题。

此外,当我按下我的物理华为设备上的菜单返回按钮时,它工作得非常好。换句话说,我只在我的模拟器中遇到了这个问题。

我收到的错误消息如下:

Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'java.util.List java.util.ArrayList.subList(int, int)' on a null object reference
        at com.example.exerciseappv5.WorkoutButtonsActivity.onCreate(WorkoutButtonsActivity.java:83)

我试过的

我已经对如何避免这种情况进行了一些研究,一些人建议添加:

android:launchMode="singleTop"到我已经完成的清单文件,但是错误仍然存​​在。

我也考虑过覆盖onBackPressed并向后传递意图,但我觉得这是不必要的。

问题

为什么这个特定的意图额外为空,我怎样才能避免错误消息并使代码正常工作?

相关代码

  1. 我在活动 1(日历)中使用的方法导航到活动 2(WorkoutButtonsActivity)
gridView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                AlertDialog.Builder builder = new AlertDialog.Builder(context);
                builder.setCancelable(true);

                final String date = eventDateFormat.format(dates.get(position));
                final ArrayList<String> arrayListDateFormattedList = (ArrayList<String>) datesFormattedList;

                Intent i = new Intent(getContext(), WorkoutButtonsActivity.class);
                i.putExtra(WorkoutButtonsActivity.EXTRA_DATE, date);
                i.putExtra(WorkoutButtonsActivity.EXTRA_VISIBLE_DATES, arrayListDateFormattedList);

                getContext().startActivity(i);
            }
        });
  1. WorkoutButtonsActivity(仅相关代码)
public class WorkoutButtonsActivity extends AppCompatActivity implements View.OnClickListener {


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

                getSupportActionBar().setHomeAsUpIndicator(R.drawable.ic_back);

                Intent intent = getIntent();
                if (intent.hasExtra(EXTRA_DATE)) {
                    SELECTED_DATE = intent.getStringExtra(EXTRA_DATE);
                }

                setTitle(SELECTED_DATE);

                if (intent.hasExtra(EXTRA_VISIBLE_DATES)) {

            EXTRA_VISIBLE_DATESS = intent.getStringArrayListExtra(EXTRA_VISIBLE_DATES);

            if (SELECTED_DATE != null && !SELECTED_DATE.isEmpty()) {
                index_number = EXTRA_VISIBLE_DATESS.indexOf(SELECTED_DATE) + 1;
            }
        }

        //There is no EXTRA_VISIBLE_DATESS
        // we need to get EXTRA_VISIBLE_DATES WORKING HERE...


        if ((index_number / 7) <= 1) {                                 
            thisWeeksDates = EXTRA_VISIBLE_DATESS.subList(0, 7);
        } else if ((index_number / 7) <= 2) {                              // Crash happens here
            thisWeeksDates = EXTRA_VISIBLE_DATESS.subList(7, 14);
        } else if ((index_number / 7) <= 3) {
            thisWeeksDates = EXTRA_VISIBLE_DATESS.subList(14, 21);
        } else if ((index_number / 7) <= 4) {
            thisWeeksDates = EXTRA_VISIBLE_DATESS.subList(21, 28);
        } else if ((index_number / 7) <= 5) {
            thisWeeksDates = EXTRA_VISIBLE_DATESS.subList(28, 35);
        } else {
            thisWeeksDates = EXTRA_VISIBLE_DATESS.subList(35, 42);
        }

       
    @Override
    public void onClick(View v) {

                openExerciseViewActivity();           
        }
    }

    public void openExerciseViewActivity() {
        Intent intent = new Intent(this, ExercisesListViewActivity.class);
        intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
        intent.putExtra(ExercisesListViewActivity.CHOSEN_DATE, SELECTED_DATE);
        intent.putExtra(ExercisesListViewActivity.WORKOUT_ID, buttonClicked);
        intent.putStringArrayListExtra(ExercisesListViewActivity.EXTRA_WEEK_DATES, (ArrayList<String>) thisWeeksDatesCopy);
        startActivity(intent);
    }
}

  1. ExerciseListViewActivity
public class ExercisesListViewActivity extends AppCompatActivity {

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

        getSupportActionBar().setHomeAsUpIndicator(R.drawable.ic_back);

        Intent intent = getIntent();
        Bundle extras = getIntent().getExtras();

        if (extras != null) {
            current_date = extras.getString(CHOSEN_DATE, "TODAY");
            setTitle(current_date);
            THIS_WEEK_DATES = getIntent().getStringArrayListExtra(EXTRA_WEEK_DATES);
        }

        if (intent.hasExtra(WORKOUT_ID)) {
            currentWorkoutID = (intent.getIntExtra(WORKOUT_ID, -1));
        }

        RecyclerView recyclerView = findViewById(R.id.exerciseHistoryRV);
        recyclerView.setLayoutManager(new LinearLayoutManager(this));
        recyclerView.setHasFixedSize(true);

        final ExerciseAndGoalAdapter adapter = new ExerciseAndGoalAdapter();
        recyclerView.setAdapter(adapter);

        junctionViewModel = ViewModelProviders.of(this).get(JunctionViewModel.class);

        junctionViewModel.getAllWorkoutExercises(currentWorkoutID, THIS_WEEK_DATES).observe(this, new Observer<List<ExerciseAndGoal>>() {
            @Override
            public void onChanged(List<ExerciseAndGoal> exercises) {
                adapter.setExercises(exercises);
            }
        });

        adapter.setOnItemClickListener(new ExerciseAndGoalAdapter.OnItemClickListener() {
            @Override
            public void onItemClick(ExerciseAndGoal exercises) {


                Intent intent = new Intent(ExercisesListViewActivity.this, RecordExerciseActivity2.class);
                intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
                intent.putExtra(RecordExerciseActivity2.PARENT_EXERCISE_ID, Integer.toString(exercises.getExercises_id()));
                intent.putExtra(RecordExerciseActivity2.EXTRA_DATE, getTitle());
                intent.putExtra(RecordExerciseActivity2.EXTRA_JUNCTIONID, exercises.getJunction_id());
                intent.putStringArrayListExtra(RecordExerciseActivity2.EXTRA_WEEK_DATES, (ArrayList<String>) THIS_WEEK_DATES);

                startActivityForResult(intent, RECORD_EXERCISE_REQUEST);

            }
        });
    }
}

标签: javaandroidandroid-fragmentsandroid-activityandroid-livedata

解决方案


当您使用导航返回按钮时,模拟器可能会破坏,重新启动 WorkoutButtonsActivity 而没有意图包。尝试使用onSaveInstanceState、onRestoreInstanceState 来保存、恢复bundle。添加此方法:

@Override
public void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);
    outState.putStringArrayListExtra(RecordExerciseActivity2.EXTRA_WEEK_DATES, (ArrayList<String>) THIS_WEEK_DATES);
}

在 onCreate 中,在这一行之后

EXTRA_VISIBLE_DATESS = intent.getStringArrayListExtra(EXTRA_VISIBLE_DATES);

添加:

if(EXTRA_VISIBLE_DATESS == null && savedInstanceState != null){
    EXTRA_VISIBLE_DATESS = savedInstanceState.getStringArrayListExtra(EXTRA_VISIBLE_DATES);
 }

推荐阅读