아메리카노가 그렇게 맛있답니다 여러분

안드로이드 서비스는 액티비티와 달리 매니페스트(manifest)에 등록하지 않아도 로그 하나 없이 없는 샘 치고 동작한다.

<service android:name=".service.MyService"/>

이런 식으로 서비스도 액티비티를 등록하듯 등록해주면 원활하게 작동한다.

현재 앱을 하나 만들고 있는데 이 앱을 처음에는 Notification 하나 없이 완벽하게 백그라운드로만 돌아가는 서비스로 만들고 싶었다. 하지만 이렇게 만들고 에뮬레이터에서 실험해봤더니 히스토리를 비워버리면 백그라운드 작업이 정상 동작을 하지 않는 일을 겪었다.

 

에뮬레이터가 아닌 실제 기기에서 테스트 할 때는 no pid ignore service라는 로그가 뜨는데 이에 대한 내용은 구글에서 잘 나오지 않아 명확하게 말할 수는 없지만 해당 프로세스가 없어졌기 때문에 서비스 거부를 당한 것 같다고 로그로 지레짐작했다.

 

히스토리를 없애도 작동하는 방법은 포그라운드 뿐인 것 같아 더미 포그라운드를 하나 만들고 다시 테스트를 실행시켜봤더니 모든 백그라운드 서비스가 정상적으로 동작했다. 포그라운드가 하나 붙어있으면 앱이 가진 백그라운드 프로세스가 죽지 않는 것 같다.

 

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        // run when other component call startService()
 
        Notification notiEx = new NotificationCompat.Builder(TimeService.this)
                .setContentTitle("TESTING TITLE")
                .setContentText("TESTING CONTENT")
                .setSmallIcon(R.drawable.ic_done_white_18dp)
                .build();
        startForeground(1, notiEx);
 
        return super.onStartCommand(intent, flags, startId);
    }

 

[특별할 것 없는 포그라운드의 더미 코드 부분이다]

안드로이드에서는 객체를 Intent에서 넘기기 위해서는 implements Serializable을 해당 객체에게 추가해주면 된다.

 

CharacterItem 이라는 객체를 리스트뷰에서 눌렀을 때 객체 속 String이나 int같은 값을 따로따로 전달하지 않는 방법.

 

Character implements Serializable { private String name; private int level; private int job; // job is job code (1=warrior, 2=archor . . .)   public String getName() { return name; } public void setName(String name) { this.name = name; } public int getLevel() { return level; } public void setLevel(int level) { this.level = level; } public int getJob() { return job; } public void setJob(int job) { this.job = job; } }

이런 식으로 Serializable을 적용해준 다음에

 

Intent intent = new Intent(getApplicationContext(), MainActivity.class);
Character character = (Character) characterAdapter.getItem(i);
intent.putExtra("character", character);

이런 방식으로 전달해주면 된다. (참고로 변수 i는 리스트뷰의 n번째 위치를 의미하고 Adapter는 리스트뷰에 붙인 어댑터를 의미한다)

 

 

 

만약 이런 식으로 Serializable을 적용했는데도 오류가 발생한다면, 객체 안에 또 다른 객체가 있을 경우에는 해당 객체에게도 Serializable을 적용해야 한다.

 

Character implements Serializable {
  private String name;
  private int level;
  private int job; // job is job code (1=warrior, 2=archor . . .)
  private List<BagItem> bag;
 
  public String getName() {
    return name;
  }
  public void setName(String name) {
    this.name = name;
  }
  public int getLevel() {
    return level;
  }
  public void setLevel(int level) {
    this.level = level;
  }
  public int getJob() {
    return job;
  }
  public void setJob(int job) {
    this.job = job;
  }
}

이런 식으로 BagItem이라는 클래스를 하나 만들었다고 한다면, Character를 Intent로 넘기기 위해서는 BagItem도 implements Serializable 해줘야 한다.