前台服务冻结了ui

时间:2014-11-29 20:55:09

标签: android android-service

我想创建一个简单的虚拟前台任务来了解它的行为。不幸的是我有一些问题。首先是代码:

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%通知会显示在设备的通知选项卡中,我无法将其删除。我需要它在完成工作时是不可删除的,但在完成工作后可以删除。

2 个答案:

答案 0 :(得分:2)

您不应该在主要/用户界面主题上运行Thread.sleep(1000);时立即致电Service

您应该引入线程(HandlerThreadThread)来执行服务中的时间操作。

此外,您还可以查找IntentService,默认情况下,该{{1}}在单独的线程上运行 - 使您的用户界面免于冻结。

答案 1 :(得分:2)

阅读this

如果你想做一个阻止主线程的任务,你必须基本上产生一个新线程。

针对您的notification问题

.setOngoing(true)

会使通知无法取消

完成任务后,使用

重新填写通知
.setOngoing(false)

为此你必须保存通知ID,或者只是从代码中删除

编辑: 完成工作后,您还必须调用stop self。相反,根本不要弄乱通知。由于它是前台服务,因此您无法删除通知,直到您的服务完成