当应用关闭时,ThreadPoolExecutor的自定义服务类被终止

时间:2015-06-02 22:42:38

标签: android multithreading locationlistener threadpoolexecutor background-service

我需要在自定义服务中并行执行multipe任务才能使这些工作正常运行:
- 位置服务和活动识别API - Geofence API和REST API调用。

我是java和android中的线程的新手,我发现实现它的最好方法是使用ThreadPoolExecutor而不是创建我自己的线程类并处理所有Handler Looper的东西。

当我执行我的应用程序时,服务启动,位置更新和活动更新在一个线程内正常工作。但是,当我关闭应用程序时,服务重新启动(当return START_STICKY;时)并且线程不再工作。当(return START_NOT_STICKY;)时,服务消失。 (在我的情况下,我不能使用startforeground())

我正在使用此库(smart-location-lib)进行位置和活动更新。

- 这是我的自定义服务代码:

public class LocationService extends Service {

    private ThreadPoolExecutor mDecodeThreadPool;
    private BlockingQueue<Runnable> mDecodeWorkQueue;

    private int NUMBER_OF_CORES = Runtime.getRuntime().availableProcessors();
    private final int KEEP_ALIVE_TIME = 1;
    private final TimeUnit KEEP_ALIVE_TIME_UNIT = TimeUnit.SECONDS;

    public LocationService () {
    }

    @Override
    public void onCreate() {
        super.onCreate();
        Toast.makeText(this, "Location services created", Toast.LENGTH_SHORT).show();
        mDecodeWorkQueue = new LinkedBlockingQueue<Runnable>();
        mDecodeThreadPool = new ThreadPoolExecutor(
                NUMBER_OF_CORES * 2, // Initial pool size
                NUMBER_OF_CORES * 2, // Max pool size
                KEEP_ALIVE_TIME,
                KEEP_ALIVE_TIME_UNIT,
                mDecodeWorkQueue);    
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Toast.makeText(this, "Location services started", Toast.LENGTH_SHORT).show();
        mDecodeThreadPool.execute(new LocationRunnable(getApplicationContext()));
        return START_STICKY;
    }

    @Override
    public void onLowMemory() {
        super.onLowMemory();
        Log.v("LOW MEMORY", "|||||||||||||||||||||||||||||||||||||");

    }

    @Override
    public IBinder onBind(Intent intent) {
        throw new UnsupportedOperationException("Not yet implemented");
    }


    @Override
    public void onDestroy() {
        Toast.makeText(this, "Location services stopped", Toast.LENGTH_LONG).show();
        mDecodeThreadPool.shutdown();
        mDecodeThreadPool.shutdownNow();
        super.onDestroy();
    }
}

- 这是我的Runnable类代码:

public class LocationRunnable implements Runnable, OnLocationUpdatedListener, OnActivityUpdatedListener {

     SmartLocation smartLocation;
     public LocationRunnable(Context ctx) {
          smartLocation = new SmartLocation.Builder(ctx).logging(true).build();

     }

    @Override
    public void run() {
        Log.v("THREAD", "THREAD STARTED");
        startLocation();
     }


    private void startLocation() {
        smartLocation.location().start(this);
        smartLocation.activity().start(this);
    }

    @Override
    public void onActivityUpdated(DetectedActivity detectedActivity) {
        if (detectedActivity != null) {
            Log.v("ACTIVITY", "ACTIVITY UPDATED");
        } else {
            Log.v("ACTIVITY", "NULL");
        }

    }
    int i = 0;
    @Override
    public void onLocationUpdated(Location location) {
        Log.v("LOCATION", "LOCATION UPDATED" + i++);
    }

    private String getNameFromType(DetectedActivity activityType) {
        switch (activityType.getType()) {
            case DetectedActivity.IN_VEHICLE:
                return "in_vehicle";
            case DetectedActivity.ON_BICYCLE:
                return "on_bicycle";
            case DetectedActivity.ON_FOOT:
                return "on_foot";
            case DetectedActivity.STILL:
                return "still";
            case DetectedActivity.TILTING:
                return "tilting";
            default:
                return "unknown";
        }
    }

}

我不确定这是否是获得我需要的最佳方式 非常感谢任何帮助!

1 个答案:

答案 0 :(得分:0)

我意识到这个问题已经过时了,但它可能对其他人有所帮助。

我认为这是因为来自Runnable.run()的代码立即退出,从而结束了父线程,因此位置的更改不再有要发布的对象。

  。

smartLocation.location()启动(这个); //这个&lt; - 是Runnable

直到重新启动才获得更新的原因可能是垃圾收集没有清除不再使用的Runnable对象或代码中的某些现有引用。