How to make main Acivity wait for subactivity in Android?

I cause subactivity from the main action. This subactivity should take a few digits from the user (for this I use Edit text control), save them in a static variable in another class and complete. I want the main activity to expect sub-dependencies, but both of them are running simultaneously. Even doing this does not help:

Thread t = new Thread(new Runnable(){ public void run(){ Log.v("==================", "run "+new Date()); startActivityForResult(new Intent(ctx,myCustomSubactivity.class),1); } }); Log.v("==================", "calling run "+new Date()); t.start(); try { t.join(); } catch (InterruptedException e) {Log.v("==================", "can't join");} Log.v("==================", "back from activity "+new Date()); 

Do you know how to make the main activity wait? The Thread.wait () method is not supported on Android (software error).

+6
android android-activity wait blocking subactivity
May 21 '10 at 6:13
source share
5 answers

I agree with Nikolai, this is definitely an android way.

Launch subactivity with startActivityForResult in using the setResult sub-activity to add the result code and intent with all the numbers you need in the dataset.

In your first operation, rewrite onActivityResult and extract the numbers from the intent.

If you use a static variable, it seems easier at the first moment, but it is very uncertain, and in some cases it may not work. If your program is sent to the background, your actions will be saved, but if there is not enough memory in the phone, the system will close your program, and after the user resumes it, everything will look as soon as the user leaves it, but static variables will be recreated until their initialization value.

Try to get used to how the android life cycle works . Using this approach will result in less memory usage and a significantly better user experience.

+3
May 21 '10 at 9:11 a.m.
source share

Maybe I missed something, but why not just use the startActivityForResult and onActivityResult ? You can get the result from your subactivity from the intention with which it was given. Edit: BTW, as I understand it, if you run the Object.wait() from Activity code, if you keep the UI slot, this can lead to an Application not responding .

+7
May 21 '10 at 8:50 a.m.
source share

Check out the Notepad example , it covers exactly this situation. And, as others have said, the Android way is to have your first launch run your second action (and not sub-activity!) And listen for the response asynchronously (do not pause or wait, no need to join, etc.).

+3
May 21 '10 at 17:44
source share

Well ... you can do it like this (by the way, there is no direct way):

You have a singleton class, call Monitor on it:

 public class Singleton { private Singleton() { } private static Singleton instance = new Singleton(); public static Singleton getInstance() { return instance; } } public class ParentActivity extends Activity { private void startAndWait() { Intent i = new Intent(); // initialize i startActivityForResult(i); Singleton si = Singleton.getInstance(); synchronized(si) { si.wait(); } //do remaining work } } public class ChildActivity extends Activity { protected void onCreate(Bundle savedInstance) { //do all the work Singleton si = Singleton.getInstance(); synchronized(si) { si.notify(); } } } 
+2
May 21 '10 at 6:22
source share

I'm not here to judge if it is good or not, but if you really need activity to wait for sub-activity, you can try this approach:

  • define an object (lock) by which two actions are synchronized; it can (should) also work as an object for exchanging data between these two actions and, therefore, should be defined as static
  • in parent activity, run the async task (since the main thread of the user interface cannot be pending)
  • in an asynchronous task, run your sub-asset.
  • asynchronous task is waiting for a lock until notification
  • the sub-activity does everything it needs and notifies the waiting thread at completion

I did a similar thing in my application, and IMHO had a good reason for this (in order not to bother the user with the login screen when starting or resuming the application, the application tries to reuse the credentials stored in a secure place, and only so Yes, in In principle, any activity in my application can be "paused" and waiting until the user provides the correct credentials in the login activity, which ends the login screen, and the application continues exactly where it was obtained is suspended (the parent activity).

In the code, it will be something like this:

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); } } 
+2
Feb 25 '15 at 10:35
source share



All Articles