Is it possible to use AsyncTask in a Service class?
Asked Answered
P

5

19

Everything is in the title.

On the official documentations it is stated that Note that services, like other application objects, run in the main thread of their hosting process and AsyncTask only works if it is executed in the UIThread.

So is it possible to use AsyncTask in a Service class?

I am trying to do so but I'm always getting the same error

05-01 18:09:25.487: ERROR/JavaBinder(270): java.lang.ExceptionInInitializerError

...

05-01 18:09:25.487: ERROR/JavaBinder(270): Caused by: java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()

Am I doing something wrong or is this just impossible ?

Here is the code of my Service class

package com.eip.core;

import android.app.Service;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log;

public class NetworkService extends Service {


    private final INetwork.Stub mBinder = new INetwork.Stub() {

        @Override
        public int doConnect(String addr, int port) throws RemoteException {
            new ConnectTask().execute("test42");
            return 0;
        }
    };

    @Override
    public IBinder onBind(Intent arg0) {
        return mBinder;
    }

    private class ConnectTask extends AsyncTask<String, Void, Void> {

        @Override
        protected void onPreExecute() {
            super.onPreExecute();
            Log.i("OnPreExecute()", "");
        }

        @Override
        protected Void doInBackground(String... arg0) {
            Log.i("doInBackground()", "");
            return null;
        }

        @Override
        protected void onPostExecute(Void result) {
            super.onPostExecute(result);
            Log.i("OnPostExecute()", "");
        }

    }
}
Philander answered 1/5, 2010 at 16:19 Comment(0)
P
2

I Think I found why it is not working in my case.

Here I am using this :

private final INetwork.Stub mBinder = new INetwork.Stub() {

        @Override
        public int doConnect(String addr, int port) throws RemoteException {
            new ConnectTask().execute("test42");
            return 0;
        }
    };

I am using this to do what so called IPC, Inter Process Communication, so I guess that my Service and my Activity are in two differents process, AsyncTask must be executed in the main UI thread according to the android doc, so why I was trying to do seems to me just impossible according to those facts.

If I am wrong please someone can correct me.

Philander answered 5/5, 2010 at 19:18 Comment(0)
L
12

Also be sure to check out IntentService. If that class is sufficient for your needs, it will take care of a lot of little details involved in making that pattern work correctly.

Lockman answered 1/5, 2010 at 23:7 Comment(0)
P
2

I Think I found why it is not working in my case.

Here I am using this :

private final INetwork.Stub mBinder = new INetwork.Stub() {

        @Override
        public int doConnect(String addr, int port) throws RemoteException {
            new ConnectTask().execute("test42");
            return 0;
        }
    };

I am using this to do what so called IPC, Inter Process Communication, so I guess that my Service and my Activity are in two differents process, AsyncTask must be executed in the main UI thread according to the android doc, so why I was trying to do seems to me just impossible according to those facts.

If I am wrong please someone can correct me.

Philander answered 5/5, 2010 at 19:18 Comment(0)
T
1

Maybe problem is not AsyncTask but something else. For example are you sure your onBind method works correctly? Please try this:

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

You could also try that

public class NetworkService extends Service{
  @Override
  public void onStart(Intent intent, int startId) {
    new ConnectTask().execute("test42");
  }
}
Throstle answered 1/5, 2010 at 23:54 Comment(0)
S
1

Is it possible to use AsyncTask in a Service class?

Yes. See Reto Meier (2010) Professional Android 2 Application Development, Wrox. Meier has published supporting code (see /Chapter 9 Earthquake 4/src/com/paad/earthquake/EarthquakeService.java):

public class EarthquakeService extends Service {        
    ... 
    private EarthquakeLookupTask lastLookup = null;
    ...

    private class EarthquakeLookupTask extends AsyncTask<Void, Quake, Void> { 
        ... 
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {    
        ...
        refreshEarthquakes();
        return Service.START_NOT_STICKY;
    };

    private void refreshEarthquakes() {
        ...
        lastLookup = new EarthquakeLookupTask();
        lastLookup.execute((Void[])null);
        ...
    }
}

On an aside, I cannot find any evidence to support your claim that "AsyncTask only works if it is executed in the UIThread" (although this would violate threading rules).

Sabrasabre answered 7/8, 2014 at 1:36 Comment(2)
Hi it doesn't violate threading rules as your service always runs on UI thread till you don't fork threads from itRushing
So the above code would work just fine i guess you are confused between services and intent services ,Intent services run in a background thread by defaultRushing
S
0

Although it is possible to use AsyncTask in a Service class, this violates threading rules, in particular, AsyncTask must be instantiated and invoked on the UI thread. (See https://mcmap.net/q/667933/-android-design-pattern-for-background-operation-with-ui-and-non-ui-modes for further discussion.)

Sabrasabre answered 14/8, 2014 at 0:7 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.