簡體   English   中英

如何強制主要Acivity在Android中等待子活動?

[英]How to force main Acivity to wait for subactivity in Android?

我稱之為主要活動的子活動。 這個子活動應該從用戶那里拿幾個數字(我使用編輯文本控件來實現這一點),將它們保存到另一個類中的靜態變量並終止。 我希望主要活動等待子活動,但兩者都只是同時運行。 即使這樣做也無濟於事:

     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());

你知道如何強迫主要活動等待嗎? Android中不支持Thread.wait()方法(程序拋出錯誤)。

可能是我遺漏了一些東西,但為什么不只是使用startActivityForResultonActivityResult機制? 你可以從你產生的意圖中獲得你的潛意識的結果。
編輯:BTW據我所知,如果你將從Activity代碼運行Object.wait()如果將保持UI胎面whitch可能導致Application not responding錯誤。

我同意Nikolay這絕對是安卓的方法。

使用setResult在子活動中使用startActivityForResult啟動子活動,以使用數據包中所需的所有數字添加結果代碼和意圖。

在您的第一個活動中,覆蓋onActivityResult並從Intent中檢索數字。

如果你使用靜態變量,這在第一時間似乎更容易,但是它非常不安全,並且在某些情況下這可能不起作用。 如果您的程序被發送到后台,您的活動將被保存,但如果手機內存不足,系統將關閉您的程序,用戶恢復后,一切看起來就像用戶離開它的那一刻,但靜態變量將被重新創建為他們的初始化值。

嘗試習慣android 活動生命周期的工作方式。 使用此方法將導致更少的已用內存和更好的用戶體驗。

查看記事本示例 ,它涵蓋了這種情況。 正如其他人所說,Android的方式是讓你的第一個活動啟動你的第二個活動(不是子活動!)並異步監聽響應(不是暫停或等待,不需要加入等)。

我不是來判斷它是否是一個好的模式,但如果你真的需要一個等待子活動的活動,你可以嘗試這種方法:

  • 定義兩個活動同步的對象(鎖); 這可以(應該)也作為在這兩個活動之間交換數據的對象,因此應該被定義為靜態的
  • 在父活動中,啟動異步任務(因為UI主線程不能處於等待狀態)
  • 在異步任務中,啟動子活動
  • 異步任務等待鎖定,直到得到通知
  • 子活動執行它需要的任何操作,並在完成時通知等待的線程

我在我的應用程序中做了類似的事情,恕我直言有充分的理由(在應用程序啟動或恢復時不打擾用戶登錄屏幕,應用程序嘗試重新使用存儲在安全位置的憑據,以防萬一它失敗,它顯示了這個登錄屏幕。所以是的,基本上我的應用程序中的任何活動都可以“暫停”並等待用戶在登錄活動中提供正確的憑據,登錄屏幕完成后,應用程序繼續准確地暫停(在父母活動)。

在代碼中它將是這樣的:

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);
    }

}

嗯......你可以這樣做(順便說一句,這不是直接的方式):

有一個單例類,我們稱之為Monitor:

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();
           }
       }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM