粘性服务管理

时间:2011-09-16 16:08:21

标签: android service sticky

我有一个粘性服务(从START_STICKY返回onStartCommand),它在AsyncTask中执行了一些代码,但我在如何以及何时启动方面遇到了一些问题,绑定,停止,解除绑定。我只想在父活动活着期间提供服务,我不希望它在应用程序关闭时在后台闲逛,但我需要服务才能在方向更改后继续存在。我目前不需要在活动的整个持续时间内激活该服务,因此我在AsyncTask的{​​{1}}中完成主要工作后调用stopSelf()然后启动需要时再次Service。有时我需要中断服务正在进行的工作,取消Service并使用不同的数据重新开始。问题在于,无论我做什么 - 我似乎无法在所有不同的场景中得到它。任何人都可以看看并告诉我我做错了什么?

我的AsyncTask是:

Service

目前,我在创建自定义public class ChordCalculatorService extends Service { private final IBinder mBinder = new LocalBinder(); private AsyncTask<SearchData, SearchStatusData, List<Item>> currentTask; @Override public void onCreate() {} @Override public int onStartCommand(Intent intent, int flags, int startId) { // We want this service to continue running until it is explicitly // stopped, so return sticky. return START_STICKY; } /** * Class for clients to access. Because we know this service always runs in * the same process as its clients, we don't need to deal with IPC. */ public class LocalBinder extends Binder { public ChordCalculatorService getService() { return ChordCalculatorService.this; } } @Override public void onDestroy() { super.onDestroy(); } @Override public IBinder onBind(Intent intent) { return mBinder; } public SearchData getSearchData() { return searchData; } public void startWork() { if (currentTask != null && currentTask.getStatus() == Status.RUNNING) { currentTask.cancel(true); } if(searchData != null) { Worker task = new Worker(); currentTask = task.execute(new SearchData[] { searchData }); } else { Message msg = handler.obtainMessage(ERROR, "No search data set"); handler.sendMessage(msg); } } class Worker extends AsyncTask<SearchData, SearchStatusData, List<Item>> { // ... code ... @Override protected void onPostExecute(List<Item> result) { Message msg = handler.obtainMessage(COMPLETE, new StatusData(Status.STATUS_FINISHED, result)); handler.sendMessage(msg); stopSelf(); } } } 时启动了Service

View

并在public class MyCustomView extends BasicFretBoardView { private ServiceConnection conn; private MyService myService; private boolean isServiceStarted; private boolean isServiceBound; public MyCustomView(Context context, AttributeSet attr) { super(context, attr); startService(); } public void startService() { Intent serviceIntent = new Intent(getContext(), MyService.class); conn = new ServiceConnection() { @Override public void onServiceConnected(ComponentName name, IBinder service) { myService = ((LocalBinder) service).getService(); myService.registerHandler(serviceHandler); } @Override public void onServiceDisconnected(ComponentName name) { myService = null; } }; // Explicitly start the service. Don't use BIND_AUTO_CREATE, since it // causes an implicit service stop when the last binder is removed. getContext().startService(serviceIntent); getContext().bindService(serviceIntent, conn, 0); isServiceStarted = true; isServiceBound = true; } public void stopService() { if (isServiceStarted) { Intent serviceIntent = new Intent(getContext(), MyService.class); getContext().stopService(serviceIntent); isServiceStarted = false; } unBindService(); } public void unBindService() { if(isServiceBound) { getContext().unbindService(conn); isServiceBound = false; } } // gets called based on some user interaction private void startServiceWork() { if(!isServiceStarted) { startService(); } else { myService.cancelCalcalation(); } myService.setData(data); myService.startWork(); } }

中处理停止服务
Activity

1 个答案:

答案 0 :(得分:0)

似乎您希望您的任务按需运行,也许IntentService可能是更合适的选择。当您需要完成工作(startServiceWork())时,您只需启动该服务即可启动AsyncTask。任务完成后,服务将完成。

现在,关于方向更改,您必须实现其意图过滤器为“android.intent.action.CONFIGURATION_CHANGED”的广播接收器。 (我假设您希望服务在方向更改时起作用)将广播接收器放在您的activity / main ui线程中。这实际上会使广播接收器的主机进程成为主要的应用程序进程,从而使从广播接收器内启动服务更安全。