当前位置: 首页 > 面试题库 >

服务崩溃并重新启动

黄俊誉
2023-03-14
问题内容

关于它有几个问题,但我总是读同一本书:“如果系统需要资源,该服务将被杀死”或“您无法构建永远运行的服务,因为它在后台运行的次数越多,越容易受到影响。被系统杀死”等等。

我面临的问题是:我的服务运行正常,并且可以预期,如果我运行我的应用程序,然后退出它,我的服务仍在运行,但是当我杀死我的应用程序时(通过转到“最近的应用程序”并对其进行扫描)离开)服务停止。在这一刻,如果我转到设置>>应用>>运行,我会看到该服务正在重新启动。过了一会儿,它又恢复了,我的服务也没有问题。

我用谷歌搜索,发现有一些我可以做的事情,但是让我们先看一下我的代码:

我通过这种方式启动服务(单击按钮后):

Intent intent = new Intent (MainActivity.this, MyService.class);
startService(intent);

我还额外添加了3个Integer,所以我有以下内容:

final Integer i, i2, i3;
i = 5; //for example
i2 = 10; //for example
i3 = 15; //for example
final Intent intent = new Intent (MainActivity.this, MyService.class);
intent.putExtra("INTEGER1", i);
intent.putExtra("INTEGER2", i2);
intent.putExtra("INTEGER3", i3);
startService(intent);

在MyService中,我有以下几点:

public class MyService extends Service
{

  AlarmManager am;
  BroadcastReceiver br;
  PendingIntent pi;
  Integer i, i2, i3;

  @Override
  public void onCreate()
  {
    super.onCreate();
    am = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
    pi = PendingIntent.getBroadcast(this, 0, new Intent("anyany"); 0) //Why those zeros?

    br = new BroadcastReceiver ()
    {
      public void onReceive (Context context, Intent i) {
        new thread(new Runnable()
        {
          public void run()
          {
            //do something
          }
        }).start();
      }
    };
  }

  @Override
  public void onStartCommand(Intent intent, int flags, int startId)
  {
    super.onStartCommand(intent, flags, startId);
    try
    {
      i = intent.getIntExtra("INTENT1", 0) // I don't understant yet why this zero are here
      i2 = intent.getIntExtra("INTENT2", 0)
      i3 = intent.getIntExtra("INTENT3", 0);
    }
    catch(NullPointerException e) {}

    this.registerReceiver(br, new IntentFilter("anyany"));

    new thread(new Runnable()
    {
    public void run()
      {
      am.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock. elapsedRealtime() + i*1000, i2*1000, pi);
      }
    }).start();
  return START_REDELIVER_INTENT; //so I can get my Extra even with my Activity closed
}

我的onDestroy:

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

我也有onBind()方法(没有@Override),但是它返回null。我在Google上搜索了很多,并尝试在前台运行该服务,所以我做到了这一点(在onStartCommand内部):

Notification n = new Notification(R.drawable.ic_laucher), getText(R.string.app_name), System.currentTimeMillis());
PendingIntent npi = PendingIntent.getActivity(this, MainActivity.class);
n.setLatestEventInfo(this, getText(R.string.notification_title), getText(R.string.notification_message), npi);
startForeground(3563, n);

我的通知出现,当我单击它时,我的应用程序运行,但是我的服务问题未得到解决(我相信它仍然不会在前台运行)。通知也重新启动。

我还删除了Try catch,并为整数定义了一个值(所以我没有使用getIntExtra()方法),但是没有任何改变

经过几次测试后,我尝试查看日志,当我杀死我的应用程序时,我收到以下消息:计划重新启动崩溃的服务。

那么,由于某种原因,我的MainActivity死亡时我的服务崩溃了,为什么?这里的目的不是要以无法杀死的上帝来改造服务(我认为这根本不可能,WhatsApp运行了105个小时!),而是防止我的应用程序死后服务不会崩溃。

我不知道这是否有帮助,但这是我在Manifest.xml中添加的内容

<Activity android:name = ".MyService"/>
<service android:name ="Myservice" android:enabled="true" android: exported="false"/>
<uses-permission android:name="android.permission.WAKE_LOCK"/>

最小API = 9,目标API =17。运行时服务的大小:大约3MB。

希望我能说清楚我的英语,对不起。

PS:整个代码都按预期运行,因此,如果您看到任何sintax错误,可以随意进行编辑。

编辑

