android - 我希望我的服务每天工作一次,但它却工作多次
问题描述
我想创建一个应用程序,它每天在特定时间将整数值减 1。为此,我使用了一个据说在上午 12 点被激活的 BroadcastReceiver。从 BroadcastReceiver,我正在调用一个服务,该服务创建一个后台线程来修改数据库(MySQL 数据库)中的值,然后关闭该服务。问题是这些值每天会减少 1 次,而不是只减少一次。这是代码:
显现
<receiver
android:name=".myAlarm"
android:enabled="true"
android:exported="true"></receiver>
<service android:name=".myService"
android:enabled="true"
android:exported="true" />
主要的
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.HOUR_OF_DAY, 23);
calendar.set(Calendar.MINUTE, 59);
calendar.set(Calendar.SECOND, 0);
AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(Main.this, myAlarm.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(this.context, 0, intent, 0);
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT && Build.VERSION.SDK_INT >= Build.VERSION_CODES.DONUT) {
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(),
AlarmManager.INTERVAL_DAY, pendingIntent);
}
else if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT)
{
alarmManager.setInexactRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(),
AlarmManager.INTERVAL_DAY, pendingIntent);
}
MyAlram(广播接收器)
public class myAlarm extends BroadcastReceiver {
public void onReceive(Context context, Intent intent) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
context.startForegroundService(new Intent(context.getApplicationContext(), myService.class));
} else {
context.startService(new Intent(context.getApplicationContext(), myService.class));
}
}
}
我的服务(服务)
public class myService extends Service{
private DBWorkers mydb;
private Thread backgroundThread;
private Context context;
private Boolean isRunning = false;
/**
* Called by the system when the service is first created. Do not call this method directly.
*/
@Override
public void onCreate() {
super.onCreate();
this.context = this;
this.backgroundThread = new Thread(myTask);
if (Build.VERSION.SDK_INT >= 26) {
String CHANNEL_ID = "my_channel_01";
NotificationChannel channel = new NotificationChannel(CHANNEL_ID,
"Channel human readable title",
NotificationManager.IMPORTANCE_DEFAULT);
((NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE)).createNotificationChannel(channel);
Notification notification = new NotificationCompat.Builder(this)
.setContentTitle("")
.setContentText("").build();
startForeground(1, notification);
}
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
private Runnable myTask = new Runnable() {
@Override
public void run() {
mydb = new DBWorkers(context);
ArrayList<Worker> myList = new ArrayList<>(mydb.getAllWorkersService());
ArrayList<Worker> newList = new ArrayList<>();
//visa and work are the values I need to decrement daily
for(Worker item : myList){
int work = item.getWork(), visa = item.getVisa();
if(visa > 0)
{
visa = visa - 1;
}
else if(visa < 0)
{
visa = 0;
}
if(work > 0)
{
work = work - 1;
}
else if(work < 0)
{
work = 0;
}
if(item.getVisa() != visa || item.getWork() != work){
newList.add(new Worker(item.getName(), visa, work, item.getId()));
}
}
mydb.updateAllWorkers(newList);
stopSelf();
}
};
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
if (!isRunning){
isRunning = true;
backgroundThread.start();
}
return START_STICKY;
}
/**
* Called by the system to notify a Service that it is no longer used and is being removed. The
* service should clean up any resources it holds (threads, registered
* receivers, etc) at this point. Upon return, there will be no more calls
* in to this Service object and it is effectively dead. Do not call this method directly.
*/
@Override
public void onDestroy() {
super.onDestroy();
}
}
我还有其他几个问题:
1)我使用 IntentService 比使用普通服务更好吗?为什么?
2)我不知道下面的代码中发生了什么。我从在线答案中复制粘贴它,因为我的代码无法在我的手机上运行,我认为这是因为我手机的操作系统是 8.0,这是建议的解决方案。通过向我解释它,我将非常感谢您的帮助。
String CHANNEL_ID = "my_channel_01";
NotificationChannel channel = new NotificationChannel(CHANNEL_ID,
"Channel human readable title",
NotificationManager.IMPORTANCE_DEFAULT);
((NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE)).createNotificationChannel(channel);
Notification notification = new NotificationCompat.Builder(this)
.setContentTitle("")
.setContentText("").build();
startForeground(1, notification);
3)我是否需要创建一个后台线程来运行此任务,或者它会自动在后台线程上执行,因为应用程序很可能会被杀死?
太感谢了!
解决方案
推荐阅读
- c++ - Find the prototypes of some Windows Kernel APIs like NtAllocateUserPhysicalPagesEx
- json - 如何将类似 json 的环境变量传递给 docker run
- java - 是否有任何可用的 Java parallelstream 替代方案仍然并行运行线程
- php - 在 php 中包含不同的导航
- python - Tkinter:按下时更改按钮背景
- css - 背景大小是否适用于两个图像?
- tensorflow - 是否可以将 TensorFlow 的卷积函数与我自己的神经网络一起使用?
- sql - How to loop through JSON array to insert rows in SQL Table using TSQL?
- powershell - 搜索中的 Powershell 自定义日期和时间
- regex - 如何编写正则表达式来获取特定的日期时间?