Как заблокировать основной поток Android до получения намерения? - PullRequest
0 голосов
/ 30 марта 2012

Я хотел бы заблокировать выполнение приложения (скажем, A), пока другое приложение (скажем, B) не отправит Намерение. Я знаю, что блокирование потока с бесконечным циклом не очень хорошо, но я действительно должен по соображениям безопасности гарантировать, что код A не будет выполнен, пока не будет получен Intent. Непосредственно перед блокировкой приложения A я запускаю другое приложение B с помощью Intent. Таким образом, приложение A будет иметь шансы выжить, пока не закончится B. Для этого я в настоящее время написал цикл блокировки, такой как:

 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

Я испробовал множество решений для проверки приема Intent:

  • использование broadcastreceiver невозможно, так как основной поток никогда не сможет обработать полученное намерение
  • с помощью службы привязки к другим приложениям для получения информации: снова метод onConnectedService не будет вызван, поскольку основной поток не будет обрабатывать событие.
  • использование второго независимого процесса, который будет уведомлен о входящем Намерении: это работает хорошо. Второй процесс уведомляется, но не может сообщить основному потоку, что что-то произошло!
  • использование второго потока для проверки полученных Intents, привязка сервиса B: нет, второй поток не отвечает за обработку сообщений.

Возможно, мне не хватает простого решения, но я начинаю думать, что пытаюсь сделать что-то, что действительно противоречит философии Android ...

Редактировать: еще одним ограничением является то, что часть кода "защищенная зона" не может быть перемещена в другое место в моей программе ...

Ответы [ 3 ]

0 голосов
/ 30 марта 2012

Думаю, вы должны использовать другой подход: Запустите appA и внутри appA, первое, что вы должны сделать, это запустить appB и дождаться его результата. Когда вы получите результаты, продолжайте запускать appA.

Псевдокод, как я его вижу:

AppA()
{
  run app B;
  if (b return needed result)
  {
    rest of code of AppA...
    ....
    ....
  }
}
0 голосов
/ 01 апреля 2012

Я нашел уродливый способ решения своей проблемы.После приостановки приложения A приложение A ожидает намерения от B, который выполняется в другом процессе.Затем, когда этот процесс получает сообщение от B, он записывает информацию в файл.Основной поток A thas заблокирован в цикле, периодически читает файл.Когда файл содержит ожидаемую информацию, условие становится ложным, а поток разблокирован.

В деталях он дает:

В приложение A:

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

Я знаю,это некрасиво ... но работает, по крайней мере в эмуляторе.

0 голосов
/ 30 марта 2012

Thread.sleep () в основном потоке не очень хорошая идея.Вы пытались переопределить метод onNewIntent () в действии A для обработки намерений, отправленных действием B?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...