【问题标题】:Sending message to a Handler on a dead thread when getting a location within Service在服务中获取位置时向死线程上的处理程序发送消息
【发布时间】:2023-04-02 09:54:01
【问题描述】:

我开发了 Android Wear 表盘,它可以在手持端的服务中获取位置。我使用从这里获得的 AsyncTask 代码。 此错误会耗尽手机约 50% 的电量。我不知道为什么。请帮忙。 错误:

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)

我的服务:

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

    }

这里是 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;
        }
    }

请帮忙,我是一名新开发人员,正在尝试解决这个问题,但目前没有任何结果。

【问题讨论】:

  • 不确定,但可能是因为 doBackground 内部的回调,如果我错了,请纠正我,但是当你从回调中得到结果时,dobackground 可能已经死了
  • @Rachit Solanki 如果这是问题所在,那么如何解决?处理程序、线程、ASyncTask 对我来说就像另一个世界。
  • 如果您的 ResultCallback 是异步运行在单独的线程上,那么您可以将其从异步任务中删除

标签: android android-asynctask wear-os


【解决方案1】:

您的错误Handler on a dead thread 可能来自一个服务,该服务在完成后立即死亡。您可以在调用 onHandleIntent 方法时使用IntentService 创建一个新线程,然后在 onHandleIntent 方法返回时立即终止该线程。

尝试在其他地方创建您的侦听器,IntentService 设置侦听器不安全,因为它们会死掉。它主要用于在main thread 之外执行一个短任务。

这是一个相关的 SO 票证,可以帮助您解决问题:Sending message to a Handler on a dead thread when getting a location from an IntentService

【讨论】:

    猜你喜欢
    • 2013-06-18
    • 2013-12-02
    • 2012-01-31
    • 2019-08-30
    • 1970-01-01
    • 1970-01-01
    • 2016-10-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多