如果我添加android:isolatedProcess="true"<service>在AndroidManifest.xml我收到的logcat此错误:java.lang.RuntimeException: Unable to create a service in com.mycompany.myapp.myservice: java.lang.SecurityException: Isolated process not allow ed to call getIntentSender

当我使用它启动服务时,MainActivity不显示任何错误,仅服务崩溃。


问题答案:

我终于找到了解决方案!我从服务中删除了AlarmManager,该服务不再兑现,但我必须使用它

问题是用户从“最近使用的应用程序”中删除该应用程序后,服务崩溃,因此我所做的是防止该应用程序出现在该窗口中。将以下内容作为以下项的子项添加到您的AndroidManifest.xml中:<activity>

android:excludeFromRecents="true"

现在,当用户从您的应用程序退出时,它不会出现在最近的应用程序窗口中,这意味着系统在您退出活动后立即将其杀死,因此不会浪费任何资源。

PS:别忘了将服务设置为在单独的进程中运行,将以下内容添加到您的AndroidManifest.xml中,作为 <service>

android:process=":remote"

编辑-找到真正的解决方案

经过大量研究和研究(数月的研究),我深入研究了android API,这是一个发现,这是仅在API 16+上才出现的预期行为,android
arquiteture的更改改变了PendingIntents的方式是由系统广播的,因此Google添加了标志FLAG_RECEIVER_FOREGROUND,您必须将此标志传递给要用作参数的intent
PendingIntent.getBroadcast(),这是一个示例:

if(Build.VERSION.SDK_INT >= 16)     //The flag we used here was only added at API 16    
    myIntent.setFlags(Intent.FLAG_RECEIVER_FOREGROUND);
    //use myIntent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); if you want to add more than one flag to this intent;



PendingIntent pi = PendingIntent.getBroadcast(context, 1, myIntent, 0); // the requestCode must be different from 0, in this case I used 1;

早于API 16的Android版本将按预期运行,如果您从“最近使用的应用”页面中删除该应用,该服务不会崩溃。



 类似资料:
  • 问题内容: 我建立了一个appWidget,它在他的onEnabled()方法上注册了一些服务。 问题是,在我使用内置的任务管理器的“清除内存/内存”之后,appWidget视图崩溃(所有appWidgets TextView的文本均设置为默认值(TextView)),并且服务停止运行并且永远不会重启。 仅在设置了小部件一段时间后才会发生这种情况,如果在设置小部件后立即清理内存/内存,则不会发生错

  • 我正在尝试制作一个粘性服务,该服务在死亡后不久就会重新启动(例如,因为Android已经杀死了它以释放内存)。(Un)幸运的是,我在Android 5.0.1上,它有一个漂亮的内存泄漏错误,使真正的测试变得容易。 看着我看到: 后来时间上升到3M,使其不可接受。 我试图使用AlarmManager和重新启动意图来解决这个问题: 然而,这没有帮助。我在日志中找不到任何信息,所以可能是AlarmMan

  • 我在这里遇到了一个问题,我想前台服务应该一直运行到它的任务完成,一旦任务完成,前台服务应该停止。但这里的问题是,即使它的前台服务——当用户仅在牛轧糖版本中关闭应用程序时,该服务也会被终止。我已经检查了Marshamallow、Oreo、Android pie版本,场景运行良好。但在牛轧糖和小米手机中,这种情况并不正常。 下面是我作为演示运行的服务代码 下面是从活动启动服务的代码 我认为start

  • 严重:初始化连接器[connector[HTTP/1.1-8080]]org.apache.catalina.LifecyCleException失败:尝试为组件[connector[HTTP/1.1-8080]]进行无效的生命周期转换([before_init]),该组件处于状态[INITIALIZED],位于org.apache.catalina.util.LifecyCleBase.inva

  • 我们在Android8.1及以上版本中偶然发现了一个我们以前从未见过的问题,不幸的是,这使得我们的应用程序对我们的用户来说不太方便。在Android 8.1及以上版本中,当用户刷屏杀死应用程序时,后台粘性服务不会重新启动。

  • 每当UwAmp重启自己(例如,当我修改php.ini或切换到不同版本的php),它经常崩溃Chrome我打开的任何页面,无论是我正在UwAmp测试的页面还是完全不相关的东西比如Facebook它们是空的,我必须重新加载它们。有时它完全关闭Chrome,我必须重新启动它,我收到消息说Chrome意外关闭。什么给?这是已知的错误吗?有什么办法可以预防吗?UwAmp是如何控制Chrome的?这是在Win