如何在选项卡之间保留本地服务 运行?

How to keep a local service running in between tabs?

我目前正在开发计步器应用程序。起初,我从一个 activity,PedometerActivity 开始。 activity 在后台启动了应该 运行 的服务,并绑定到它。代码很长,所以我只给出我认为对我的问题有帮助的部分。

//Bind service
    private ServiceConnection mServiceConnection = new ServiceConnection() {
        public void onServiceConnected(ComponentName className, IBinder service) {

            //binder to communicate with the service
            PedometerService.PedometerBinder mBinder = (PedometerService.PedometerBinder)service;

            mPedometerService = mBinder.getService();
            mPedometerService.registerCallback(mCallback);
        }

        public void onServiceDisconnected(ComponentName className) {
            mPedometerService = null;
        }
    };

private void startPedometerService() {
        if (!isPedometerService) {
            Log.v(TAG, "Start service");
            isPedometerService = true;

            //start service
            Intent intent = new Intent(getApplicationContext(),
                    PedometerService.class);
            startService(intent);
        }
    }

    //Bind to the service
    private void bindPedometerService() {
        Log.i(TAG, "Bind service");

        Intent intent = new Intent(PedometerActivity.this, PedometerService.class);
        bindService(intent, mServiceConnection,
                Context.BIND_AUTO_CREATE + Context.BIND_DEBUG_UNBIND);
    }

    //close connection with service
    private void unbindPedometerService() {
        Log.i(TAG, "Unbind service");
        unbindService(mServiceConnection);
    }

    //Stop the service that had been started
    private void stopPedometerService() {
        Log.i(TAG, "Stop service");
        if (mPedometerService != null) {

            //stop service
            Intent intent = new Intent(PedometerActivity.this, PedometerService.class);
            stopService(intent);

            isPedometerService = false;
        }
    }

@Override
    public void onResume() {
        Log.i(TAG, "onResume");
        super.onResume();

        startPedometerService();
        bindPedometerService();


    }


    @Override
    public void onStop() {
        super.onStop();
        Log.i(TAG, "onStop");
        stopPedometerService();

    }

    public void onDestroy() {
        super.onDestroy();

        unbindPedometerService();
        stopPedometerService();        

    }

在扩展服务

的服务class中
 /*Local service binding*/
    public class PedometerBinder extends Binder {
        public PedometerService getService() {
            return PedometerService.this;
        }
    }


    /*A client is binding to the service with bindService()
    * Returns the IBinder object received in
     * ServiceConnection.onServiceConnected(ComponentName,IBinder)*/
    @Override
    public IBinder onBind(Intent intent) {
        return new PedometerBinder();
    }

然后我修改了我的应用程序,使 tablayout 具有 3 个选项卡,因此有 3 个片段。我将 PedometerActivity 中的代码粘贴到 PedometerFragment 中并对其进行了修改

//Bind service
    private ServiceConnection mServiceConnection = new ServiceConnection() {
        public void onServiceConnected(ComponentName className, IBinder service) {

            //binder to communicate with the service
            PedometerService.PedometerBinder mBinder = (PedometerService.PedometerBinder)service;

            mPedometerService = mBinder.getService();
            mPedometerService.registerCallback(mCallback);
        }

        public void onServiceDisconnected(ComponentName className) {
            mPedometerService = null;
        }
    };

private void startPedometerService() {
        if (!isPedometerService) {
            Log.v(TAG, "Start service");
            isPedometerService = true;

            //start service
            Intent intent = new Intent(getActivity().getApplicationContext(),
                    PedometerService.class);
            getActivity().startService(intent);
        }
    }

    //Bind to the service
    private void bindPedometerService() {
        Log.i(TAG, "Bind service");

        Intent intent = new Intent(getActivity(), PedometerService.class);
        getActivity().bindService(intent, mServiceConnection,
                Context.BIND_AUTO_CREATE + Context.BIND_DEBUG_UNBIND);
    }

    //close connection with service
    private void unbindPedometerService() {
        Log.i(TAG, "Unbind service");
        getActivity().unbindService(mServiceConnection);
    }

    //Stop the service that had been started
    private void stopPedometerService() {
        Log.i(TAG, "Stop service");
        if (mPedometerService != null) {

            //stop service
            Intent intent = new Intent(getActivity(), PedometerService.class);
            getActivity().stopService(intent);

            isPedometerService = false;
        }
    }

@Override
    public void onResume() {
        Log.i(TAG, "onResume");
        super.onResume();

        startPedometerService();
        bindPedometerService();


    }


    @Override
    public void onStop() {
        super.onStop();
        Log.i(TAG, "onStop");
        stopPedometerService();

    }

    public void onDestroy() {
        super.onDestroy();

        unbindPedometerService();
        stopPedometerService();        

    }

问题是当我在选项卡之间切换时无法保持服务 运行ning。我正在使用 FragmentStatePagerAdapter,因此当我导航到最后一个选项卡时,第一个片段 (PedometerFragment) 被卸载。我已经能够在 onSaveInstanceState 中保存其他变量,但这似乎没有帮助,因为一切都重新启动了。

您正在使用 startService,因此即使您的绑定组件被销毁,服务也不应停止。但是,您在 onStop() 中显式调用 stopPedometerService(),当您的片段不再启动时调用它。

尝试简单地从片段中的 onStop()onDestroy() 中删除 stopPedometerService()

参见:https://developer.android.com/reference/android/support/v4/app/FragmentStatePagerAdapter.html

This version of the pager is more useful when there are a large number of pages, working more like a list view. When pages are not visible to the user, their entire fragment may be destroyed, only keeping the saved state of that fragment.

您需要在Activityclass中绑定服务。然后您可以通过接口或 public 方法从任何附加的 Fragment 使用它。