服务崩溃并重新启动 [英] Service crashing and restarting

查看:176
本文介绍了服务崩溃并重新启动的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有几个问题,但我总是读同样的事情:如果系统需要资源,服务将被杀死或你无法构建一个永远运行的服务,因为它在后台运行的越多,更多容易被系统杀死等等。

There are several questions about it but I always read the same thing: "the service will be killed if the system need resources" or "you can't build an service that runs forever because the more it runs in background, more susceptible it is to the system kills it" and etc.

我面临的问题是:我的服务运行良好,正如预期的那样,如果我运行我的应用程序然后退出它我的服务仍在运行,但是当我杀死我的应用程序时(通过转到最近的应用程序并将其取消)服务停止。在这一刻,如果我进入设置>> aplications >>运行,我会看到该服务正在重启。过了一会儿,它回来了,我的服务运行没有问题。

The problem I'm facing is: My service runs fine and as it is expected, if I run my app then exit it my service is still running, but when I kill my app (by going to the "recent apps" and swype it away) the service stops. In this moment, if I go to the Settings >> aplications >> running I'll see that the service is restarting. After a while, it goes back and my Service run with no problem.

我谷歌它,我找到了一些我能做的事情,但让我们先看看我的代码:

I google it and I find some things I could do but lets see my code first:

我通过这种方式启动我的服务(点击一下按钮后):

I start my service by this way (after a button click):

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

我还有3个额外的整数,所以我有这样的东西:

I also have 3 Integers I put in extra, so I have something like this:

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中,我有以下方式:

In MyService I have the folloywing:

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:

My onDestroy:

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

我也有onBind()方法(没有@Override),但它返回空值。
我谷歌很多,我试图在前台运行该服务,所以我这样做(在de onStartCommand内):

I also have onBind() method (without @Override), but it returns null. I google a lot and I tried to run the service in foreground, so I did this (inside de 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);

我的通知出现,当我点击它时我的应用程序运行,但我的服务问题是'固定(我相信它仍然没有在前景上运行)。通知也重新启动。

My notification appears and when I click on it my app runs, but the problem with my service wasn't fixed (I believe it still not run on foreground). The notification is restarted too.

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

I also deleted the Try catch and I define a value for the integers (so I didn't use the getIntExtra() method), but nothing changed

经过多次测试我试图查看日志,当我杀死我的应用程序时,我有以下消息:调度崩溃服务的重新启动。

After several tests I tried to see the logs, when I kill my App I have the following message: Scheduling restart of crashed service.

因此,由于某些原因,当我的MainActivity死亡时,我的服务崩溃,为什么?这里的意图不是要改变一个无法杀死的神的服务(我不认为这根本不可能,WhatsApp运行了105个小时!)但是在我的应用程序死后我的服务不会被破坏。

So, for some reason my service crash when my MainActivity dies, why? The intention here is not to transform the service in a god that can not be killed (I don't think it is impossible at all, the WhatsApp are running for 105 hours !) but prevent my Service to not being crashed after my App dies.

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

I don't know if this'll help but this is what I add on my 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。

Min API = 9, target API = 17. Size of the Service when running: about 3MB.

希望我很清楚并抱歉我的英语。

Hope I was clear and sorry for my English.

PS:整个代码都在运行正如预期的那样,如果您发现任何sintax错误可以自由编辑它。

PS: the entire code are running as expected, so if you see any sintax error fell free to edit it.

编辑

如果我在AndroidManifest.xml中的< service> 中添加 android:isolatedProcess =true我在logCat中收到此错误: java.lang.RuntimeException:无法在com.mycompany.myapp.myservice中创建服务:java.lang.SecurityException:隔离进程不允许ed调用getIntentSender

If I add android:isolatedProcess="true" in the <service> in AndroidManifest.xml I receive this error in 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不显示任何错误,只有服务崩溃。

When I start my service using this, the MainActivity does not show any erros, only the service crashes.

推荐答案

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

I finally found the solution ! I removed the AlarmManager from the Service and the service does not cashed anymore, but I have to use it

问题是用户从应用程序中取出应用程序后服务崩溃最近的应用程序,所以我做的是阻止应用程序出现在该窗口中。将以下内容添加到您的AndroidManifest.xml中作为< activity>的孩子

The problem is the service crash after the user swype away the app from Recent App, so what I did was prevent the app to appear in that window. Add the following to your AndroidManifest.xml as a child of <activity>

android:excludeFromRecents="true"

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

Now when the user exit from your app it wil not appear in the recent apps window, what means the system kills the Activity right after you exit it, so it'll not waste any resources.

PS:不要忘记要将服务设置为在单独的进程中运行,请将以下内容添加到AndroidManifest.xml中,作为< service>的子项

PS: don't forget to set the service to run in a separate process, add the following to your AndroidManifest.xml, as a child of <service>

android:process=":remote"

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

经过大量的研究和研究(几个月的学习)后,我深入研究了android API和这是一个被发现的,这是仅在API 16+上出现的预期行为,android arquiteture的变化改变了PendingIntents被系统广播的方式,因此Google添加了标志 FLA G_RECEIVER_FOREGROUND ,你必须将这个标志传递给你在 PendingIntent.getBroadcast()上用作参数的意图,这里是例子:

After a lot of research and study (months of study) I took a deep look at android APIs and here is what a found, this is na expected behaviour that occours only at API 16+, a change at android arquiteture changed the way that PendingIntents are broadcasted by the system, so Google added the flag FLAG_RECEIVER_FOREGROUND, you must pass this flag to the intent you are using as a parameter on the PendingIntent.getBroadcast(), here is na example:

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版本将按预期工作,如果您远离该服务,该服务不会崩溃来自Recent Apps页面的应用程序。

Android versions older than API 16 will work as expected, the service won't crash if you swype away the app from Recent Apps page.

这篇关于服务崩溃并重新启动的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