2012-11-30 7 views
2

나는 동시성 문제가 있습니다. 나는 수색을했고 내 것과 같은 조건으로 질문을 찾을 수 없다. 포인터를 환영합니다.onActivityResult가 너무 일찍 호출 됨

이클립스 4.2.1

안드로이드 4.1.2 나는이 개 활동이있다; ListActivity 및 DetailActivity라고 부르 자. ListActivity 버튼을 누르면 DetailActivity가 시작됩니다. 사용자가 DetailActivity에서 데이터를 변경 한 다음 뒤로 버튼을 클릭하면 두 가지 작업을 수행하려고합니다. 첫째, 더티 플래그가 true이면 데이터베이스에 변경 사항을 저장하려고합니다. 둘째, ListActivity의 onActivityResult() 메서드에 Intent를 반환하려고합니다.

문제는 타이밍 중 하나입니다. 데이터베이스 업데이트를하고 싶으므로 DetailActivity의 onStop() 메서드에서이 작업을 수행하는 것이 가장 좋습니다. 데이터베이스를 업데이트 한 직후에 인 텐트를 설정하고 DetailActivity에서 setReult() 메서드를 호출합니다. 나는 결과를 설정할 수있는 기회를하기 전에

_resultIntent = new Intent(); 
_resultIntent.putExtra(ListActivity .DETAIL_RESULT, _currentData); 
Log.d("ListActivity.setUpReturn()", "checkpoint"); 
setResult(Activity.RESULT_OK, _resultIntent); 

ListActivity의 onActivityResult를() 메소드가 호출됩니다. 로그 호출을 통해 다음과 같이 나타납니다.

1) 사용자가 DetailActivity에 있고 더티 플래그를 설정하는 일부 데이터를 true로 변경합니다.
2) 사용자가 시스템 뒤로 버튼을 클릭합니다.
3) DetailActivity가 화면에서 사라집니다.
4) ListActivity가 다시 나타납니다.
5) Log는 onActivityResult(), onRestart(), onStart() 및 ListActivity의 onResume() 메서드가 순서대로 실행됨을 나타냅니다.
6) 다른 것들이 기록됩니다.
7) Log는 False로 DetailActiviy의 onStop() 메서드가 실행됨을 나타냅니다.

이것은 데이터베이스를 업데이트하고 결과 인 텐트를 설정하기 전에는 호출하는 활동이 이미 사용 지점을 지나치고 있음을 의미합니다.

저는 데이터베이스를 지속적으로 업데이트하지 않을 것입니다. 차라리 모범 사례처럼 onStop() 메서드에 넣을 것이지만 타이밍 문제를 해결하는 방법을 알지 못합니다. 어떤 제안? 나는 분명히 잘못된 것을하고 있습니까?

답변

1

에 그것을 만들 경우에 따라서 SingleInstance로했다

+0

PravinCG, 이것은 정확히 내가 찾던 해답입니다. 이렇게하면 시스템이 사용자가이 활동을 취소하기를 원하기 전에 데이터베이스 작업을 완료 할 수 있습니다. 부작용으로 사용자가 뒤로 버튼을 클릭 할 때만 발생하며 활동이 중지되지 않은 경우에는 발생하지 않습니다. 즉, 사용자가 방향을 바꾸거나 전화가 걸려 활동이 중지되거나 파기 되어도 정상적인 방법으로는 상태를 관리 할 수 ​​있지만 사용자가 명시 적으로 활동을 닫을 때 변경 사항 만 데이터베이스에 커밋됩니다. -Continued – Dogulas

+0

Continued- \t @Override 공공 무효 onBackPressed() { \t Log.d ("DetailActivity.onBackPressed()", "체크 포인트"); \t if (_currentDataIsDirty) { \t \t DoDatabaseWork (_currentData); \t} \t _resultIntent = new Intent(); \t _resultIntent.putExtra (ListActivity .DETAIL_RESULT, _currentData); \t setResult (Activity.RESULT_OK, _resultIntent); \t super.onBackPressed(); } 나는 무거운 작업을해야 할 때 자식 활동에서 부모 활동으로 돌아 가기위한 패턴으로 이것을 유지하려고합니다. 다시 한번 감사드립니다. – Dogulas

