2012-03-30 97 views
0

我想阻止應用程序的執行(假設A),直到另一個應用程序(讓我們說B)發送一個意圖。我知道阻塞無限循環的線程並不好,但爲了安全起見,我確實需要保證在收到Intent之前不會執行A的代碼。在阻止應用程序A之前,我使用Intent啓動另一個應用程序B.這樣,應用程序A將有機會生存直到B完成。爲此,我目前正在寫了一個阻塞循環,例如:如何阻止主Android線程,直到收到一個意圖?

context.startActivity(message); // starting app B 

// Blocking A 
while (condition) // waits an authorization from B 
{ 
    Thread.sleep(5000); 
    // some checks can be done here to modify the condition evaluation 
    // for example, check the Intents received from B 
} 
// (Secured zone) 
// Some code that should not be executed before that the condition is true 

我嘗試了很多解決方案,以檢查意向接待:

  • 使用broadcastreceiver是不可能的,因爲主線程會從來沒有機會處理收到的Intent
  • 使用綁定服務到另一個應用程序來獲取信息:再次,onConnectedService方法將不會被調用,因爲主線程不會處理該事件。
  • 使用第二個獨立進程將被通知傳入的意圖:這很好。第二個進程被通知,但它不能通知主線程發生了什麼事情!
  • 使用第二個線程來檢查接收到的Intent,綁定服務到B:沒辦法,第二個線程不負責處理消息。

也許我缺少一個簡單的解決方案,但我開始想,我試圖做一些事情,與Android的理念真的很矛盾......

編輯:另一個限制是「安全區」部分代碼無法在我的程序中的其他位置移動...

+1

你怎麼知道何時收到意向..? – ngesh 2012-03-30 08:14:47

+0

我想你應該找到另一種防止你的代碼被運行的方法。鎖定主線程,用戶交互以及因爲系統很可能認爲活動被凍結並詢問用戶他/她是否想要關閉活動永遠不是一個好主意。 – Jave 2012-03-30 08:16:30

+0

例如,我可以使用BroadcastReceiver捕獲Intent,它在第二個進程中執行onReceive方法,如果我放入清單中: JFL 2012-03-30 08:41:57

回答

0

主線程中的Thread.sleep()不是一個好主意。 您是否嘗試覆蓋活動A中的onNewIntent()方法以處理活動B發送的意圖?

+0

我沒有嘗試過,但我的約束是我想避免執行應用程序A的其餘代碼。應用程序B嚮應用程序發送授權一個被允許執行代碼的其餘部分。如果我不阻止主線程,我相信我會成功地從B獲取Intent,但是我會違反我的約束... – JFL 2012-03-30 08:54:53

+0

你不應該以這種方式阻塞主線程。我最好的建議是重新考慮你的方法。可能會使用工作線程(AsyncTask類)在後臺運行任務。 – Ika 2012-04-02 08:54:46

0

它認爲你應該使用另一種方法: 運行appA和appA內部,你應該做的第一件事是運行appB並且等到它的結果。 當你得到結果時,繼續運行appA。

僞代碼,因爲我看到它:

AppA() 
{ 
    run app B; 
    if (b return needed result) 
    { 
    rest of code of AppA... 
    .... 
    .... 
    } 
} 
+0

這是我試圖做的。但是不可能等待B的結果,因爲應用程序A和B都將以併發方式執行。即使使用對startActivityForResult()的調用也不會阻止,因爲當Android調用onActivityResult()時,結果是異步獲取的。 – JFL 2012-03-30 08:51:53

0

我找到解決我的問題的醜陋的方式。在暫停應用程序A之後,應用程序A正在等待來自在不同過程中執行的B的意圖。然後,當這個進程收到來自B的消息時,它將信息寫入文件。 A thas的主線程被阻塞到循環中,定期讀取文件。當文件包含預期的信息時,條件變爲false並且線程被解除阻塞。

在細節,它提供了:

到應用程序答:

Thread.sleep(1000); 

context.startActivity(message); // starting app B 

// Blocking A 
while (!auth) // waits an authorization from B 
{ 

try { 
    FileInputStream fIn = c.openFileInput("authorization.txt"); 
    InputStreamReader isr = new InputStreamReader(fIn); 
    char buf[] = new char[1]; 
    isr.read(buf); 
    String res = new String(buf); 
    isr.close(); 

    if (res.equals("1")) 
    { 
    auth = true; 
    System.out.println("READ OK"); 
    } 
} 

在應用程序A,廣播接收器應該在清單中聲明瞭Android:過程標籤 「:P2」:

<receiver android:name="reporter.ReporterReceiver" android:process=":p2"> 
    <intent-filter> 
    <action android:name="andro.jf.reporterResponse" /> 
    <category android:name="android.intent.category.DEFAULT" /> 
</intent-filter> 
</receiver> 

和接收器應該是:

public class ReporterReceiver extends BroadcastReceiver { 

public void onReceive(Context context, Intent intent) { 
    Bundle extra = intent.getExtras(); 

    System.out.println("ANSWER RECEIVED"); 

    if (extra != null) 
    { 
    String auth = extra.getString("authorization"); 
    //Reporter.authorization = contact; 

    // Write the string to the file 
    try { 
     FileOutputStream fOut = context.openFileOutput("authorization.txt", Context.MODE_PRIVATE); 
     OutputStreamWriter osw = new OutputStreamWriter(fOut); 
     osw.write(auth); 
     osw.flush(); 
     osw.close(); 
    } catch (IOException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } 
    } 
} 
} 

我知道,這是醜陋的......但它起作用,至少在模擬器中。

相關問題