1

I've developed Android Wear watch face, which gets location within a Service on handheld side. I use AsyncTask code which I've got from here. This error drains about 50% battery of the phone. And I don't know why. Please help. Error:

W/MessageQueue: Handler (android.location.LocationManager$ListenerTransport$1) {93795ca} sending message to a Handler on a dead thread
                                                                 java.lang.IllegalStateException: Handler (android.location.LocationManager$ListenerTransport$1) {93795ca} sending message to a Handler on a dead thread
                                                                     at android.os.MessageQueue.enqueueMessage(MessageQueue.java:543)
                                                                     at android.os.Handler.enqueueMessage(Handler.java:631)
                                                                     at android.os.Handler.sendMessageAtTime(Handler.java:600)
                                                                     at android.os.Handler.sendMessageDelayed(Handler.java:570)
                                                                     at android.os.Handler.sendMessage(Handler.java:507)
                                                                     at android.location.LocationManager$ListenerTransport.onLocationChanged(LocationManager.java:248)
                                                                     at android.location.ILocationListener$Stub.onTransact(ILocationListener.java:58)
                                                                     at android.os.Binder.execTransact(Binder.java:453)

My Service:

public class WeatherService extends WearableListenerService {

private void startTask() {

        Log.d(TAG, "Start Weather AsyncTask");
        mGoogleApiClient = new GoogleApiClient.Builder(this).addApi(Wearable.API).build();

        mLocationManager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);

        // getting GPS status
        isGPSEnabled = mLocationManager
                .isProviderEnabled(LocationManager.GPS_PROVIDER);

        // getting network status
        isNetworkEnabled = mLocationManager
                .isProviderEnabled(LocationManager.NETWORK_PROVIDER);
        if (!isGPSEnabled && !isNetworkEnabled) {
            Log.d(TAG, "no network provider is enabled");
            // no network provider is enabled

        } else {
            this.canGetLocation = true;
            Log.d(TAG, "canGetLocation" + isGPSEnabled + isNetworkEnabled);
            if (isNetworkEnabled) {
                mLocationManager.requestLocationUpdates(
                        LocationManager.NETWORK_PROVIDER,
                        0,
                        0, new LocationListener() {
                            @Override
                            public void onLocationChanged(Location location) {
                                Log.d(TAG, "onLocationChanged: " + location);
                                //mLocation = location;
                                mLocationNetwork = location;
                                Task task = new Task();
                                task.execute();
                                Log.v(TAG, "isNetworkEnabled onLocationChanged: " + mLocationNetwork);
                                if (mLocationManager != null) {
                                    mLocationManager.removeUpdates(this);
                                }
                            }

                            @Override
                            public void onStatusChanged(String provider, int status, Bundle extras) {
                                Log.d(TAG, "onLocationChanged: " + location);
                                if (mLocationManager != null) {
                                    mLocationManager.removeUpdates(this);
                                }
                                //mLocation = location;
                                mLocationNetwork = location;

                            }

                            @Override
                            public void onProviderEnabled(String provider) {
                                if (mLocationManager != null) {
                                    mLocationManager.removeUpdates(this);
                                }

                            }

                            @Override
                            public void onProviderDisabled(String provider) {
                                if (mLocationManager != null) {
                                    mLocationManager.removeUpdates(this);
                                }
                            }

                        });
                Log.d("Network", "Network Enabled");
                if (mLocationManager != null) {
                    location = mLocationManager
                            .getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
                    if (location != null) {
                        latitude = location.getLatitude();
                        longitude = location.getLongitude();
                        Log.d(TAG, "Network Enabled: lat and long: " + latitude + longitude);
                        Task task = new Task();
                        task.execute();
                        Log.v(TAG, "isNetworkEnabled mLocationManager != null: " + location + latitude + longitude);


                    }
                }
            }
            // if GPS Enabled get lat/long using GPS Services
            if (isGPSEnabled) {
                if (location == null) {
                    mLocationManager.requestLocationUpdates(
                            LocationManager.GPS_PROVIDER,
                            0,
                            0, new LocationListener(){
                                @Override
                                public void onLocationChanged( Location location )
                                {
                                    Log.d( TAG, "onLocationChanged: " + location );

                                    //mLocation = location;
                                    mLocationNetwork = location;
                                    Task task = new Task();
                                    task.execute();
                                    Log.v(TAG, "isGPSEnabled onLocationChanged: " + mLocationNetwork);
                                    if (mLocationManager != null) {
                                        mLocationManager.removeUpdates(this);
                                    }
                                }

                                @Override
                                public void onStatusChanged( String provider, int status, Bundle extras )
                                {
                                    Log.d( TAG, "onLocationChanged: " + location );
                                    //mLocation = location;
                                    mLocationNetwork = location;
                                    if (mLocationManager != null) {
                                        mLocationManager.removeUpdates(this);
                                    }
                                }

                                @Override
                                public void onProviderEnabled( String provider )
                                {
                                    if (mLocationManager != null) {
                                        mLocationManager.removeUpdates(this);
                                    }
                                }

                                @Override
                                public void onProviderDisabled( String provider )
                                {
                                    if (mLocationManager != null) {
                                        mLocationManager.removeUpdates(this);
                                    }
                                }
                            });
                    Log.d("GPS", "GPS Enabled");
                    if (mLocationManager != null) {
                        location = mLocationManager
                                .getLastKnownLocation(LocationManager.GPS_PROVIDER);
                        if (location != null) {
                            latitude = location.getLatitude();
                            longitude = location.getLongitude();
                            Log.d(TAG, "GPS Enabled: lat and long: " + latitude + longitude);
                            Task task = new Task();
                            task.execute();
                            Log.v(TAG, "isGPSEnabled mLocationManager != null: " + location + latitude + longitude);
                        }
                    }
                }
            }
        }

    }

