Mur*_*ira 2 java crash service android kill
关于它有几个问题,但我总是读同样的事情:"如果系统需要资源,服务将被杀死"或"你无法构建一个永远运行的服务,因为它在后台运行的越多,就越容易受到影响系统杀死它"等等
我面临的问题是:我的服务运行良好并且正如预期的那样,如果我运行我的应用程序然后退出它我的服务仍在运行,但是当我杀了我的应用程序时(通过转到"最近的应用程序"并转换它离开)服务停止.在这一刻,如果我转到设置>> aplications >>运行,我会看到该服务正在重启.过了一会儿,它回来了,我的服务运行没有问题.
我谷歌它,我找到了一些我能做的事情,但让我们先看看我的代码:
我通过这种方式启动我的服务(点击一下按钮后):
Intent intent = new Intent (MainActivity.this, MyService.class);
startService(intent);
Run Code Online (Sandbox Code Playgroud)
我还有3个额外的整数,所以我有这样的东西:
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);
Run Code Online (Sandbox Code Playgroud)
在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
}
Run Code Online (Sandbox Code Playgroud)
我的onDestroy:
@Override
public void onDestroy()
{
unregisterReceiver(br);
super.onDestroy();
}
Run Code Online (Sandbox Code Playgroud)
我也有onBind()方法(没有@Override),但它返回null.我谷歌很多,我试图在前台运行该服务,所以我这样做(在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);
Run Code Online (Sandbox Code Playgroud)
我的通知出现了,当我点击它我的应用程序运行,但我的服务问题没有修复(我相信它仍然没有在前台运行).通知也重新启动.
我还删除了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"/>
Run Code Online (Sandbox Code Playgroud)
最小API = 9,目标API = 17.运行时服务的大小:大约3MB.
希望我很清楚并抱歉我的英语.
PS:整个代码都按预期运行,所以如果你看到任何sintax错误可以自由编辑它.
编辑
如果我在AndroidManifest.xml中添加android:isolatedProcess="true",<service>我在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不会显示任何错误,只有服务崩溃.
Mur*_*ira 10
我终于找到了解决方案!我从服务中删除了AlarmManager,服务不再兑现,但我必须使用它
问题是用户从最近的应用程序中删除应用程序后服务崩溃,所以我所做的是阻止应用程序出现在该窗口中.将以下内容添加到您的AndroidManifest.xml中<activity>
android:excludeFromRecents="true"
Run Code Online (Sandbox Code Playgroud)
现在,当用户从您的应用程序退出时,它不会出现在最近的应用程序窗口中,这意味着系统在您退出后立即终止该活动,因此它不会浪费任何资源.
PS:不要忘记将服务设置为在单独的进程中运行,将以下内容添加到AndroidManifest.xml中,作为子进程 <service>
android:process=":remote"
Run Code Online (Sandbox Code Playgroud)
编辑 - 找到真正的解决方案
经过大量的研究和研究(几个月的研究),我深入研究了android API,这是一个发现,这是仅在API 16+发生的预期行为,android arquiteture的变化改变了PendingIntents的方式由系统广播,所以谷歌添加了标志FLAG_RECEIVER_FOREGROUND,你必须将这个标志传递给你用作参数的意图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;
Run Code Online (Sandbox Code Playgroud)
早于API 16的Android版本将按预期工作,如果您从"最近的应用"页面中删除该应用,该服务不会崩溃.
| 归档时间: |
|
| 查看次数: |
9610 次 |
| 最近记录: |