Служба не перезапускается после сброса «Очистить память» + appWidget - PullRequest
3 голосов
/ 23 октября 2011

Я создал appWidget, который регистрирует некоторые службы в его методе onEnabled ().

Проблема заключается в том, что после использования встроенного в Task Memmory / Ram диспетчера задач происходит сбой представления appWidget (всеappWidgets Текст TextView имеет значение по умолчанию (TextView), и службы перестают работать и никогда не перезапускаются.

Это происходит только через некоторое время, когда виджет установлен, и если я очищаю память / баран сразу после установки виджетаошибка не происходит, но я думаю, что это связано с методом очистки ОЗУ в диспетчере задач.

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

Будем рады идеям и решениям!Спасибо, Gal:)

некоторый код, который я использую:

метод onEnabled () в appWidget:

@Override
public void onEnabled(Context context) {
    super.onEnabled(context);

    Intent newinIntent = new Intent(context, CallService_1x1.class);
        context.startService(newinIntent);

    newinIntent = new Intent(context, SmsService_1x1.class);
        context.startService(newinIntent);
}

Некоторые методы из одной из служб (другие услуги очень похожи, поскольку это из их абстрактного метода):

 @Override
  public int onStartCommand(Intent intent, int flags, int startId) {
      // We want this service to continue running until it is explicitly
      // stopped, so return sticky.
      Log.d("SERVICE-SMS","CallMonitorService - onStartCommand created");
      return START_STICKY;
  } 

@Override
  public void onCreate() {
    super.onCreate();
    context = this.getApplicationContext();
    Log.d("SERVICE-SMS","CallMonitorService created");
    registerObserver();
  }

@Override
  public void onStart(Intent intent, int startId) {
    super.onStart(intent, startId);
  }

  @Override
  public void onDestroy() {
    unregisterObserver();
    super.onDestroy();
  }

  @Override
  public IBinder onBind(Intent intent) {
    return null;
  }
  /**
   * Start the service to process that will run the content observer
   */
  public static void beginStartingService(Context context) {
   Log.d("SERVICE-SMS","CallMonitorService: beginStartingService()");
    context.startService(new Intent(context, CallService.class));
  }

  /**
   * Called back by the service when it has finished processing notifications,
   * releasing the wake lock if the service is now stopping.
   */
  public static void finishStartingService(Service service) {
    Log.d("SERVICE-SMS","CallMonitorService: finishStartingService()");
    service.stopSelf();
  }

Ответы [ 3 ]

9 голосов
/ 24 октября 2011

После долгих исследований и некоторых попыток, Решил это!:)

Только что добавленный BroadcastReciever прослушивает изменения и обновления пакета:

зарегистрирует получатель в файле манифеста:

<receiver android:name=".receivers.onRestartReciever">
        <intent-filter>
            <action android:name="android.intent.action.PACKAGE_REPLACED" />
            <action android:name="android.intent.action.PACKAGE_RESTARTED" />
            <data android:scheme="package" android:path="my.Package.Path" />
        </intent-filter>
  • PACKAGE_REPLACED - вызывается, в частности, для уведомленияобновление приложения.
  • PACKAGE_RESTARTED - вызывается, когда большинство очистителей памяти очищают память.
  • строка «данные» используется для отслеживания действий, выполняемых для определенного пакета.

В этом приемнике я снова запускаю свои службы и перезапускаю представление виджета (в данном случае вызывая его метод onUpdate ()):

public class onRestartReciever extends BroadcastReceiver {

@Override
public void onReceive(Context context, Intent intent) {
    // TODO Auto-generated method stub
    Log.d("DEBUG", "onRestartReciever");

    // Register Services
    MyWidget_1x1.registerServices(context);
    MyWidget_2x2.registerServices(context);

    // reInitialize appWidgets
    AppWidgetManager appWidgetManager=AppWidgetManager.getInstance(context);

    MyWidget_1x1 widget1x1=new CallWidgi();
    widget1x1.onUpdate
    (context,
         AppWidgetManager.getInstance(context),
            widget1x1.getIDs(context, appWidgetManager));

    MyWidget_2x2 widget2x2=new CallWidgi2();
    widget2x1.onUpdate(context,
                        AppWidgetManager.getInstance(context),
                            widget2x2.getIDs(context, appWidgetManager));
    }
}

registerServices (Context) - статический метод в моих классах AppWidgetProvider (MyWidget_1x1/ MyWidget_2x2), который регистрирует необходимые сервисы.

Надеюсь, это вам тоже поможет =]

1 голос
/ 06 ноября 2013

Вещи выше перехватывают событие перезагрузки, но не могут перехватить событие очистки памяти, потому что android.intent.action.PACKAGE_RESTARTED не отправляется самому пакету.

Я решил это, добавив Сервис,Эта служба вызывает метод onCreate () для события очистки памяти.Обратите внимание, что вы должны запустить службу с помощью вызова startService, который я вызываю из AppWidgetProvider.

Intent i= new Intent(context, CTService.class);
// potentially add data to the intent
i.putExtra("KEY1", "Value to be used by the service");
ComponentName name = context.startService(i); 

Код службы имеет вид:

@Override
public void onCreate()
{
    Log.d(TAG,"onCreate");
    ping();
}
 @Override
  public int onStartCommand(Intent intent, int flags, int startId) {
    Log.d(TAG,"onStartCommand: "+intent.getAction());
    //TODO do something useful
    ping();
    return Service.START_STICKY; 
  }

с ping фактическимвещи, которые заставляют сенсорные события работать на виджетах.

0 голосов
/ 17 декабря 2011

Спасибо за успешное исследование вашего собственного решения.Вы указали мне в правильном направлении.У меня была похожая проблема, когда приложение больше не обновлялось после перезагрузки или отключения питания, а также не отвечало на нажатия кнопок.

Сначала я добавил следующее в манифест:

<receiver android:name=".BootReceiver">
  <intent-filter>
    <action android:name="android.intent.action.BOOT_COMPLETED"/>
  </intent-filter>
</receiver>

Затем я создал файл BootReceiver.java с чем-то вроде следующего.В моем случае мне пришлось воссоздать тревогу и ожидающие намерения для кнопок.

public class BootReceiver extends BroadcastReceiver
{
  /* 
   * after reboot widget appears to stop working and becomes unresponsive to clicks
   * this broadcast receiver will create new alarm and refresh pending intents
   */

  @Override
  public void onReceive(Context context, Intent intent)
  {
    /* do your stuff here, mostly just copy&paste from other places */
  }
}

Некоторый кредит на это также идет: Не сбрасываются уведомления о сближении после перезагрузки телефона

...