Android - 定期后台服务 - 建议
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/10420358/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Android - Periodic Background Service - Advice
提问by Ziyan Junaideen
I am working on an app that will relay information about its location to a remote server. I am intending to do it by doing a simple HTTP post to the web-server and all is simple and fine.
我正在开发一个应用程序,它将有关其位置的信息中继到远程服务器。我打算通过向 Web 服务器发送一个简单的 HTTP 帖子来实现,一切都很简单。
But according to the spec, the app needs to execute itself from time to time, lets say once in every 30 mins. Be independent of the interface, meaning which it needs to run even if the app is closed.
但是根据规范,该应用程序需要不时执行自身,例如每 30 分钟执行一次。独立于界面,这意味着即使应用程序关闭它也需要运行。
I looked around and found out that Android Services is what needs to be used. What could I use to implement such a system. Will the service (or other mechanism) restart when the phone restarts?
我环顾四周,发现需要使用Android服务。我可以用什么来实现这样的系统。手机重启时服务(或其他机制)会重启吗?
Thanks in advance.
提前致谢。
采纳答案by Argyle
Create a Service
to send your information to your server. Presumably, you've got that under control.
创建一个Service
将您的信息发送到您的服务器。据推测,你已经控制住了。
Your Service
should be started by an alarm triggered by the AlarmManager
, where you can specify an interval. Unless you have to report your data exactlyevery 30 minutes, you probably want the inexact alarm so you can save some battery life.
您Service
应该由 触发的警报启动AlarmManager
,您可以在其中指定时间间隔。除非您必须每 30 分钟准确报告一次数据,否则您可能需要不准确的警报,以便节省一些电池寿命。
Finally, you can register your app to get the bootup broadcast by setting up a BroadcastReceiver
like so:
最后,您可以通过如下设置来注册您的应用程序以获取启动广播BroadcastReceiver
:
public class BootReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(Intent.ACTION_BOOT_COMPLETED)) {
// Register your reporting alarms here.
}
}
}
You'll need to add the following permission to your AndroidManifest.xml
for that to work. Don't forget to register your alarms when you run the app normally, or they'll only be registered when the device boots up.
您需要将以下权限添加到您AndroidManifest.xml
的工作中。不要忘记在您正常运行应用程序时注册您的闹钟,否则它们只会在设备启动时注册。
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
回答by Pierre
Here is a semi-different way to keep the service going forever. There is ways to kill it in code if you'd wish
这是一种保持服务永久运行的半不同方式。如果您愿意,有多种方法可以在代码中杀死它
Background Service:
后台服务:
package com.ex.ample;
import android.app.Service;
import android.content.*;
import android.os.*;
import android.widget.Toast;
public class BackgroundService extends Service {
public Context context = this;
public Handler handler = null;
public static Runnable runnable = null;
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public void onCreate() {
Toast.makeText(this, "Service created!", Toast.LENGTH_LONG).show();
handler = new Handler();
runnable = new Runnable() {
public void run() {
Toast.makeText(context, "Service is still running", Toast.LENGTH_LONG).show();
handler.postDelayed(runnable, 10000);
}
};
handler.postDelayed(runnable, 15000);
}
@Override
public void onDestroy() {
/* IF YOU WANT THIS SERVICE KILLED WITH THE APP THEN UNCOMMENT THE FOLLOWING LINE */
//handler.removeCallbacks(runnable);
Toast.makeText(this, "Service stopped", Toast.LENGTH_LONG).show();
}
@Override
public void onStart(Intent intent, int startid) {
Toast.makeText(this, "Service started by user.", Toast.LENGTH_LONG).show();
}
}
Here is how you start it from your main activity or wherever you wish:
以下是您如何从您的主要活动或您希望的任何地方开始:
startService(new Intent(this, BackgroundService.class));
onDestroy()
will get called when the application gets closed or killed but the runnable just starts it right back up.
onDestroy()
当应用程序被关闭或终止时将被调用,但可运行的只是将它重新启动。
I hope this helps someone out.
我希望这可以帮助某人。
The reason why some people do this is because of corporate applications where in some instances the users/employees must not be able to stop certain things :)
有些人这样做的原因是因为公司应用程序在某些情况下用户/员工不能停止某些事情:)
http://i.imgur.com/1vCnYJW.png
http://i.imgur.com/1vCnYJW.png
EDIT
编辑
Since Android O (8.0) you have to use JobManager
for scheduled tasks. There is a library called Android-Job by Evernotewhich will make periodic background work a breeze on all Android versions. I have also made a Xamarin Bindingof this library.
从 Android O (8.0) 开始,您必须JobManager
用于计划任务。Evernote有一个名为Android-Job的库,它可以让所有 Android 版本的周期性后台工作变得轻而易举。我还制作了这个库的Xamarin 绑定。
Then all you need to do is the following:
那么你需要做的就是以下几点:
In your application class:
在您的应用程序类中:
public class MyApp extends Application {
@Override
public void onCreate() {
super.onCreate();
JobManager.create(this).addJobCreator(new MyJobCreator());
}
}
Create the following two classes YourJobCreator
and YourSyncJob
(Where all the work will be done. Android allocates time for all the background jobs to be run. For android versions < 8.0 it will still run with an Alarm manager and background service as per normal)
创建以下两个类YourJobCreator
和YourSyncJob
(所有工作都将在这里完成。Android 为所有要运行的后台作业分配时间。对于 android 版本 < 8.0,它仍将按正常方式与警报管理器和后台服务一起运行)
public class MyJobCreator implements JobCreator {
@Override
@Nullable
public Job create(@NonNull String tag) {
switch (tag) {
case MySyncJob.TAG:
return new MySyncJob();
default:
return null;
}
}
}
public class MySyncJob extends Job {
public static final String TAG = "my_job_tag";
@Override
@NonNull
protected Result onRunJob(Params params) {
//
// run your job here
//
//
return Result.SUCCESS;
}
public static void scheduleJob() {
new JobRequest.Builder(MySyncJob.TAG)
.setExecutionWindow(30_000L, 40_000L) //Every 30 seconds for 40 seconds
.build()
.schedule();
}
}
回答by SohailAziz
You should schedule your service with alarm manager, first create the pending intent of service:
您应该使用警报管理器安排您的服务,首先创建待处理的服务意图:
Intent ii = new Intent(getApplicationContext(), MyService.class);
PendingIntent pii = PendingIntent.getService(getApplicationContext(), 2222, ii,
PendingIntent.FLAG_CANCEL_CURRENT);
Then schedule it using alarm manager:
然后使用警报管理器安排它:
//getting current time and add 5 seconds to it
Calendar cal = Calendar.getInstance();
cal.add(Calendar.SECOND, 5);
//registering our pending intent with alarmmanager
AlarmManager am = (AlarmManager) getSystemService(ALARM_SERVICE);
am.set(AlarmManager.RTC_WAKEUP,cal.getTimeInMillis(), pi);
this will launch your service after 5 seconds of current time. You can make your alarm repeating.
这将在当前时间的 5 秒后启动您的服务。您可以使闹钟重复。
回答by vandzi
You can use Alarm Managerto start Service at specified time and then repeat alarm in specified interval. When alarm goes on you can start service and connect to server and make what you want
您可以使用警报管理器在指定时间启动服务,然后在指定时间间隔重复警报。当警报响起时,您可以启动服务并连接到服务器并制作您想要的