我有一个粘性服务(从onStartCommand返回START_STICKY ),它执行AsyncTask中的一些代码,但我在如何以及何时启动、绑定、停止和解除绑定方面遇到了一些问题。我只想让服务在父母活动活跃的时候存在,我不希望它在应用程序关闭时挂在后台,但我需要服务在方向改变后存活下来。目前,我不需要服务在活动的整个持续时间内都处于活动状态,因此我在Service中的AsyncTask中完成主要工作后调用stopSelf(),然后在需要时再次启动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();
}
}
}目前,我已经在创建自定义View时启动了Service:
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中处理的
public class CustomChordActivity extends Activity {
// ... code ...
@Override
public void onBackPressed() {
super.onBackPressed();
}
@Override
protected void onPause() {
if(isFinishing()) {
chordsView.stopService();
}
super.onPause();
}
@Override
protected void onStop() {
super.onStop();
}
@Override
protected void onDestroy() {
chordsView.unBindService();
super.onDestroy();
}
@Override
protected void finalize() throws Throwable {
super.finalize();
}
}发布于 2011-09-17 02:23:41
似乎你想让你的任务按需运行,也许IntentService会是一个更合适的选择。当您需要完成工作时,(startServiceWork()),您只需启动服务,这将启动您的AsyncTask。然后,服务将在任务完成后结束。
现在,关于方向更改,您必须实现一个意图过滤器为"android.intent.action.CONFIGURATION_CHANGED".的广播接收器(我假设您希望服务在方向更改时执行工作)将广播接收器放在您的活动/主ui线程中。这实际上会使广播接收器的托管进程成为主要应用程序进程,从而更安全地从广播接收器内部启动服务。
https://stackoverflow.com/questions/7447537
复制相似问题