Bam*_*Bam 70 service android shutdown restart android-activity
我从我的主要Android活动开始提供服务,如下所示:
final Context context = base.getApplicationContext();
final Intent intent = new Intent(context, MyService.class);
startService(intent);
Run Code Online (Sandbox Code Playgroud)
当我通过从最近的应用程序列表中滑出来关闭活动页面时,服务会停止运行并在一段时间后重新启动.由于我的应用程序要求,我无法将持久服务与通知一起使用.如何使服务不重启或关闭,并继续在应用程序退出运行?
小智 42
我处于相同的情况,到目前为止,我知道应用程序关闭时服务也因为它们在一个线程中而关闭,所以服务应该在另一个线程上,以便它不被关闭,看看并通过这里的示例http://www.vogella.com/articles/AndroidServices/article.html查看使用警报管理器保持服务的活动状态,这样您的服务就不会显示在通知中.
最后,经过我所做的所有研究后,我逐渐意识到长期服务的最佳选择是startForeground(),因为它是为此而制定的,系统实际上可以很好地处理您的服务.
ala*_*ban 12
让你在Mainifest中像这样服务
<service
android:name=".sys.service.youservice"
android:exported="true"
android:process=":ServiceProcess" />
Run Code Online (Sandbox Code Playgroud)
那么您的服务将在名为ServiceProcess的其他进程上运行
如果你想让你的服务永远不会死:
onStartCommand()返回START_STICKY
onDestroy() - > startself
创建一个Deamon服务
jin - >创建一个Native Deamon进程,你可以在github上找到一些开源项目
startForeground(),有一种方法可以启动没有通知的startForeground,google它
主要问题是应用程序关闭时无法启动服务,android操作系统(在某些操作系统中)将终止服务以进行资源优化,如果您无法重新启动服务,则调用警报管理器来启动接收器,如下所示,这是完整的代码,此代码将使您的服务保持活动状态。
体现为,
<service
android:name=".BackgroundService"
android:description="@string/app_name"
android:enabled="true"
android:label="Notification" />
<receiver android:name="AlarmReceiver">
<intent-filter>
<action android:name="REFRESH_THIS" />
</intent-filter>
</receiver>
Run Code Online (Sandbox Code Playgroud)
在 Main Activty 中以这种方式启动警报管理器,
String alarm = Context.ALARM_SERVICE;
AlarmManager am = (AlarmManager) getSystemService(alarm);
Intent intent = new Intent("REFRESH_THIS");
PendingIntent pi = PendingIntent.getBroadcast(this, 123456789, intent, 0);
int type = AlarmManager.RTC_WAKEUP;
long interval = 1000 * 50;
am.setInexactRepeating(type, System.currentTimeMillis(), interval, pi);
Run Code Online (Sandbox Code Playgroud)
这将调用接收者,接收者是,
public class AlarmReceiver extends BroadcastReceiver {
Context context;
@Override
public void onReceive(Context context, Intent intent) {
this.context = context;
System.out.println("Alarma Reciver Called");
if (isMyServiceRunning(this.context, BackgroundService.class)) {
System.out.println("alredy running no need to start again");
} else {
Intent background = new Intent(context, BackgroundService.class);
context.startService(background);
}
}
public static boolean isMyServiceRunning(Context context, Class<?> serviceClass) {
ActivityManager activityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
List<ActivityManager.RunningServiceInfo> services = activityManager.getRunningServices(Integer.MAX_VALUE);
if (services != null) {
for (int i = 0; i < services.size(); i++) {
if ((serviceClass.getName()).equals(services.get(i).service.getClassName()) && services.get(i).pid != 0) {
return true;
}
}
}
return false;
}
}
Run Code Online (Sandbox Code Playgroud)
当Android应用程序打开和关闭时,这个Alaram接收器会调用一次。所以服务是这样的,
public class BackgroundService extends Service {
private String LOG_TAG = null;
@Override
public void onCreate() {
super.onCreate();
LOG_TAG = "app_name";
Log.i(LOG_TAG, "service created");
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.i(LOG_TAG, "In onStartCommand");
//ur actual code
return START_STICKY;
}
@Override
public IBinder onBind(Intent intent) {
// Wont be called as service is not bound
Log.i(LOG_TAG, "In onBind");
return null;
}
@TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH)
@Override
public void onTaskRemoved(Intent rootIntent) {
super.onTaskRemoved(rootIntent);
Log.i(LOG_TAG, "In onTaskRemoved");
}
@Override
public void onDestroy() {
super.onDestroy();
Log.i(LOG_TAG, "In onDestroyed");
}
}
Run Code Online (Sandbox Code Playgroud)
小智 5
有时服务非常复杂。
当您从活动(或您的流程)启动服务时,该服务本质上是在同一流程上。
引用开发者注释
关于Service类的最困惑实际上是围绕它不是什么:
服务不是独立的过程。Service对象本身并不意味着它在自己的进程中运行;除非另有说明,否则它将与它所属的应用程序在同一进程中运行。
服务不是线程。它本身并不是在主线程之外工作的一种方式(以避免Application Not Responding错误)。
因此,这意味着,如果用户将应用程序从最近的任务中滑出,它将删除您的流程(包括您的所有活动等)。现在,让我们来看三种情况。
首先,该服务没有前台通知。
在这种情况下,您的过程将与服务一起被杀死。
其次,服务具有前台通知
在这种情况下,服务不会被终止,进程也不会被终止
第三种情况如果该服务没有前台通知,则在应用程序关闭时仍可以继续运行。我们可以通过使服务在不同的流程中运行来做到这一点。(但是,我听说有人说它可能不起作用。请您自己尝试一下)
您可以通过在清单中包含以下属性来在单独的过程中创建服务。
android:process =“:yourService”
要么
android:process =“ yourService”流程名称必须以小写字母开头。
引用开发人员注释
如果分配给此属性的名称以冒号(':')开头,则会在需要时创建一个新的进程,该进程是应用程序专用的,并且服务在该进程中运行。如果进程名称以小写字母开头,则该服务将在具有该名称的全局进程中运行,前提是它具有这样做的权限。这允许不同应用程序中的组件共享进程,从而减少资源使用。
这是我收集的信息,如果有人是专家,如果我错了,请纠正我:)
小智 5
从 Android O 开始,您无法使用这些服务来进行长时间运行的后台操作,因为https://developer.android.com/about/versions/oreo/background。Jobservice 将是 Jobscheduler 实施的更好选择。
| 归档时间: |
|
| 查看次数: |
89845 次 |
| 最近记录: |