startActivity가 안돼요

startActivity 메소드(startActivityForResult 메소드 포함)는 파라미터로 전달된 인텐트(Intent) 정보로 액티비티를 실행한다. 안드로이드 책 처음마다 이 메소드 소개는 빠지지 않는다. 그렇게 많이 사용하는데, 왜 안될까?

확인이 쉬운 것부터 살펴보자. 액티비티 호출을 위해 만드는 인텐트 유형은 명시적 인텐트와 암시적 인텐트로 나뉜다. 인텐트를 잘 만들었는지 살펴보자.

  • 명시적 인텐트는 호출할 대상 패키지와 패키지 속 액티비티 정보를 넣어야 한다. 명시적 인텐트를 통해 호출을 시도했으나 에러가 난다면 패키지나 액티비티 이름이 틀린 것은 아닌지 확인해보자.
  • 암시적 인텐트는 액션(action)을 이용하므로, 액션이 틀렸는지 확인하자.

intent에 넣은 정보가 맞는데도 안되는 경우도 있다. 그럼, 다음 경우도 생각해 보자.

  • 암시적 인텐트를 사용할 때 액션과 함께 전달하는 추가정보가 잘못 되었는지 확인하자.  예를 들면, AndroidManifest.xml에 액티비티가 처리할 수 있는 URL 스키마를 선언할 수 있다. 이 설정과 전달하는 url 데이터가 맞지 않다면 실행되지 않는다.
  • 퍼미션이 필요한지 확인하자. 안드로이드의 컴포넌트는 자신을 호출하는 앱이 퍼미션을 갖고(granted)있어야 실행하도록 강제할 수 있다. 퍼미션이 없다면 Exception이 발생한다.
  • 액티비티가 앱 외부에서 공개되지 않게 설정되었을 수도 있다. AndroidManifest.xml 내의 액티비티 컴포넌트 선언부의 android:exported 어트리뷰트가 true인지 확인하자. 참고로, 기본값이 true다.
  • intent에 넣은 정보가 맞는데도 실행이 안된다면 앱이 설치되었는지 확인하자. 앱 슬롯이나 셋팅 내 어플이케이션 목록을 통해 확인할 수 있다.
  • 설치가 되었는데도 실행되지 않는다면 앱이 비활성화 됐을 수 있다. 셋팅 내 어플이케이션 목록에서 앱을 찾아, 사용하지 않기(비활성화)로 둔 것은 아닌지 확인해보자.
  • 혹시, MAIN 액션과 LAUNCHER 카테고리를 가지는 일명 메인 액티비티가 실행되지 않는다면 이 글을 읽어보자.

그 밖에

액티비티를 실행할 때는 가능하다면 암시적 인텐트를 이용하는 것이 좋다.

  • 같은 액션을 활용하는 모든 앱이 사용자에게 표시되므로 사용자에게 선호하는 앱을 이용할 수 있게 선택권을 줄 수 있다.
  • 호출할 액티비티의 패키지 이름이 바뀌더라도 명시적으로 컴포넌트를 선언하지 않기 때문에, ActivityNotFoundException과 같은 문제가 발생하지 않는다.
  • 액티비티 정보는 쉽게 알 수 없으니 명시적 인텐트가 안전하다고 생각하는 경우가 있다. dumpstate의 설치된 앱 정보 등을 통해 액티비티를 알아낼 방법은 다양하므로, 호출은 모두 가능하다. 잘못된 값이 전달될 위험은 값을 validation하여 대응하고, 사용 자체를 막고자 한다면 퍼미션을 활용하자.

참고

댓글 남기기

이메일은 공개되지 않습니다.

이 사이트는 스팸을 줄이는 아키스밋을 사용합니다. 댓글이 어떻게 처리되는지 알아보십시오.