0

我有一个粘性服务(START_STICKY从中返回onStartCommand),它在 中执行一些代码AsyncTask,但是我在如何以及何时开始、绑定、停止、取消绑定方面遇到了一些问题。我只希望在父活动还活着的时候服务,我不希望它在应用程序关闭时在后台徘徊,但我需要该服务在方向变化中幸存下来。我目前不需要该服务在整个活动期间都处于活动状态,因此我在我的主要工作完成后调用 stopSelf() AsyncTaskService然后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

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

1 回答 1

0

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

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

于 2011-09-16T18:23:41.393 回答