我想创建一个简单的虚拟前台任务来了解它的行为。不幸的是我有一些问题。首先是代码:
public class ImageSendEmailService extends Service {
@Override
public void onCreate() {
super.onCreate();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
if (intent.getAction().equals(ForegroundServiceTags.STARTFOREGROUND_ACTION.getValue())) {
for (int i = 0; i <= 10; i++) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
String notificationText = String.valueOf((int) (100 * i / 10)) + " %";
Notification.Builder builder = new Notification.Builder(this);
builder.setContentTitle("Progress");
builder.setContentText(notificationText);
builder.setTicker("Notification!");
builder.setWhen(System.currentTimeMillis());
builder.setDefaults(Notification.DEFAULT_SOUND);
builder.setAutoCancel(true);
builder.setSmallIcon(R.drawable.ic_launcher);
Notification notification = builder.build();
this.startForeground(101, this.notification);
}
}
return START_STICKY;
}
@Override
public IBinder onBind(Intent intent) {
return null;
}
}
我遇到的第一个问题是该服务冻结了应用程序的UI。在Service
完成其工作后,UI仍在继续,但在执行时会被冻结。
我遇到的第二个问题是,当工作完成后,100%通知会显示在设备的通知选项卡中,我无法将其删除。我需要它在完成工作时是不可删除的,但在完成工作后可以删除。
答案 0 :(得分:2)
您不应该在主要/用户界面主题上运行Thread.sleep(1000);
时立即致电Service
。
您应该引入线程(HandlerThread
或Thread
)来执行服务中的时间操作。
此外,您还可以查找IntentService
,默认情况下,该{{1}}在单独的线程上运行 - 使您的用户界面免于冻结。
答案 1 :(得分:2)
阅读this
如果你想做一个阻止主线程的任务,你必须基本上产生一个新线程。
针对您的notification问题
.setOngoing(true)
会使通知无法取消
完成任务后,使用
重新填写通知.setOngoing(false)
为此你必须保存通知ID,或者只是从代码中删除
编辑: 完成工作后,您还必须调用stop self。相反,根本不要弄乱通知。由于它是前台服务,因此您无法删除通知,直到您的服务完成