“清除内存”+ appWidget崩溃后,服务不会重新启动

时间:2011-10-22 21:58:06

标签: java android service widget

我已经构建了一个appWidget,它在onEnabled()方法上注册了一些服务。

问题是,在我使用内置的任务管理器的Clean Memmory / Ram后,appWidget视图崩溃(所有appWidgets TextView的文本都设置为默认值(TextView)),服务停止运行,从不重启。

这只发生在设置小部件一段时间后,如果我在设置小部件后立即清理Memmory / Ram,则不会发生错误,但我想这与任务管理器清理RAM的方法有关。 / p>

所以最后,我的问题是:有没有办法告诉Android系统重新启动这些服务?我通过市场下载的其他应用程序似乎在此过程后继续正常工作。

对于想法和解决方案感到高兴!谢谢先进,Gal:)

我使用的一些代码:

appWidget中的onEnabled()方法:

@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 个答案:

答案 0 :(得分:9)

经过大量的研究和一些尝试,解决了它! :)

刚刚添加了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 - 当大多数记忆清洁工正在清理记忆时打电话。
  • “data”行用于监控应用于特定包的操作。

在这个接收器中,我再次启动我的服务,并重新启动widget视图(在这种情况下调用它的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 :(得分:1)

上面的内容确实捕获了重启事件,但无法捕获清除内存事件,因为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实际的东西,使小工具上的触摸事件发挥作用。

答案 2 :(得分:0)

感谢您成功研究自己的解决方案。你指出我正确的方向。我遇到了类似的问题,即appwidget在重启或重启后不再更新,也不再响应按钮点击。

我所做的是首先将以下内容添加到清单中:

<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 */
  }
}

这也归功于:Proximity Alerts not working after phone reboot