我正在尝试更新我的应用程序以手动处理配置更改(尤其是屏幕转向)。Android:关于在线程运行时手动处理配置更改的问题
我对线程执行期间发生更改时发生的情况有一些疑问。
我创建了一个抽象类,我调用ThreadTask,它使用主线程的Looper的线程和处理程序向主线程发送更新。这是我的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
所以当我实现一个具体的类时它会这样mething这样的:
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);
}
}
}
和我更新调用此像这样的活动:
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;
}
}
这里是我的问题:
一)被宣告我的观测方法为synchronized有必要吗?我只是为了确保,但是当活动被销毁并重新创建时,它是否发生在同一个线程上?有没有机会例如在onDestroy期间观察者被移除时progress_update可能发生?
b)如果线程在配置更改期间完成并调用post_execute(这很重要)会发生什么?更新会丢失吗?
c)如果确实更新因为目前没有观察者而丢失,那么在我的实现或其他方法中,是否有办法处理上述问题?
预先感谢任何帮助,您可以提供
我在保留片段收留了它,MyDataFragment _data是一个保留的片段。感谢isChangingConfigurations方法,它可能会有所帮助。另外感谢有关AsyncTask的信息,我会看看AsyncTask的代码,看看我是否也可以在我的代码中复制该行为 – Cruces
嗯,我检查了AsyncTask的代码,并且我没有看到任何特殊的预防措施在配置更改期间运行postexecute。它似乎使用一个简单的处理程序发布完成数据到任务,然后调用onpostexecute,也许我错过了什么? – Cruces
@Cruces它不在'AsyncTask'的代码中。这是框架将配置更改的所有步骤发布到整个主线程的结果。 –