2013-03-24 2 views
1

내 Activity의 onCreate 메소드에서 onSharedPreferenceChangeListener를 등록합니다. 액티비티 자체는 OnSharedPreferenceChangeListener를 구현합니다.공유 환경 설정이 변경된 후 UI를 업데이트 할 때 앱이 충돌 함

기본 설정이 업데이트되면 다음 방법이 호출됩니다.

@Override 
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) { 
    if(key.equals(Configuration.PREF_TIMETABLE_UPDATING)){ 
     resetView(); 
    } 

} 

public void resetView(){ 
    this.container.removeAllViews(); 
} 

이 코드는 특정 속성이 업데이트 된 후 컨테이너보기에서 모든보기를 제거합니다. 그것은 모든 바로 내 안드로이드 4 장치와 작동하지만, 내 안드로이드 2.2.1 장치의 응용 프로그램 충돌 :

03-24 16:09:00.054: E/AndroidRuntime(1712): FATAL EXCEPTION: AsyncTask #5 
03-24 16:09:00.054: E/AndroidRuntime(1712): java.lang.RuntimeException: An error occured while executing doInBackground() 
03-24 16:09:00.054: E/AndroidRuntime(1712):  at android.os.AsyncTask$3.done(AsyncTask.java:200) 
03-24 16:09:00.054: E/AndroidRuntime(1712):  at java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:273) 
03-24 16:09:00.054: E/AndroidRuntime(1712):  at java.util.concurrent.FutureTask.setException(FutureTask.java:124) 
03-24 16:09:00.054: E/AndroidRuntime(1712):  at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:307) 
03-24 16:09:00.054: E/AndroidRuntime(1712):  at java.util.concurrent.FutureTask.run(FutureTask.java:137) 
03-24 16:09:00.054: E/AndroidRuntime(1712):  at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1068) 
03-24 16:09:00.054: E/AndroidRuntime(1712):  at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:561) 
03-24 16:09:00.054: E/AndroidRuntime(1712):  at java.lang.Thread.run(Thread.java:1102) 
03-24 16:09:00.054: E/AndroidRuntime(1712): Caused by: android.view.ViewRoot$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views. 
03-24 16:09:00.054: E/AndroidRuntime(1712):  at android.view.ViewRoot.checkThread(ViewRoot.java:2824) 
03-24 16:09:00.054: E/AndroidRuntime(1712):  at android.view.ViewRoot.requestLayout(ViewRoot.java:598) 
03-24 16:09:00.054: E/AndroidRuntime(1712):  at android.view.View.requestLayout(View.java:8126) 
03-24 16:09:00.054: E/AndroidRuntime(1712):  at android.view.View.requestLayout(View.java:8126) 
03-24 16:09:00.054: E/AndroidRuntime(1712):  at android.view.View.requestLayout(View.java:8126) 
03-24 16:09:00.054: E/AndroidRuntime(1712):  at android.view.View.requestLayout(View.java:8126) 
03-24 16:09:00.054: E/AndroidRuntime(1712):  at android.widget.ScrollView.requestLayout(ScrollView.java:1200) 
03-24 16:09:00.054: E/AndroidRuntime(1712):  at android.view.View.requestLayout(View.java:8126) 
03-24 16:09:00.054: E/AndroidRuntime(1712):  at android.view.ViewGroup.removeAllViews(ViewGroup.java:2263) 
03-24 16:09:00.054: E/AndroidRuntime(1712):  at com.example.TimetableActivity.resetView(TimetableActivity.java:430) 
03-24 16:09:00.054: E/AndroidRuntime(1712):  at com.example.TimetableActivity.onSharedPreferenceChanged(TimetableActivity.java:557) 
03-24 16:09:00.054: E/AndroidRuntime(1712):  at android.app.ContextImpl$SharedPreferencesImpl$EditorImpl.commit(ContextImpl.java:2869) 
03-24 16:09:00.054: E/AndroidRuntime(1712):  at com.example.MyHelper.setTimetableUpdate(MyHelper.java:145) 
03-24 16:09:00.054: E/AndroidRuntime(1712):  at com.example.webservice.task.LessonFetcherTask.doInBackground(LessonFetcherTask.java:33) 
03-24 16:09:00.054: E/AndroidRuntime(1712):  at com.example.webservice.task.LessonFetcherTask.doInBackground(LessonFetcherTask.java:1) 
03-24 16:09:00.054: E/AndroidRuntime(1712):  at android.os.AsyncTask$2.call(AsyncTask.java:185) 
03-24 16:09:00.054: E/AndroidRuntime(1712):  at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305) 
03-24 16:09:00.054: E/AndroidRuntime(1712):  ... 4 more 

은 어떻게 OnSharedPreferenceChangeListener 호출하는 방법은 UI 스레드에서 실행 확인합니까? 이 문제를 해결하는 방법에 대한 도움을 주시면 매우 감사하겠습니다!

답변

1

문제는 어떻게 든 새로운 스레드에 방황 한 것입니다 : UI 명령은 UI 스레드에있는 보장하기

Caused by: android.view.ViewRoot$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views. 

한 가지 방법은 UI 처리기를 사용하는 것입니다. (소리가 나는 것처럼 어렵지는 않습니다.) 단순히 removeViews()을 Runnable에 넣고 어떤보기에서도 post()을 사용하십시오. 그래서 같이 :

는 Runnable를 만들기 :

Runnable runnable = new Runnable() { 
    @Override 
    public void run() { 
     resetView(); 
    } 
}; 

포스트 그것을 UI 스레드에 :

if(key.equals(Configuration.PREF_TIMETABLE_UPDATING)){ 
    container.post(runnable); 
} 
+0

가 대단히 감사합니다, 이건 내 문제가 해결되었습니다! :) –