2

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

//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();        

    }

在扩展 Service 的服务类中

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

然后我修改了我的应用程序,使其具有带有 3 个选项卡的 tablayout,因此有 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();        

    }

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

4

2 回答 2

1

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

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

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

当有大量页面时,此版本的寻呼机更有用,更像列表视图。当页面对用户不可见时,它们的整个片段可能会被销毁,只保留该片段的已保存状态。

于 2017-10-31T08:21:48.673 回答
0

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

于 2017-10-31T08:50:53.203 回答