【问题标题】:Why is Intent Extra NULL after back button pressed?为什么按下后退按钮后 Intent Extra NULL?
【发布时间】:2020-07-17 19:30:24
【问题描述】:

问题

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

当你点击一个单元格时,你会被带到下一个活动WorkoutButtonsActivity

第一个活动的数据被传递到第二个活动中,用于计算所选单元格的一周(周一 - 周日)日期。

我遇到的问题是,当我从 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 并将意图向后传递,但我觉得这是不必要的。

问题

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

相关代码

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

            }
        });
    }
}

【问题讨论】:

    标签: java android android-fragments android-activity android-livedata


    【解决方案1】:

    尝试使用 putStringArrayListExtra() 而不是 putExtra()

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

    【讨论】:

    • 执行这个后问题依旧。
    【解决方案2】:

    当您使用导航返回按钮时,模拟器可能会破坏,重新启动 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);
     }
    

    【讨论】:

    • 如何在我的场景中执行此操作?我在网上看过,我不确定如何正确实施。
    猜你喜欢
    • 1970-01-01
    • 2023-01-03
    • 2016-05-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-03
    • 1970-01-01
    相关资源
    最近更新 更多