Skip to main content

One post tagged with "서비스"

View All Tags

· 14 min read
  1. 인플레이션
  • XML 레이아웃에 정의된 내용이 메모리에 객체화되는 과정
  • setContentView() 함수가 내부적으로 인플레이션 작업 실행
  • 인플레이션 작업 하기 전에 xml 파일에 접근하면 널 포인트 에러 발생
  • 전체 화면 중 일부분만 차지하는 화면 구성요소들을 XML레이아웃에서 로딩
    • getSystemService(Context.LAYOUT_INFLATER_SERVICE)
    • LayoutInflater라는 클래스 제공하며, 이 클래스는 시스템 서비스로 제공된다.
    • LayoutInflater inflater = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE); inflater.inflate(R.layout.sub1, container, true);
  1. 액티비티 생명주기
  • 실행(Running): 화면 상에 액티비타가 보이면서 실행되어 있는 상태, 액티비티 스택의 최상위에 있으며 포커스를 가지고 있음
  • 일시 중지(Paused): 사용자에게 보이기는 하지만 다른 액티비티가 위에 있어 포커스를 받지 못하는 상태, 대화상자가 위에 있어 일부가 가려져 있는 경우에 해당
  • 중지(Stopped): 다른 액티비티에 의해 완전히 가려져 보이지 않는 상태
  1. 생명주기를 활용한 데이터 저장
  • onCreate -> onStart -> onResume -> onPuase -> onStop -> onDestroy
  • onPause 에서 데이터 저장 후 onResume에서 데이터 복구
  • onPuase
    • SharedPreferences pref = getSharedPreference("pref", Activity.MODE_PRIVATE);
    • SharedPreferences.Editor editor = pref.edit();
    • editor.putString("name", "davidyoon");
    • editor.commit();
  • onResumse
    • SharedPreferences pref = getSharedPreferences("pref", Activity.MODE_PRIVATE);
    • if ( pref != null) { String name = pref.getString("name"); }
  1. 서비스
  • 서비스는 화면이 없는 상태에서 백그라운드로 실행됨

  • 서비스는 프로세스가 종료되어도 시스템에서 자동으로 재시작함

  • 서비스 생명주기

    • onCreate -> onDestroy
    • startService()
  • 액티비티에서 서비스로 데이터 전달

    • Intent intent = new Intent(getApplicationContext(), MyService.class);
    • intent.putExtra("command", "show");
    • startService(intent);
  • onCreate 는 한 번 만들어 지고 새로 만들어지지 않는다.

    • 결국 데이터 처리는 onCreate가 아닌 onStartComamnd(Intent intent, int flags, int startId) 에서 처리
    • if ( intent == null) { return Service.START_STICKY }
    • START_STICKY : 서비스가 종료되었을 떄에도 다시 시작해 달라는 의미
  • Service 에서 Activity로 데이터 전달

    • Intent showIntent = new Intent(getApplicationContext(), MainActivity.class);
    • showIntent.addFlags(Intent.FlAG_ACTIVITY_NEW_TASK| Intent.FLAG_ACTIVITY_SINGLE_TOP| Intent.FLAG_ACTIVITY_CLEAR_TOP);
    • showIntent.putExtra("command", "show");
    • showIntent.putExtra("name", name + " from service.");
    • startActivity(showIntent);
  • Activity 에서 데이터 받기

    • onNewIntent(Intent intent) 사용
      • processComamnd(intent);
    • onCreate()에서도 처리
      • Intent passedIntent = getIntent()
      • processCommand(passedIntent);
    • processCommand(Intent intent)
    • if(intent != null) { String command = intent.getStringExtra("command"); String name = intent.getStringExtra("name"); }
  1. BroadCast Receiver
  • 어플리케이션이 글로벌 이벤트(Global Event)를 받아서 처리하려면 브로드캐스트 수신자로 등록
  • 글로벌 이벤트란 전화, 문자 메시지 와 같이 안드로이드 시스템 전체에 보내지는 메시지다
  • 브로드 캐스트 수신자는 인텐트필터를 포함하며, 매니페스트 파일에 등록함으로써 인텐트를 받을 준비를 한다
  • 수신자가 매니페스트 파일에 등록되었다면 따로 시작시키지 않아도 된다
  • 어플리케이션 컨텍스트 클래스의 registerReceiver 메소드를 이용하면 런터임 시에도 수신자를 등록할 수 있다
  • 서비스처럼 브로드캐스트 수신자도 UI가 없다
  • 인텐트와 브로드캐스트
    • 인텐트를 이용하여 액티비트를 실행하며 포그라운드(foreground)로 실행되어 사용자에게 보여지지만
    • 브로드캐스트를 이용해서 처리하면 백그라운드(background)로 동작하므로 사용자가 모름
    • 인텐트를 받으면 onReceive() 메소드가 자동으로 호출된다
  • 브로드캐스트의 구분
    • 브로드캐스트는 크게 두 가지 클래스로 구분된다
      • 일반 브로드캐스트(sendBroadcase() 메소드로 호출): 비동기적으로 실행되며 모든 수신자는 순서없이 실행된다 (때로는 동시에 실행됨) 효율적이나, 한 수신자의 처리 결과를 다른 수신자가 이용할 수 없고 중간에 취소가 불가능
      • 순차 브로드캐스트(sendOrderedBroadcase() 메소드로 호출): 한 번에 하나의 수신자에만 전달되므로 순서대로 실행됨. 중간에 취소하면 그 다음 수신자는 받지 못함. 수신자가 실행되는 순서는 인텐트필터의 속성으로 정할 수 있음. 순서가 같으면 임의로 실행된다
  1. SMS Receiver
  • BroadcastReceiver 상속 받는 Receiver 생성
  • onReceive() 메소드에서 intent 처리
  • Bundle bundle = intent.getExtras();
  • Object[] objs = (Object[]) bundle.get("pdus"); // SMS 표준 프로토콜 puds로 번들에서 object형태로 꺼내 사용
  • SmsMessage[] messages = new SmsMessage[objs.length]; //SmsMessage 객체에 object 넣어서 메시지 파싱
  • 마시멜로 이상 버전은 format 설정
    • String format = bundle.getString("format");
    • message[i] = SmsMessage.createFromPdu((byte[])objs[i], format);
  • 액티비티에 intent 전송 (화면이 없는 Receiver에서 화면으로)
    • sendToActivity(context, sender, contents, date)
    • Intent intent = new Intent(context, SmsActivity.class);
    • 데이터 put
      • intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK| Intent.FLAG_ACTIVITY_SINGLE_TOP| Intent.FLAG_ACTIVITY_CLEAR_TOP ); // 화면없는 곳에서 activity로 데이터 보낼때 셋팅
      • intent.putExtra("sender", sender);
      • Date to String foramt
        • private static SimpleDateForamt format = new SimpleDateFormat("yyyy-MM-dd HH:mm");
      • intent.putExtra("receivedDate", format.format(date));
      • context.startActivity(intent);
    • SmsActivity
      • onCreate()
      • Intent passedIntent = getIntent(); //getIntent로 받아서 처리
      • processCommand(passedIntent);
      • private void processCommand(Intent intent){ if (intent != null) { String sender = intent.getStringExtra("sender); } }
  • 실행한 Activity가 foreground 상태에서 Intent에 Extra 값을 추가하고 StartActivity를 호출하면 onCreate() 대신 onNewIntent(Intent intent)가 시랳ㅇ 되고 그 다음 onResume()이 호출된다.
  • 따라서 SmsActivity에서도 onNewIntent() 오버라이딩 해주어야 한다.
    • onNewIntent(Intent intent){ processCommand(intent); }
  1. Activity Flags
  • 안드로이드 Activity는 Stack 형태로 쌓이게 된다.
  • startActiviy로 activity를 호출할 때 FLAG 셋팅으로 Activity 스택을 제어할 필요하 있다.
  • FlAG 종류
    • Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT: 시스템에 의해 스택 관리되며 가장 기본 값이다.
    • Intent.FLAG_ACTIVITY_NEW_TASK: 새로운 테스크 생성, 기존에 열어놓은게 없으면 새로운 테스크 생성, 기존에 열어놓은게 있으면 그 테스트로 들어감.
    • Intent.FLAG_ACTIVITY_CLEAR_TOP: 상위 스택 제거, 실행하는 액티비티가 존재하면 새로 시작하지 않고 상위에 액티비티 모두 제거
    • Intent.FLAG_ACTIVITY_SINGLE_TOP: 액티비티가 이미 최상단에 있으면 다시 시작하지 않고 재사용, [ABCDE]가 있고, E에서 다시 E를 열면 onPuase() -> onNewIntent() -> onResume()
    • Intent.FLAG_ACTIVITY_CLEAR_TASK // 실행 액티비티 외 모두 제거
    • Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS // 최근 목록에서 제외.
    • Intent.FLAG_ACTIVITY_FORWARD_RESULT // result를 상위로 보냄. startActivityForResult()에서 사용.
    • Intent.FLAG_ACTIVITY_PREVIOUS_IS_TOP // onActivityResult()로 결과를 전달할 때 이전 액티비티로 돌아가도록 하기 위해 추가.
    • Intent.FLAG_ACTIVITY_LAUNCH_ADJACENT // 멀티 윈도우 시 사용.
    • Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY // 시스템에 의해 설정됨. 최근 목록에서 실행되면 자동으로 붙음.
    • Intent.FLAG_ACTIVITY_MULTIPLE_TASK // FLAG_ACTIVITY_NEW_TASK와 함께 사용시 새 태스크 생성
    • Intent.FLAG_ACTIVITY_NEW_DOCUMENT // concurrent document 동시 문서에서 사용
    • Intent.FLAG_ACTIVITY_NO_ANIMATION // 액티비티 전환시 애니메이션 무시
    • Intent.FLAG_ACTIVITY_NO_HISTORY // 액티비티를 스택에 존재X (로딩화면 등)
    • Intent.FLAG_ACTIVITY_NO_USER_ACTION // onUserLeaveHint() 실행을 차단
    • Intent.FLAG_ACTIVITY_REORDER_TO_FRONT // 실행하는 액티비티를 최상위로 올려줌
    • Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED // 정리할 액티비티가 있으면 태스크를 리셋
    • Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET // 리셋하면 상위 태스크 모두 삭제
    • Intent.FLAG_ACTIVITY_TASK_ON_HOME // FLAG_ACTIVITY_NEW_TASK와 함께 사용. 현재 홈 태스크 위에 위치.
    • Intent.FLAG_ACTIVITY_MATCH_EXTERNAL // 전체 앱이 intent를 처리할 수 없을 때
    • Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS // 최근 목록에서 재실행할 수 있도록 유지.
    • Intent.FLAG_DEBUG_LOG_RESOLUTION // 디버깅 정보를 로그로 출력.
    • Intent.FLAG_INCLUDE_STOPPED_PACKAGES // stopped된 application도 target이 됨.
    • Intent.FLAG_EXCLUDE_STOPPED_PACKAGES // stopped된 application은 target이 되지 않음.
    • Intent.FLAG_FROM_BACKGROUND // 백그라운드 동작중을 알려줌.
    • Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION // URI 지속 권한
    • Intent.FLAG_GRANT_PREFIX_URI_PERMISSION // URI prefix match 권한.
    • Intent.FLAG_GRANT_READ_URI_PERMISSION // URI 읽기 권한.
    • Intent.FLAG_GRANT_WRITE_URI_PERMISSION // URI 쓰기 권한.
    • Intent.FLAG_RECEIVER_FOREGROUND // 포그라운드로 변경
    • Intent.FLAG_RECEIVER_NO_ABORT // 리시버가 브로드캐스트를 중지 못함.
    • Intent.FLAG_RECEIVER_REGISTERED_ONLY // 동적 리시버만 브로드캐스트 받음.
    • Intent.FLAG_RECEIVER_REPLACE_PENDING // 중복된 브로드캐스트를 제거.
    • Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS // 브로드캐스트가 instant app의 수신자에게 표시.
  1. 일반 권한과 위험 권한 (마시멜로 API 23 부터)
  • 설치시 권한 설정 했는데 유저들이 모두 OK 누르는 형태에서 문제 발생하여 23이상부터 변경
  • 위험 권한은 실행 시 권한 부여
  • 위험 권한
    • 위치
    • 카메라
    • 마이크
    • 연락처
    • 전화
    • 문자
    • 일정
    • 센서
  • 퍼미션 체크
    • int permissionCheck = ContextCompact.checkSelfPermission(this, Manifest.permission.RECEIVE_SMS);
    • if (permissionCheck == PackageManger.PERMISSION_GRADNTED)
    • 퍼미션 거절
      • if (ActivityCompat.shouldShowRequestPermisionRationale(this, Manifest.permission.RECEIVE_SMS))
    • 퍼미션 요청 창 띄우기
      • ActivityCompact.requestPermssions(this, new String[] {Manifest.permission.RECEIVE_SMS}, 1);
  • 퍼미션 요청 결과 콜백 함수
    • onRequestPermissionResult(requestCode, permissions, gratResults)
    • switch (requestCode) { case 1: if (grantResults.length > 0) { if ( grantResults[0] == PackageManager.PERMISSION_GRANTED) { //토스트 메시지 승인 } } }
  1. 다양한 위젯과 이벤트 활용
  • 대표적 이벤트
    • 터치: 화면을 손가락으로 누를 떄 발생
    • 키: 키패드나 하드웨어 버튼을 누를 떄 발생
    • 제스처: 터치 이벤트 중에서 일정 패턴을 만들어 내는 이벤트
    • 포커스: 뷰마다 순서대로 주어지는 포커스
    • 화면 방향 변경: 화면의 방향이 가로/세로로 바뀜에 따라 발생하는 이벤트
  • 제스처를 통해 처리할 수 있는 이벤트
    • onDown(): 화면이 눌렸을 경우
    • onShowPress(): 화면이 눌렸다 뗴어지는 경우
    • onSingleTapUp(): 화면이 한 손가락으로 눌렸다 뗴어지는 경우
    • onSingleTapConfirmed(): 화면이 한 손가락으로 눌려지는 경우
    • onDoubleTap(): 화면이 두 손가락으로 눌려지는 경우
    • onDoubleTapEvent(): 화면이 두 손가락으로 눌려진 상태에서 뗴거나 이동하는 등 세부적인 액션을 취하는 경우
    • onScroll(): 화면이 눌린 채 일정힌 속도와 방향으로 움직였다 떼는 경우
    • onFling(): 화면이 눌린 채 가속도를 붙여 손가락을 움직였다 떼는 경우
    • onLongPress(): 화면을 손가락으로 오래 누르는 경우
  1. 가로 세로 전환
  • res/layout-land 폴더 생성 후 activity_main.xml 복사 해서 붙여넣기
  • 2 개의 액티비티를 가로 세로에 따라서 새로 띄우고 꺼지고 반복 된다.
  • onSaveInstanceState() 함수 오버라이딩 해서 저장된 값을 불러와서 사용 가능.
  • 동일한 PlainText(EditView)에는 자동으로 값 저장되게 최신버전의 안드로이드는 변경 되었다.
  • 한 액티비티에서 가로 세로 전환
    • onConfigurationChanged() 함수 오버라이드
    • 상태가 변할 때 마다 호출되는 함수
    • newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE 등으로 조건문 붙여서 처리 가능.