+0

@Dogulas : 도움이 된 것을 기쁘게 생각합니다. stackoverflow가있는 경우와 마찬가지로 이것을 대답으로 받아 들여야합니다. – PravinCG

0

액티비티가 포커스를 잃은 직후에 onPause()이 호출 되었기 때문입니다. 그러나 onStop()은 활동이 파괴 될 때 호출됩니다 (대개 메모리가 충분하지 않은 경우). 예 나는 오히려 이벤트 기반의 코드 논리에 의존하는 것 SingleTop

+0

토마스, 당신의 응답을 감사합니다. 예, 정리 작업을 onPause()에 넣을 생각 이었지만 설명서에서 권장하지 않습니다. http://developer.android.com/training/basics/activity-lifecycle/stopping.html " onPause() 메서드가 onStop() 전에 호출되면 onStop()을 사용하여 데이터베이스에 정보를 쓰는 것과 같이 더 많은 CPU 집중적 인 종료 작업을 수행해야합니다. " -Continued – Dogulas

+0

-Continued 이것이 내가 onStop()을 사용했던 이유입니다. 나는 onDestroy()도 고려해 봤지만 현재의 문제는 더 나쁠 것입니다. 또한 onPause()는 onStop()보다 빈번하게 발생합니다 (조금만 더 자주 OK). 활동이 부분적으로 가려 질 때 호출됩니다. 나는 정말로 내가하는 것보다 더 자주 모든 데이터베이스 작업을하고 싶지 않다. 이 모든 것이 말하면 솔루션이 효과적입니다. 도그 – Dogulas

+0

@Dogulas 네 말이 맞아. 'onPause()'는 사용자가 응답을 너무 오랫동안 기다릴 필요가 없도록 빠른 코드만을 포함해야합니다. 다른 한편으로, 이것은 확실히 불리는 유일한 방법입니다. 따라서 쉬운 선택은 아닙니다. – user219882

3

확인 당신이 당신의 활동을 ... onPause() 방법으로 코드를 삽입하면 괜찮을 확률보다는 오히려. 당신은 다음을 시도 할 수 있습니다.

* 1) 사용자가 DetailActivity에 있고 더티 플래그를 설정하는 일부 데이터를 true로 변경합니다. 2) 사용자가 시스템 뒤로 버튼을 클릭합니다. *

onBackPressed 메서드를 재정의하고 바로 데이터베이스 작업을 수행하고 DB 작업이 수행되면 super.onBackPressed() 메서드를 호출하고 Android Activity 스택을 대신 처리 할 수 ​​있습니다. DB 작업에 시간이 많이 걸릴 수 있으므로 콜백과 함께 AsyncTask를 사용하고 finish()를 호출하는 것이 좋습니다.

+0

Ali Imran, 감사합니다. 마법사가 활동 및 매니페스트 파일을 만들도록 허용하고, 기본적으로 시작 모드는 포함하지 않습니다. 즉, 기본값은 "표준"입니다. 제 경우에는 문제가되지 않습니다. 수정 사항은 PravinCG에서 제안한 것 같습니다. 답장을 보내 주셔서 다시 한 번 감사드립니다. 도그 렐 – Dogulas

0

나를위한 최고의 해결책은 PravinCG에서 나왔다. 앞으로이 패턴을 사용할 것입니다.

@Override 
public void onBackPressed() { 
    Log.d("DetailActivity.onBackPressed()", "checkpoint"); 
    if (_currentDataIsDirty) { 
     DoDatabaseWork(_currentData); 
    } 
    _resultIntent = new Intent(); 
    _resultIntent.putExtra(ListActivity .DETAIL_RESULT, _currentData); 
    setResult(Activity.RESULT_OK, _resultIntent); 
    super.onBackPressed(); 
} 

Dogulas

관련 문제