구성 변경 (특히 화면 선삭)을 수동으로 처리하도록 앱을 업데이트하려고합니다.Android : 스레드가 실행되는 동안 수동으로 구성 변경 사항을 처리하는 것에 관한 질문
스레드 실행 중에 변경 사항이 발생하면 어떻게되는지에 대한 질문이 있습니다.
주 스레드의 루퍼에 스레드와 처리기를 사용하여 스레드를 업데이트하여 주 스레드에 업데이트를 보내는 ThreadTask를 작성했습니다. 이것은 AsyncTask를 구현 한 것입니다.하지만 스레드를 사용하면 AsyncTask를 사용하는 것이 더 좋기 때문에 AsyncTask를 사용하는 것이 더 좋습니다.
public interface TaskObserver {
void pre_execute();
void on_progress(ProgressData progress);
void finished(Object result);
void cancelled(Object result);
}
서브 클래스가 구현해야하는 추상 멤버
은 다음과 같습니다 :abstract Object do_in_background();
일부 콘크리트
는 또한 위의 이벤트에 관찰자를 등록하는 두 가지 방법이있다,이 인터페이스를 사용 회원은 다음과 같습니다 :
synchronized void add_observer(TaskObserver observer){
_observers.add(observer);
}
synchronized void remove_observer(TaskObserver observer){
_observers.remove(observer);
}
synchronized void post_execute(Object result) {
int observers = _observers.size();
for (int idx = 0; idx < observers; idx++) {
_observers.get(idx).finished(result);
}
}
///plus all the other methods of the interface
그래서 구체적인 수업을 구현하면
public class MyThreadTask extends ThreadTask{
@Override
Object do_in_background() {
progress.primary_max = 5;
for (int cur = 0 ; cur < 5 ; cur++) {
progress.primary = cur;
publish();
Thread.Sleep(3000);
}
}
}
나는이과 같이 호출하는 활동 업데이트 :이 같은 mething
static final string TAG ="my_main_activity";
MyDataFragment _data; //this is a datafragment, a fragment with retaininstancestate , and a public `MyThreadTask task` variable
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (_data == null) {
_data = (MyDataFragment)getFragmentManager().findFragmentByTag(TAG + "_data");
if (_data == null) {
_data = new MyDataFragment();
getFragmentManager().beginTransaction().add(_data, TAG + "_data").commit();
}
}
if (_data.task != null) {
_data.task.register(this);
}
}
@Override
protected void onDestroy() {
super.onDestroy();
if (_data.task != null) {
_data.task.remove(this);
}
}
이 내가하고자 할 때 항상 올바른 스레드
에 대한 참조가 있는지 확인합니다을 내가 그렇게하는 일을 시작해라.
button.setOnClickListener((v) -> {
if (_data.task != null) return; //to make sure only one thread starts at a time
_data.task = new MyThreadTask();
_data.task.register(this);
_data.task.start(); //this is not thread's start, it is mine, it does other things too
})
그리고 내가 끝내면 그것은 void f 내가 지금처럼 처리 inished (개체 결과) :
여기void finished(Object result) {
try {
//get result;
} finally {
_data.task.remove(this);
_data.task = null;
}
}
내 질문은 :
가) 필요한 동기화로 내 관찰자 방법을 선언한다? 나는 그것을 확실히하기 위해 행동을했으나, 활동이 파괴되고 다시 만들어지면 같은 실에서 일어날까요? onDestroy 동안 관찰자가 제거되는 동안 progress_update가 발생할 수있는 기회가 있습니까?
b) 스레드가 완료되고 구성 변경 중에 post_execute (중요한)를 호출하면 어떻게됩니까? 업데이트가 손실됩니까?
c) 현재 관찰자가 없으므로 업데이트가 손실되는 경우 위의 처리 방법 중 하나가 구현되었거나 다른 방법일까요? 당신이 구성 변경을 통해 살아 백그라운드 작업을 계속
, MyDataFragment의 _data는 유지 조각입니다. isChangingConfigurations 메서드를 주셔서 감사합니다. 아마도 도움이 될 것입니다. 또한 AsyncTask에 대한 정보를 주셔서 감사합니다. AsyncTask의 코드를 살펴보고 코드에서 해당 동작을 복제 할 수 있는지 확인해 보겠습니다. – Cruces
AsyncTask의 코드를 확인한 결과, 특별한 문제는 없습니다. postexecute는 구성 변경 중에 실행됩니다. 간단한 데이터 핸들러를 사용하여 finish 데이터를 태스크에 게시하는 것으로 보입니다.이 태스크는 onpostexecute를 호출합니다. – Cruces
@Cruces 'AsyncTask' 코드에 없습니다. 구성 변경의 모든 단계를 주 스레드와 함께 게시하는 것은 프레임 워크의 결과입니다. –