【发布时间】:2016-12-23 02:28:25
【问题描述】:
我需要在自定义服务中并行执行多个任务才能使这些工作正常运行:
- 位置服务和活动识别 API。
- 地理围栏 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";
}
}
}
我不确定这是否是获得我需要的正确或最佳方式。
非常感谢任何帮助!
【问题讨论】:
-
您不会在 Android 中“关闭应用程序”。请准确解释您所说的“关闭应用程序”是什么意思。
-
这只是多任务按钮(显示打开的应用程序的按钮)。所以,我把它刷掉,它应该继续在后台运行。
-
终止后台进程,就好像进程因内存不足而终止一样。
-
是的,但是当服务重新启动时(返回 START_STICKY;),位置更新不再起作用。
-
我不知道“位置更新不再起作用”的确切含义。您将需要再次设置位置更新,这在您的问题中没有的代码中。您的进程可以随时终止,即使使用服务也是如此,因此这是您的应用需要能够处理的场景。
标签: android multithreading locationlistener threadpoolexecutor background-service