2010-12-02 9 views
6

У меня есть требование перезапустить приложение, когда пользователь изменяет предпочтение. Очистка стека не помогает мне, так как это не отменяет вызовы службы backend. Я хочу убить сам процесс приложения. Я используюКак перезапустить приложение для Android из приложения

Process.killProcess(Process.myPid()); 

и он работает для меня, чтобы убить приложение. Но мне нужно перезагрузить приложение. Средство уничтожает процесс и запускает новый процесс, чтобы приложение снова начиналось снова.

Есть ли способ сделать это?

Заранее спасибо.

+0

Я интересно, если это необходимо для целей тестирования или если его что-то что вам нужно делать в реальном приложении? – jcollum 2010-12-05 16:36:10

ответ

4

Android не предназначен для этого, и это не «требование». Это реализация. Что именно требуется? Почему вы не можете проектировать свое приложение для обработки изменений предпочтений без перезагрузки? Это кажется очень плохим решением.

+0

У меня есть несколько тестовых сред, и у них есть свои особые свойства для установления соединения с серверами, специфичными для среды. Поэтому, когда мы переключаемся между средами, мне нужно перезапустить все приложение с новыми свойствами. – AKh 2010-12-02 22:04:48

+0

Так это для тестирования кода или производственного кода? Если это для тестирования, то обязательно продолжайте и убейте этот процесс. Затем вы можете перезапустить его в своем тестовом коде. – Falmarri 2010-12-02 22:20:58

+0

Я отказался от идеи перезапуска приложения, вместо этого я перезагружаю свое HTTP-соединение, чтобы восстановить новый, поскольку раньше было тайм-аут, если устройство простаивает более 20 минут. Вот почему мы хотели перезапустить приложение, чтобы восстановить новое соединение для подключения к нашим серверам. – AKh 2010-12-08 18:55:05

2

Проектирование ОС, чтобы приложение могло перезапустить себя, похоже на очень плохую идею. ОС Android должна быть бесплатной убить процесс, чтобы освободить память - если приложение может перезапустить себя, освобожденная память снова будет использована. Я согласен с Falmarri, вам нужно выяснить, почему ваше приложение не может справиться с изменением предпочтений на лету.

5

Это не то, что нужно, вероятно, попытаться сделать за пределами тестовой среды.

Тем не менее, две идеи:

1) Установка будильника на некоторое время в ближайшем будущем, а затем убить ваш процесс

2) Стартовое что-то еще (возможно, небольшой собственный процесс или оболочки скрипт), который обнаружит вашу смерть и перезапустит вас с намерением.

Вы также можете попробовать стрелять из намерения начать себя, а затем быстро умереть, но это звучит как потенциальное состояние гонки в зависимости от реализации. Если вы схватили связующее fd из/proc и сделали зло в собственном коде, вы могли бы скрыть намерение таким образом, чтобы ваше приложение вышло из обращения по возврату из ioctl ...

0

вот Идея:

есть служба, которая имеет другой процесс, чем один из ваших остальных компонентов (действия, услуги, ...).

Чтобы перезагрузить приложение, позвоните в эту службу, и что он будет делать, это убить процессы других компонентов приложения, а затем отправить намерение в действие, к которому вы хотите перейти.

Это просто идея, так как я ее никогда не тестировал. сообщите мне, если он работает, и обновите вопрос, чтобы включить ответ, если он действительно работает.

2

Так как вы сделали с убивая процесс, чтобы перезапустить приложение, используйте этот код:

Intent i = getBaseContext().getPackageManager().getLaunchIntentForPackage(getBaseContext().getPackageName()); 
i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); 
startActivity(i); 
1

Если вы действительно хотите, чтобы перезагрузить вашу деятельность в том числе убийства текущего процесса, попробуйте следующий код. Поместите его в HelperClass или где вам это нужно.

public static void doRestart(Context c) { 
     try { 
      //check if the context is given 
      if (c != null) { 
       //fetch the packagemanager so we can get the default launch activity 
       // (you can replace this intent with any other activity if you want 
       PackageManager pm = c.getPackageManager(); 
       //check if we got the PackageManager 
       if (pm != null) { 
        //create the intent with the default start activity for your application 
        Intent mStartActivity = pm.getLaunchIntentForPackage(
          c.getPackageName() 
        ); 
        if (mStartActivity != null) { 
         mStartActivity.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); 
         //create a pending intent so the application is restarted after System.exit(0) was called. 
         // We use an AlarmManager to call this intent in 100ms 
         int mPendingIntentId = 223344; 
         PendingIntent mPendingIntent = PendingIntent 
           .getActivity(c, mPendingIntentId, mStartActivity, 
             PendingIntent.FLAG_CANCEL_CURRENT); 
         AlarmManager mgr = (AlarmManager) c.getSystemService(Context.ALARM_SERVICE); 
         mgr.set(AlarmManager.RTC, System.currentTimeMillis() + 100, mPendingIntent); 
         //kill the application 
         System.exit(0); 
        } else { 
         Log.e(TAG, "Was not able to restart application, mStartActivity null"); 
        } 
       } else { 
        Log.e(TAG, "Was not able to restart application, PM null"); 
       } 
      } else { 
       Log.e(TAG, "Was not able to restart application, Context null"); 
      } 
     } catch (Exception ex) { 
      Log.e(TAG, "Was not able to restart application"); 
     } 
    } 

Это также будет повторно инициализировать классы jni и все статические экземпляры.

0

Если это проект предприятия, в котором вы контролируете устройства, вы можете легко установить второе приложение, которое будет функционировать как сторожевой таймер для первого. Один из моих клиентов использует такое приложение сторожевого таймера для обработки таких вещей, как перезагрузка при ночном перезагрузке (по неизвестным, нетехническим причинам), а также для проверки и обновления самообслуживаемых обновлений (не Play Store).

Но если вы действительно хотите к нему из вашего приложения, вы можете сделать следующее (в том числе и ваш процесс глушения выше):

Process.killProcess(Process.myPid()); 
AlarmManager am = (AlarmManager) this.getSystemService(Context.ALARM_SERVICE); 
am.set(AlarmManager.ELAPSED_REALTIME, SystemClock.elapsedRealtime() + 500 /* half a second*/, 
     PendingIntent.getActivity(this, 0, new Intent(this, this.getClass()), 
           Intent.FLAG_ACTIVITY_NEW_TASK)); 
Смежные вопросы