如何在标签之间保持本地服务运行?

时间:2017-10-31 07:57:21

标签: android android-fragments android-service android-service-binding fragment-lifecycle

我目前正在研究计步器应用程序。起初,我开始使用一项活动,即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();        

    }

在扩展服务

的服务类中
 /*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();        

    }

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

2 个答案:

答案 0 :(得分:1)

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

尝试从片段中的onStop()onDestroy()中删除public RestTemplate oAuthRestTemplate() { ClientCredentialsResourceDetails resourceDetails = new ClientCredentialsResourceDetails(); resourceDetails.setId("1"); resourceDetails.setClientId(clientId); resourceDetails.setClientSecret(clientSecret); resourceDetails.setAccessTokenUri(accessTokenUrl); resourceDetails.setTokenName("accessToken"); resourceDetails.setClientAuthenticationScheme(AuthenticationScheme.form); OAuth2RestTemplate restTemplate = new OAuth2RestTemplate(resourceDetails, new DefaultOAuth2ClientContext()); return restTemplate; }

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

  

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

答案 1 :(得分:0)

您需要绑定Activity类中的服务。然后,您可以从任何附加的Fragment via界面或公共方法中使用它。