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

onDestroy에서 DB에 값 넘겨주기

0 추천

다름이 아니라 앱을 사용하다가 강제 종료하게 되면 onDestroy을 실행시켜서 카운팅하던 데이터를 DB에 더해주도록 하고 싶습니다.

이를 위해 onDestory에 데이터를 읽어오고 이를 다시 쓰는 코드를 작성하였는데요, onDestory의 다른 코드들은 잘 동작하지만 DB에서 읽어오고 다시 쓰는 코드는 동작하지 않습니다.

혹시 onDestroy에서 DB의 데이터를 읽어오도록 할 수 있을까요?

현재 DB는 Firebase를 사용하였으며, 강제 종료 시에 서비스를 통해 onDestroy를 동작하도록 하였습니다.

위의 문제를 해결할 수 있거나 강제종료 시 DB의 데이터를 읽을 수 있는 방법을 알고 싶습니다!

 

@Override
public void onDestroy() {
    super.onDestroy();
    updateCountBall();
    sendData("0,0,0,0");
    Log.i(TAG, "Destroy 실행");

}

public void updateCountBall(){
    SimpleDateFormat dtf = new SimpleDateFormat("yyyyMMdd");
    Calendar calendar = Calendar.getInstance();
    Date dateObj = calendar.getTime();
    String formattedDate = dtf.format(dateObj);
    String cnt_str = String.valueOf((int)ball_count);
    Log.i(TAG, formattedDate);
    Log.i(TAG, "update Count Ball");
    databaseReference.child("users").child(uid).child("ballCount").child(formattedDate).get().addOnCompleteListener(new OnCompleteListener<DataSnapshot>() {
        @Override
        public void onComplete(@NonNull Task<DataSnapshot> task) {
            if(!task.isSuccessful()){
                Log.i(TAG, "failed");
            }
            else{
                String res = String.valueOf(task.getResult().getValue());
                if(res.equals("null")){
                    databaseReference.child("users").child(uid).child("ballCount").child(formattedDate).setValue(cnt_str);
                    Log.i(TAG, "null");
                }
                else{
                    Log.i(TAG, "task");
                    Log.i(TAG, "테스크: " + String.valueOf(task.getResult().getValue()));
                    int res_cnt = Integer.parseInt(String.valueOf(task.getResult().getValue()));
                    res_cnt += (int)ball_count;
                    databaseReference.child("users").child(uid).child("ballCount").child(formattedDate).setValue(String.valueOf(res_cnt));
                }
            }
            ball_count = 0.5;
        }
    }).addOnFailureListener(new OnFailureListener() {
        @Override
        public void onFailure(@NonNull Exception e) {
            Log.i(TAG, "onFailure: "+e.getMessage());
        }
    });
}
Niaak (220 포인트) 님이 2022년 6월 2일 질문
Niaak님이 2022년 6월 2일 수정
onComplete이 있으면 그 안에서 에러 처리가 가능하므로 addOnFaiilure는 중복일 것 같은데요. onComplete나 addOnSuccess + addOnFailure 둘 중의 방법으로 사용하셔야 할 것 같은데, 확인해 보세요.

1개의 답변

+1 추천
 
채택된 답변

왜 저장이 안되는지는  코드를 보지 못해서 말씀드릴 수 없기 때문에 그에 대한 해결책도 말씀 드리기 어려울 것 같지만, 한가지 안알야두셔야 할 점은, onDestory 는 항상 호출되는게 아닙니다. 에를 들면, 시스템이 메모리부족 등의 이유로 백그라운에 있는 앱을 예고없이 죽일 수 있습니다. 이 때 onDestory는 호출되지 않습니다. 그리고 불행하게도 이런 현상은 우리가 아는 것보다 실제로 많이 일어납니다.

한가지 방법은 onPause/onStop등의 확실하게 호출되는 라이프사이클 이벤트에서 데이터를 저장해 주는 겁니다.

public class MyActivity extends AppCompatActivity implements  BallRepository.Listener {
    
    private BallRepository ballRepository;
    private int ballCount;

    @Override
    public void onCreate(...) {
       super.onCreate(...);
       
      ballRepository = new BallRepository();
    }
    
    @Override
    public void onStart() {
       super.onStart();
       ballRepository.setListener(this);
       ballRepository.updateCount(ballCount);
    }

    public void onStop() {
       super.onStop();
       ballRepository.setListener(null);
    }

    @Override
    public void onCountBallSaved(int count) {
        ballCount = 0.5;
    }

    @Override
    public  void onCountBallError(Exception e) {
        // 에러처리
    }
}


public class BallRepistory {
    interface Listener {
         void onCountBallSaved(int count);
         void onCountBallError(Exception e);
    }

    public void updateCount(int count){
         String today = DateUtil.krToday();
         String countAsString = String.valueOf(count);

         databaseReference.child("users").child(uid).child("ballCount").child(today).get().addOnCompleteListener(new OnCompleteListener<DataSnapshot>() {
             @Override
             public void onComplete(@NonNull Task<DataSnapshot> task) {
                 if(!task.isSuccessful()){
                     Log.i(TAG, "failed");
                     if (listener != null) listener.onCountBallError(task.getException());
                     return;
                 }
            
                ..
           
                if (listener != null) listener.onCountBallSaved(count);
           };
       
}

public class DateUtil {
    public static String krToday() {
          return formatKrDate(new Date(), "yyyyMMdd");
    }

    private static String formatDate(Date date, String pattern) {
         SimpleDateFormat dtf = new SimpleDateFormat(pattern);
         return dtf.format(date);
    }
}

 

spark (227,830 포인트) 님이 2022년 6월 2일 답변
Niaak님이 2022년 6월 3일 채택됨
...