0

I'm trying to run a asynchronous task inside the IntentService for downloading a file. However when I start the downloading thread, I get the following warning, and the process doesn't proceed.

W/MessageQueue(10371): java.lang.RuntimeException: Handler{406ee8f8} sending message to a Handler on a dead thread

I searched about this issue, and found that it's likely to have something to do with Handler and Looper of Pipeline Threading. The cause might be that the process of the thread to download a file is passed to the Handler of IntentService which dies soon after finishing its process. I know the thread should be passed to the Handler of the main thread (UI thread), not IntentService. Some people are saying that writing the following code in MainActivity class or Application class's onCreate() works, in order to pass the thread to proper Handler (Handler of main thread),

Class.forName("name.of.class.doing.asynch.task");

, but didn't work for me.

Let me give you details about my code and libraries I'm using.

- IntentService

Extending the class GCMBaseIntentService of "Google Cloud Messaging" (http://developer.android.com/guide/google/gcm/index.html). The error above occurs after Log.i(TAG, "STARTING CONNECTION") on LogCat.

public class GCMIntentService extends GCMBaseIntentService{

    public GCMIntentService() {
        super(Environment.GCM_SENDER_ID);
    }

    @Override
    protected void onMessage(Context context, Intent intent) {
        String[] allowedContentTypes = new String[] { "image/jpeg" };
        Log.i(TAG, "STARTING CONNECTION");
        AsynchConnector.getForBinaryResponse("MY_URL", new BinaryHttpResponseHandler(allowedContentTypes){
            @Override
            public void onSuccess(byte[] imageData) {
                Log.i(TAG, "SUCCESS!!");
        });
    }

    (... @Override methods follows)
 }

- Thread to download a file

Using "Android Asynchronous Http Client" (http://loopj.com/android-async-http/) which facilitates asynchronous http connection.

public class AsynchConnector{                                                                                                                                                 
    private static final String BASE_URL = Environment.SERVER_URL;
    private static AsyncHttpClient client = new AsyncHttpClient();

    public static void getForBinaryResponse(String url, BinaryHttpResponseHandler binaryHttpResponseHandler){
        client.get(getAbsoluteUrl(url), binaryHttpResponseHandler);
    }
}

Application's onCreate()

class MyApp extends Application{
    @Override
    onCreate(){
        try {                                                                                                                                                                 
            Class.forName("com.myapp.AsynchConnector");
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
}

How can I make this work? Please help me!

Ryo
  • 2,003
  • 4
  • 27
  • 42
  • The problem in GCMBaseIntentService not in your AsynchConnector – Yahor10 Sep 18 '12 at 07:05
  • Have You tried override public int onStartCommand(Intent intent, int flags, int startId) { return START_STICKY; } ? – sandrstar Sep 18 '12 at 07:09
  • @Yahor10, Could you tell me what's the exact problem is? – Ryo Sep 18 '12 at 07:31
  • @sandrstar, Should I use that in GCMIntentService? This service's methods are triggered automatically when receiving the gcm message.. – Ryo Sep 18 '12 at 07:33
  • 1
    Right, as I can see, all these methods works in main thread, (Service won't be killed until onHandleIntent() return). But You're trying to introduce async processing in separate thread which is different. – sandrstar Sep 18 '12 at 07:37
  • @sandrstar, The problem is in the post below, and that solved the problem! Thank you very much for your suggestion! (I didn't know about onHandleIntent() stuff, so I'm gonna study after this project :)). – Ryo Sep 18 '12 at 08:06

1 Answers1

1

GCMBaseIntentService extends IntentService.

IntentService sometimes call wrong handler in onHandleIntent function -when message received for example. You can avoid this warning by using async task:

  @Override
    protected void onMessage(Context context, Intent intent) {
    AsyncTask<Void, Void, Void> task = new AsyncTask<Void, Void, Void>() {
            @Override
            protected Void doInBackground(Void... params) {
                          // getForBinaryResponse()
            }
            @Override
            protected void onPostExecute(Void result) {

            }
        };
        task.execute(null,null,null);
    }

Your AsynchConnector should work

Yahor10
  • 2,123
  • 1
  • 13
  • 13
  • I tried this with a intentservice that uses asynctasks, but didn't solve it. Also tried it in the Application oncreate and tried `Class.forName`. Nothing works. – Peterdk Jun 22 '13 at 11:24
  • Your OnMessage gcm function receive messages? If not try to use google gcm example. – Yahor10 Jun 24 '13 at 08:42