Я здесь не для того, чтобы судить, является ли это хорошим шаблоном или нет, но если вам действительно нужно занятие для ожидания подэтапа, вы можете попробовать этот подход:
- определить объект (блокировку), над которым синхронизируются эти два действия; это может (должно) также работать как объект для обмена данными между этими двумя действиями и поэтому должно быть определено как статическое
- в родительском действии запустите асинхронную задачу (поскольку основной поток пользовательского интерфейса не может находиться в состоянии ожидания)
- в асинхронной задаче, запустите ваше вспомогательное действие
- асинхронная задача ожидает блокировки, пока не получит уведомление
- дочерняя операция делает все, что ей нужно, и уведомляет ожидающий поток о завершении
Я сделал похожую вещь в своем приложении, и у IMHO была на то веская причина (чтобы не беспокоить пользователя с экраном входа в систему при запуске или возобновлении работы, приложение пытается повторно использовать учетные данные, хранящиеся в защищенном месте и только в в случае неудачи он показывает этот экран входа в систему.Так да, в принципе, любое действие в моем приложении может быть приостановлено и ожидает, пока пользователь не предоставит правильные учетные данные в действии входа в систему, после чего экран входа завершается и приложение продолжает работать именно там, где оно получено. приостановлено (в родительской активности).
В коде это будет примерно так:
ParentActivity:
public class ParentActivity extends Activity {
private static final String TAG = ParentActivity.class.getSimpleName();
public static class Lock {
private boolean condition;
public boolean conditionMet() {
return condition;
}
public void setCondition(boolean condition) {
this.condition = condition;
}
}
public static final Lock LOCK = new Lock();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.parent_layout);
// do whatever logic you need and anytime you need to stat sub-activity
new ParentAsyncTask().execute(false);
}
private class ParentAsyncTask extends AsyncTask<Boolean, Void, Boolean> {
@Override
protected Boolean doInBackground(Boolean... params) {
// do what you need and if you decide to stop this activity and wait for the sub-activity, do this
Intent i = new Intent(ParentActivity.this, ChildActivity.class);
startActivity(i);
synchronized (LOCK) {
while (!LOCK.conditionMet()) {
try {
LOCK.wait();
} catch (InterruptedException e) {
Log.e(TAG, "Exception when waiting for condition", e);
return false;
}
}
}
return true;
}
}
}
ChildActivity:
public class ChildActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.child_layout);
// do whatever you need in child activity, but once you want to finish, do this and continue in parent activity
synchronized (ParentActivity.LOCK) {
ParentActivity.LOCK.setCondition(true);
ParentActivity.LOCK.notifyAll();
}
finish();
// if you need the stuff to run in background, use AsyncTask again, just please note that you need to
// start the async task using executeOnExecutor method as you need more executors (one is already occupied), like this:
// new ChildAsyncTask().executeOnExecutor(ChildAsyncTask.THREAD_POOL_EXECUTOR, false);
}
}