마스터Q&A 안드로이드는 안드로이드 개발자들의 질문과 답변을 위한 지식 커뮤니티 사이트입니다. 안드로이드펍에서 운영하고 있습니다. [사용법, 운영진]

액티비티의 전달받은 Intent 오류에 관한 질문

0 추천

SettingActivity는 최대값,최소값을 적는 액티비티이고, MainActivity는 SettingActivity로부터 최소값과 최대값을

받아와 그 사이의 숫자중 랜덤한 숫자 하나를 뽑는 액티비티입니다.

<SettingActivity>의 MainActivity로 넘어가는 버튼button_pick2를 눌렀을 때 코드

button_pick2.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View view) {
        int number_max = Integer.parseInt(textView_number_max.getText().toString());
        int number_min = Integer.parseInt(textView_number_min.getText().toString());
        //number_max는 textView_number_max라는 텍스트뷰에 적은 최대값, number_min는 textView_number_min라는 텍스트뷰에 적은 최소값
        Intent intent = new Intent(getApplicationContext(), MainActivity.class);
        intent.putExtra("number_max", number_max);
        intent.putExtra("number_min", number_min);
        intent.putExtra("number_before",1);
        //number_before은 그전에 최소값,최대값을 지정한 적이 있는지 MainActivity에서 확인을 하기 위한 if를 사용할 때 쓰는 임의의 값
            startActivity(intent);
        finish();
    }
});

 

<MainActivity>의 숫자뽑기 버튼button_pick를 눌렀을 때 코드

button_pick.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View view) {
        Intent intent = getIntent();
        if(intent != null){
            number_before = getIntent().getExtras().getInt("number_before");
        }
//SettingActivity에서 최대값,최소값을 지정했는지 유무를 파악하기 위한 임의의 값 number_before를 가져옴
        Random random = new Random();
        if(number_before == 1) {
            int number_max = getIntent().getExtras().getInt("number_max");
            int number_min = getIntent().getExtras().getInt("number_min");
            int randomNum = random.nextInt(number_max-number_min+1)+number_min;
            textView_number.setText(String.valueOf(randomNum));

//number_before가 1이면 최소값,최대값을 SettingActivity에서 지정한 것이기 때문에 내가 설정한 최대,최소값으로 랜덤한 숫자를 textView_number에 출력함

        }else{
            int number_max = 100;
            int number_min = 0;
            int randomNum = random.nextInt(100-0+1)+0;
            textView_number.setText(String.valueOf(randomNum));
        }

//그외 상황일때 SettingActivity에서 최대,최소값을 지정한 것이 아니기 때문에 그냥 기본적으로 최대값100, 최소값0으로 설정되도록 한다.

    }
});

button_setting.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View view) {
        Intent intent = new Intent(getApplicationContext(), SettingActivity.class);
        startActivity(intent);
        finish();
    }
});
//button_setting 버튼은 SettingActivity로 넘어가는 버튼

 

이렇게 코드가 짜여진 상황에서 MainActivity에서 SettingActivity로 넘어가 최대, 최소값을 설정하지 않고

바로 button_pick 버튼을 누르게 되면 SettingActivity에서 넘겨받은 intent가 없는데도 불구하고

 

int number_before = getIntent().getExtras().getInt("number_before")가

'int android.os.Bundle.getInt(java.lang.String)' on a null object reference이렇게 오류가 남게 됩니다.

 

if문으로 전달받은 intent가 없으면 그냥 넘기고 오류가 안나야하는거 아닌가요?

어떻게 수정해야할지 알려주세요...

 

쿠롱 (400 포인트) 님이 2022년 10월 6일 질문

1개의 답변

0 추천

intent의 null값 체크를 부분적으로 하셔서 그렇습니다.

button_pick.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View view) {
        Intent intent = getIntent();
        if(intent != null){
            ..
        }

        // 여기에서 getIntent()를 하게 되면 null 일 경우 에러가 남. 위에서는 intent가 null인지만 체크할 뿐 다른 처리를 하고 있지 않음
       ...
           

    }
});

 

아래처럼 null 값 체크를 해서 null이면 더 이상 로직을 진행하지 않는 early return으로 바꿔보세요.

button_pick.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View view) {
        Intent intent = getIntent();
        if(intent == null) return; // early return

        number_before = getIntent().getExtras().getInt("number_before");
         ...

    }
});

 

버튼 클릭시 랜덤넘버를 무조건 생성해야 한다면, intent에 값이 없을 때 기본값을 주세요.

Intent intent = getIntent();
//boolean isByUser = intent != null && intent.getInt("number_before") == 1;
int minValue = intent == null ? 0 : intent.getInt("number_min");
int maxValue = intent == null ? 100 : intent.getInt("number_max");

int randomNum = random.nextInt(maxValue - minValue + 1) + minValue;
textView_number.setText(String.valueOf(randomNum));

 

spark (227,830 포인트) 님이 2022년 10월 6일 답변
spark님이 2022년 10월 6일 수정
참고로 Intent에 값을 넘길 때는 여러개의 원시필드를 넘기지 마시고 class 를 하나 만들어서 넘기세요.

public class RangeSettings implements Serializable {
     private final int min;
     private final int max;
     private final boolean byUser;

     private Random random = new Random();
     
     private RangeSettings(int min, int max, boolean byUser) {
         this.min = min;
         this.max = max;
         this.byUser = byUser;
     }

     public static RangeSettings byUser(int min, int max) {
          return new RangeSettings(min, max, true);
     }

    //getter 생략

    public int getRandomNumber() {
        if (byUser) return random.nextInt(max - min + 1) + min;
        return random.nextInt(100 +1);
    }
}

public static final String RANGE_SETTINGS_KEY = "rangeSettings";

// Write
RangeSettings rangeSettings = RangeSettings.byUser(number_min, number_max);
intent.putExtra(RANGE_SETTINGS_KEY,  rangeSettings);

// Read
RangeSettings rangeSettings = (RangeSettings) getIntent().getSerializable(RANGE_SETTINGS_KEY);
if (rangeSettings != null) {
    ...
}
...