0

How can i run and AsyncTask in a Service so that the UI does not freeze when i do my work in a service? Today i implemented a very basic service:

public class ImageSendEmailService extends Service {
    private NotificationManager notificationManager = null;
    private Notification notification = null;

    @Override
    public void onCreate() {
        super.onCreate();

        this.notificationManager = (NotificationManager) this.getSystemService(NOTIFICATION_SERVICE);
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        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);

            this.notification = builder.build();
            this.notificationManager.notify(0, notification);
        }

        return super.onStartCommand(intent, flags, startId);
    }

    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }
}   

but the ui is freezing while i perform that.

Xaver Kapeller
  • 49,491
  • 11
  • 98
  • 86
Mulgard
  • 9,877
  • 34
  • 129
  • 232
  • Please, create a new question. and leave the old question intact so others can benefit from it. – Emmanuel Nov 29 '14 at 18:40
  • You should ask a new question if you have a new problem instead of recycling your old questions... – Xaver Kapeller Nov 29 '14 at 18:40
  • ok so did i: http://stackoverflow.com/questions/27206087/intentservice-is-stopping-everytime-i-kill-the-app/27206208#27206208 And the first answer ist exactly what i expected and what i tried to explain you. the intentservice gets killed when the app gets killed. – Mulgard Nov 29 '14 at 19:50

2 Answers2

3

You can run an AsyncTask in a Service just like you would run it in an Activity or Fragment. Why would there be any difference?

ExampleTask task = new ExampleTask();
task.execute();

But you can also subclass IntentService instead of Service! An IntentService automatically handles each Intent in a separate Thread. That way you can perform work in the Service without blocking the UI and you don't have to deal with AsyncTasks or Threads!

public class ImageSendEmailService extends IntentService {

    @Override
    protected void onHandleIntent(Intent intent) {
        // Do your work here!
    }
}

You can find the documentation of IntentService here.

As an aside: Whatever you are trying to there with Thread.sleep() is a really bad idea. Never use Thread.sleep() like that. Use a Timer or Handler instead!

Xaver Kapeller
  • 49,491
  • 11
  • 98
  • 86
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/65882/discussion-between-emmanuel-and-xaver-kapeller). – Emmanuel Nov 29 '14 at 18:35
  • First answer says exactly that what i knew about IntentServices: http://stackoverflow.com/questions/27206087/intentservice-is-stopping-everytime-i-kill-the-app/27206208#27206208 – Mulgard Nov 29 '14 at 19:38
  • @Emmanuel The documentation here (http://developer.android.com/guide/components/fundamentals.html) says that by default every app runs in its own Linux process. If we're killing the app, how we can expect that any of its components (services/activities/etc) will proceed to work? – aga Nov 29 '14 at 19:46
  • Well this answer seems to be referring to killing the whole process and not just the app. Nothing of the app can survive that as is mentioned in the answer. And the `IntentService` documentation states that an `IntentService` keeps running until it runs out of work. Right there in the first paragraph. – Xaver Kapeller Nov 29 '14 at 19:46
  • Is it possible you are swiping away the app in the recent menu? That would kill the whole process of the app and no app component can survive that. But as I mentioned earlier a foreground `Service` will keep running no matter what. – Xaver Kapeller Nov 29 '14 at 19:47
  • @aga If by killing the app you mean killing the whole process for example through the recent menu than yes, nothing can survive that. – Xaver Kapeller Nov 29 '14 at 19:49
  • And just as an aside: You can specify in the manifest that a `Service` should run in a separate process from the rest of the app. In that case even swiping away the app in the recent menu would not kill the process in which the `Service` is running. – Xaver Kapeller Nov 29 '14 at 19:50
1

This is how you do an async task

AsyncTask<Void,Integer,Void> myTask = new AsyncTask<Void,Integer,Void>(){

@Override
public Void doInBackground(Void... params){
   for (int i = 0; i <= 10; i++) {
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

           publishProgress((int) (100 * i / 10));
        }
return null;
}
     @Override
    public void onProgressUpdate(Integer... progress) {
     String notificationText = String.valueOf(progress[0]) + " %";

            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);

            this.notification = builder.build();
            this.notificationManager.notify(0, notification);
 }



}

myTask.execute();

Just to be clear this is what i meant in my answer

public class ImageSendEmailService extends Service {
private NotificationManager notificationManager = null;
private Notification notification = null;

@Override
public void onCreate() {
    super.onCreate();

    this.notificationManager = (NotificationManager) this.getSystemService(NOTIFICATION_SERVICE);
}

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
   AsyncTask<Void,Integer,Void> myTask = new AsyncTask<Void,Integer,Void>(){

@Override
public Void doInBackground(Void... params){
   for (int i = 0; i <= 10; i++) {
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

           publishProgress((int) (100 * i / 10));
        }
return null;
}
     @Override
    public void onProgressUpdate(Integer... progress) {
     String notificationText = String.valueOf(progress[0]) + " %";

            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);

            this.notification = builder.build();
            this.notificationManager.notify(0, notification);
 }



}

myTask.execute();
    return super.onStartCommand(intent, flags, startId);
}

@Override
public IBinder onBind(Intent intent) {
    return null;
}

}

Lena Bru
  • 13,521
  • 11
  • 61
  • 126
  • this is not the answer i need. i use the service for a reason. – Mulgard Nov 29 '14 at 18:01
  • write this inside your service - you asked how to do an async task, it doesnt matter where it is written – Lena Bru Nov 29 '14 at 18:03
  • 1
    @LenaBru You should really do something about your code formatting. I just looked through a few of your questions and answers and even tough you have over 250 questions and more than 180 answers you never seem to format your code properly. It's always all over the place and unreadable. Please fix this, from someone with more than 3k reputation this is almost unacceptable... – Xaver Kapeller Nov 29 '14 at 19:10