[안드로이드] startActivityForResult ,onActivityResult 사용법



안드로이드 개발을 진행하다 보면 단순히 액티비티를 전환하고 끝! 이 아니라

후속 액티비티에서 작업한 결과물을

호출한 액티비티에서 사용하고 싶은 경우가 왕왕 있습니다.


예를 들자면 회원가입을 진행할 때 ,

회원가입 액티비티에서 다이얼로그를 띄우고

다이얼로그에서 주소를 입력하게 하고, 완료 버튼을 누르면 다시 액티비티로 가져오는 경우나,

(이 경우는 CallBack 으로도 가능합니다.)


자신의 앱에서 카메라 앱을 호출하고 그 결과를 다시 자신의 앱으로 가져오는 경우가 있습니다.

이러한 경우 사용하는 방법이 startActivityForResult 입니다.


startActivityForResult

위 사진처럼

  1. Activity A 에서 B 를 호출

  2. Activity B 에서 작업 처리.

  3. 처리된 작업 결과 값을 Activity A 로 반환.

같은 프로세스로 진행됩니다.


이러한 방식으로 결과를 수신하기 위해 액티비티를 사용할 때는

startActivityForResult() 메소드에 추가로 “요청 코드” 를 전달해야 합니다.

요청 코드를 통해서 결과 값을 반환 받을 때, 내가 요청한 결과를 식별하여 처리할 수 있습니다.


그럼 직접 예제 앱을 만들어보겠습니다.

예제 앱은 간단한 계산기 어플리케이션으로

한 Activity 에서 더하기나 빼기를 선택하고 다음 액티비티에서 연산을 한 후 결과를 리턴 받는 앱입니다.



1. Result

forResult Screenshot

  1. MainActivity 에서 CalculateActivity 를 호출합니다.

  2. CalculateActivity 에서 연산한 결과를 MainActivity 로 반환합니다.

  3. MainActivity 에서 반환 받은 결과 값을 TextView 에 표시합니다.



2. Step by Step

2-1. MainActivity

  • 메인 액티비티에선 더하기 버튼과 빼기 버튼을 눌러 CalculateActivity 로 이동합니다.

여기에서 CalculateActivity 를 시작할 때 일반적으로 startActivity(Intent) 메소드를 호출한 것이 아니라,

결과 값을 리턴받길 원하기 때문에 startActivityForResult(calIntent,3000); 메소드를 호출한 것을 알 수 있습니다.

startActivityForResult 메소드는 전달할 인텐트와 requestCode (여기에선 3000, 아무 값이나 상관 없습니다. ) 를 같이 보내주는데 아래 나오는 onActivityResult 에서 요청한 코드를 구분하기 위해 넘겨줍니다.


  • 다음으로 주의깊게 봐야할 점은 onActivityResult 메소드 입니다. 저 메소드에선 CalculateActivity 에서 계산된 값이 넘어오면 호출 됩니다.

onActivityResult 에서 requestCode 는 CalculateActivity 를 호출하는 액티비티가 여러개 있을 경우 구분하기 위해 사용합니다. MainActivity 에선 정수 3000 을 사용했습니다.

처리 결과가 RESULT_OK 라면 텍스트 뷰에 결과를 보이게 하는 간단한 코드입니다.


/**
 * Created by charlie on 2018. 2. 8
 * startActivityForResult 를 학습하기 위한 Test Application
 *
 * MainActivity 에서 더하기 혹은 빼기를 선택하면 CalculateActivity 에서 연산할 숫자를 입력하고 결과를 리턴한다.
 * 리턴된 결과는 MainActivity 에 표시된다.
 */

public class MainActivity extends AppCompatActivity implements View.OnClickListener{

    private TextView mainResultTv;

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

        // find view 
        ImageView mainPlusIv = findViewById(R.id.mainPlusIv);
        ImageView mainMinusIv = findViewById(R.id.mainMinusIv);
        mainResultTv = findViewById(R.id.mainResultTv);