And here is the ASyncTask:

private class Task extends AsyncTask
    {
        private String resp;
        @Inject
        IWeatherApi api;

        @Override
        protected Object doInBackground( Object[] params )
        {
            if (this.isCancelled()) {
                return null;
            }
            try
            {
                Log.d( TAG, "Task Running" );
                RoboGuice.getInjector( WeatherService.this.getApplicationContext() ).injectMembers( this );

                if ( !mGoogleApiClient.isConnected() )
                { mGoogleApiClient.connect();

                }

                final DataMap config = new DataMap();

                WeatherInfo infoNetwork = api.getCurrentWeatherInfo(latitude, longitude);

                config.putInt( KEY_WEATHER_TEMPERATURE, infoNetwork.getTemperature() );
                config.putString( KEY_WEATHER_CONDITION, infoNetwork.getCondition() );
                config.putLong( KEY_WEATHER_SUNSET, infoNetwork.getSunset() );
                config.putLong( KEY_WEATHER_SUNRISE, infoNetwork.getSunrise() );
                config.putInt( KEY_WEATHER_WIND_SPEED, infoNetwork.getSpeed() );
                config.putInt( KEY_WEATHER_WIND_DEGREE, infoNetwork.getDeg() );
                config.putInt( KEY_WEATHER_TEMP_MIN, infoNetwork.getTempMin() );
                config.putInt( KEY_WEATHER_TEMP_MAX, infoNetwork.getTempMax() );
                config.putInt( KEY_WEATHER_HUMIDITY, infoNetwork.getHumidity() );
                config.putInt( KEY_WEATHER_PRESSURE, infoNetwork.getPressure() );

                    Wearable.MessageApi.sendMessage(mGoogleApiClient, mPeerId, PATH_WEATHER_INFO, config.toByteArray())
                            .setResultCallback(
                                    new ResultCallback<MessageApi.SendMessageResult>() {
                                        @Override
                                        public void onResult(MessageApi.SendMessageResult sendMessageResult) {
                                            Log.d(TAG, "SendUpdateMessage: " + sendMessageResult.getStatus());
                                            Log.v(TAG, KEY_WEATHER_CONDITION);
                                            Log.v(TAG, "AsyncTask config in onResult: " + config.toString());
                                            Log.v(TAG, "mGoogleApiClient, mPeerId, PATH_WEATHER_INFO, config.toByteArray()" + mGoogleApiClient + " " + mPeerId + " " + PATH_WEATHER_INFO + " " + config);
                                        }
                                    }
                            );

            }catch (IllegalStateException e) {
                e.printStackTrace();
                resp = e.getMessage();
            }
            catch ( Exception e )
            {
                Log.d( TAG, "Task Fail: " + e );
            }
            return null;
        }
    }

Please help, I'm a new developer and trying to solve this problem and for now without any result.

Jack
  • 11
  • 1
  • 3
  • not sure but may be because of callback inside doBackground correct me if i am wrong but by the time you get your result from call back dobackground probably dead – Rachit Solanki Aug 19 '16 at 18:55
  • @Rachit Solanki if that's the problem then how to fix it? Handlers, Threads, ASyncTask is like another world to me. – Jack Aug 19 '16 at 19:48
  • if your ResultCallback is async runs on separate thread then you can remove it from async task – Rachit Solanki Aug 21 '16 at 07:27

1 Answers1

2

Your error Handler on a dead thread may came from a service which die immediately when they finish. You can use IntentService to create a new thread when you call the onHandleIntent method and then kill the thread as soon as onHandleIntent method returns.

Try to create your listener somewhere else, IntentService are not safe for setting up listeners because they die. It mainly used for executing a short task outside of the main thread.

Here's a related SO ticket that may help you solve your issue: Sending message to a Handler on a dead thread when getting a location from an IntentService

Community
  • 1
  • 1
Android Enthusiast
  • 4,826
  • 2
  • 15
  • 30