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

发布于 2024-12-11 04:10:17 字数 2181 浏览 0 评论 0原文

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

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

这种情况只会在小部件设置一段时间后发生,如果我在小部件设置后立即清理内存/RAM,则不会发生错误,但我猜这与任务管理器清理 RAM 的方法有关。

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

我们将很高兴提供想法和解决方案!谢谢先进,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();
  }

I've built an appWidget which register some services on his onEnabled() method.

The problem is that after I use the built in Task Manager's Clean Memmory/Ram, the appWidget view crashes (all the appWidgets TextView's text is set to default (TextView)) and the Services stop running and never restarts.

This only happen after some time the widget is set, and if I Clean Memmory/Ram right after the widget is set the bug does'nt happen, but I guess this is related to the Task Manager's method of cleaning RAM.

So finally, my question is: Is there a way to tell the android system to reStart those services? as other appWidgets I've downloaded through the market is seem to continue working fine after this procedure.

Will be happy for ideas and solutions! Thanks advanced, Gal :)

some code that I use:

the onEnabled() method in the 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);
}

Some methods from one of the Services (others services are very similiar as this is from their abstract method):

 @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();
  }

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

一桥轻雨一伞开 2024-12-18 04:10:17

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

刚刚添加了 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) 中的静态方法,用于注册所需的服务。

希望它也能帮助你=]

After a lot of research and some attempts, Solved it! :)

Just added BroadcastReciever listening to package changes and updates:

register receiver in the manifest file:

<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 - called in particular to notify application update.
  • PACKAGE_RESTARTED - called when most memmory cleaners are cleaning memmory.
  • the "data" row is used to monitor action applied for the specific package.

Within this reciever I start my services again, and restarts the widget view (calling it's onUpdate() method in this case):

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) is a static method in my AppWidgetProvider classes (MyWidget_1x1/MyWidget_2x2) which registers the needed services.

Hope it will help you too =]

双手揣兜 2024-12-18 04:10:17

上面的内容确实捕获了重新启动事件,但无法捕获清除内存事件,因为 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 使小部件上的触摸事件起作用的实际内容。

The stuff above does catch the reboot event but fails to catch the clear memory event, because the android.intent.action.PACKAGE_RESTARTED is not sent to the package itself.

I solved this by adding a Service. This service gets its onCreate() called on a clear memory event. Note that you have to start the service with a startService call, which I call from the 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); 

The Service code is like:

@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; 
  }

with ping the actual stuff which makes the touch events on the widgets work.

硬不硬你别怂 2024-12-18 04:10:17

感谢您成功研究自己的解决方案。你为我指明了正确的方向。我遇到了类似的问题,应用程序小部件在重新启动或重新启动后不会再更新,也不会再响应按钮单击。

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

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

这也归功于:手机重启后接近警报不起作用

Thanks for successfully researching your own solution. You pointed me in the right direction. I was having a similar problem where the appwidget would not update anymore after a reboot or power cycle, neither would it respond to button clicks anymore.

What I did was first add the following to the manifest:

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

Then I created a BootReceiver.java file with something like the following. In my case I had to recreate the alarm and pending intents for the buttons.

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

Some credit for this also goes to: Proximity Alerts not working after phone reboot

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文