6

반 복잡한 문제가 있으며 여기 누군가가 나를 도울 수 있기를 바랍니다.Android : notifyDataSetChanged() 방향 변경 후 목록보기가 업데이트되지 않습니다.

클릭 이벤트에서 스레드를 만들고 this 메서드를 기반으로 장기 실행 작업을 시작합니다. 의 Runnable 호출

@Override 
public void contentSearchModelChanged(Model_ContentSearch csm, ArrayList<Class_Reminder> newRemindersList) { 
    remindersList = newRemindersList; 
    mHandler.post(mUpdateDisplayRunnable); 
} 

: 장기 실행 작업이 완료 후에는 핸들러에 게시물을하지 다른 방법에 콜백 않습니다 여기에, 마지막으로

// post this to the Handler when the background thread completes 
private final Runnable mUpdateDisplayRunnable = new Runnable() { 
    public void run() { 
    updateDisplay(); 
    } 
}; 

무엇을 내 updateDisplay() 메서드는 다음 작업을 수행합니다.

private void updateDisplay() { 
    if (csModel.getState() != Model_ContentSearch.State.RUNNING) { 
     if(remindersList != null && remindersList.size() > 0){ 
       r_adapter = new ReminderAdapater(Activity_ContentSearch.this, remindersList, thisListView); 
       thisListView.setAdapter(r_adapter); 
       r_adapter.notifyDataSetChanged(); 
     } 
    } 
} 

정상적으로 이렇게하면 효과적입니다. 그러나 장기 실행 작업이 실행되는 동안 방향을 변경하면 작동하지 않습니다. 콜백이 제대로 이루어지며 remindersList에 항목이 있습니다. 하지만이 줄에 도달했을 때 :

r_adapter.notifyDataSetChanged(); 

아무런 반응이 없습니다. 이상한 점은 다른 제출을하고 전체 프로세스를 다시 실행하면 (오리 엔테이션을 변경하지 않고) 실제로는 이전 제출과 다시 제출을 위해 두 번보기를 두 번 업데이트한다는 것입니다. 따라서 뷰는 첫 번째 제출 결과로 한 번 업데이트되고 두 번째 결과는 두 번째로 나중에 업데이트됩니다. adapater가 데이터를 얻지 못하면 뷰를 새로 고치지 않습니다.

나는 이것이 오리엔테이션 변화와 관련이 있다는 것을 알고있다. 그러나 나는 왜 그런지 알 수 없다. 누구든지 도와 줄 수 있습니까? 아니면 방향 변경으로 스레드를 처리하는 다른 방법을 제안 할 수 있습니까?

바라

답변

6

문제는 당신이 방향을 변경할 때 새 활동 시작 (에서 onCreate)에서 스핀 업된다는 것이다. 장시간 실행되는 프로세스에는 이전 (더 이상 볼 수없는) 활동에 대한 핸들이 있습니다. 이전 활동을 올바르게 업데이트하고 있지만 더 이상 화면에 표시되지 않으므로 표시되지 않습니다.

이 문제는 쉽게 해결할 수 없습니다. 거기 밖으로 당신을 도울지도 모른다 도서관이있다. 그것은 DroidFu라고합니다. http://brainflush.wordpress.com/2009/11/16/introducing-droid-fu-for-android-betteractivity-betterservice-and-betterasynctask/

편집 : (활성 활동을 추적하는 코드를 추가)

에서 여기 (훨씬 더 정확하게 I 이상)이 블로그 포스트는 DroidFu 라이브러리를 억제한다 방법 당신이보고있는과의 근본 원인은 설명입니다 응용 프로그램 클래스이 추가

private Activity _activeActivity; 
public void setActiveActivity(Activity activity) { 
    _activeActivity = activity; 
} 
public Activity getActiveActivity() { 
    return _activeActivity; 
} 

당신의 활동이 추가 :

@Override 
public void onResume() { 
    super.onResume(); 
    ((MyApplicationClassName)getApplication()).setActiveActivity(this); 
} 

지금 활성 activi를 얻을 수 있습니다 MyApplicationClassName.getActiveActivity()를 호출하여 호출합니다.

이것은 DroidFu가하는 방식이 아닙니다. DroidFu는 onCreate에서 활성화 된 액티비티를 설정하지만 매우 강력하다고는 생각하지 않습니다.

+0

음 ... 매우 도움이되는 것 같지만 문서가 많지 않습니다. 내 구현을 DroidFu를 사용하여 변경하는 것을 싫어하고 문제를 해결하는 방법을 알지 못합니다. 이는 일을하는 "일반적인"방식이 아니기 때문입니다. – Bara

+0

그래, 오래된 버려진 도서관 인 것처럼 보이지만 그 전제는 건전 해 보입니다. 라이브러리를 사용하지 않고도이 작업을 수행 할 수 있습니다. 기본적으로 Application 개체는 onResume을 사용하여 활성 활동을 추적합니다. 그런 다음 어댑터에 알릴 준비가되면 응용 프로그램에서 활성 활동을 가져오고 예상 활동의 인스턴스인지 확인한 후 캐스트하고 통지하십시오. –

+0

"활성 활동"을 추적하는 코드는 무엇입니까? 즉, 내가 CurrentActivity act = new CurrentActivity();와 같은 것을해야 하는가? act를 Application 클래스에 전달하면됩니까? – Bara

1

나는 ListAdapter에서 notifyDataSetChanged를 호출하는 핸들러에 시간 소모적 인 쓰레드 인 sendEmptyMessage를 가지고 비슷한 문제가있다. 나는 오리엔테이션을 바꿀 때까지 잘 돌아갔다.

UI 스레드에서 두 번째 핸들러를 선언하고 첫 번째 핸들러 sendEmptyMessage를이 핸들러로 만들고이 핸들러에서 ListAdapter의 notifyDataSetChanged를 호출합니다. 그리고 ListAdapter를 정적으로 선언하는 것. 이 못생긴 솔루션의 경우 나도 몰라 그래서

나는 초보자 해요,하지만 난이 같은 일 가정 할 Jere.Jones 설명에서 ... 나를 위해

을했다 : 장기 실행 프로세스를 sendEmptyMessage를 이전 Activity의 핸들에 보내면 sendEmptyMessage가 새 Activity의 핸들에 전달됩니다.

관련 문제