        // 더하기, 빼기 ClickListener 설정
        // Override 된 onClick 메소드에서 클릭 처리.
        mainPlusIv.setOnClickListener(this);
        mainMinusIv.setOnClickListener(this);

    }

    // 더하기나 빼기를 할 때 CalculateActivity 에서 연산의 구분을 두기 위해 인텐트로 Flag 를 넘겨줍니다.
    @Override
    public void onClick(View v) {
        Intent calIntent = new Intent(this, CalculateActivity.class);
        switch (v.getId()){
            case R.id.mainPlusIv:
                calIntent.putExtra("isPlus",true);
                break;
            case R.id.mainMinusIv:
                calIntent.putExtra("isPlus",false);
                break;
        }
        startActivityForResult(calIntent,3000);
    }


    // CalculateActivity 에서 처리된 결과를 받는 메소드
    // 처리된 결과 코드 (resultCode) 가 RESULT_OK 이면 requestCode 를 판별해 결과 처리를 진행한다.
    // CalculateActivity 에서 처리 결과가 담겨온 데이터를 TextView 에 보여준다.
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        if(resultCode == RESULT_OK){
            switch (requestCode){
                // MainActivity 에서 요청할 때 보낸 요청 코드 (3000)
                case 3000:
                    mainResultTv.setText(data.getStringExtra("result"));
                    break;
            }
        }
    }
}


2-2. CalculateActivity

  • CalculateActivity 에선 MainActivity 에서 선택한 어떤 연산을 선택 했는지 인텐트를 통해 전달 받습니다. ( 더하기 혹은 빼기 )

  • 전달 받은 뒤 사용자에게 입력받은 두 개의 숫자를 연산하고, 연산한 결과 값을 MainActivity 에게 전달합니다.

여기에서 주의깊게 봐야할 코드는 setResult(RESULT_OK,resultIntent) 부분 입니다.

setResult 함수를 호출하면 현재 액티비티를 startActivityForResult 로 실행한 호출 액티비티에게 결과 값을 전달하게 됩니다.

여기에서 RESULT_OK 를 결과 상태로 알려줘서 연산이 정상적으로 완료 되었다는 것을 전달해줍니다.

/**
 * Created by charlie on 2018. 2. 8
 *
 * EditText 에 입력한 두 정수를 MainActivity 에서 선택한 더하기 혹은 빼기 연산합니다.
 * 연산이 완료되면 CalculateActivity 를 종료하고 MainActivity 로 결과 값을 되돌려 줍니다.
 */

public class CalculateActivity extends AppCompatActivity {

    private EditText num1;
    private EditText num2;

    // MainActivity 에서 선택한 연산이 더하기 연산인지 빼기 연산인지 구분하기 위한 변수
    // 더하기라면 true 를 빼기라면 false 를 전달 받음.
    private boolean isPlus;
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_calculator);

        // MainActivity 에서 선택한 연산이 어떤 것인지 확인 (더하기 , 빼기)
        isPlus = getIntent().getBooleanExtra("isPlus",false);

        // 숫자 입력하는 EditText 와 연산하는 버튼 뷰 설정
        num1 = findViewById(R.id.calNum1Et);
        num2 = findViewById(R.id.calNum2Et);

        // 두 숫연산을 실행하고 MainActivity 로 결과를 리턴함.
        // 1. 숫자 값 둘 중 하나가 없다면 토스트 메시지를 띄우고 아니라면 연산을 실행함
        // 2. 인텐트로 넘겨받은 isPlus 의 값의 따라 더하기,빼기 연산을 함.
        // 3. 연산한 결과 값을 resultIntent 에 담아서 MainActivity 로 전달하고 현재 Activity 는 종료.
        Button calBtn = findViewById(R.id.calBtn);
        calBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                // 1. 숫자 값 둘 중 하나가 없다면 토스트 메시지를 띄우고 아니라면 연산을 실행함
                if(num1.getText() == null || num2.getText() == null){
                    Toast.makeText(CalculateActivity.this,"연산할 값이 없습니다. 확인해주세요.",Toast.LENGTH_SHORT).show();
                }else{
                    int n1 = Integer.parseInt(num1.getText().toString());
                    int n2 = Integer.parseInt(num2.getText().toString());
                    int result;

                    // 2. 인텐트로 넘겨받은 isPlus 의 값의 따라 더하기,빼기 연산을 함.
                    if(isPlus){
                        result = n1 + n2;
                    }else{
                        result = n1 - n2;
                    }

                    // 3. 연산한 결과 값을 resultIntent 에 담아서 MainActivity 로 전달하고 현재 Activity 는 종료.
                    Intent resultIntent = new Intent();
                    resultIntent.putExtra("result","연산 결과는 "+result+" 입니다.");
                    setResult(RESULT_OK,resultIntent);
                    finish();
                }
            }
        });
    }
}

이상으로 startActivityForResultonActivityResult 사용법을 알아보았습니다.

가장 기본인 Intent 사용만 잘 해도 어플리케이션 구현이 가능합니다!!

다들 개발 공부 화이팅 하세요!!



3. Source Code

전체 소스 코드는 GitHub 에 공유했습니다.