当Activity被销毁时,为什么Service会破坏自我?

时间:2017-12-24 03:37:23

标签: android service binding destroy

我想从Activity启动服务,然后即使活动退出/结束也继续运行。然后,当我再次启动应用程序活动时,它将重新连接到现有服务。

我已经阅读了关于bindService的文档,但是每次按下后退按钮退出活动时,服务的onUnBind都会被自动调用,从而有效地终止服务。我想我必须在服务未绑定之前手动调用unbindService。

我确实知道,一旦Activity被销毁,一旦创建了新的Activity,就必须重新填充成员变量mService,mBound和tv,所以下面的简单代码将显示“bindService的启动并不奇怪。 “但我认为LocalService实例中的所有成员变量都是相同的,没有变化,因此”bindService已经开始.Val =“+ mService.myval; 应该保持不变每次我重新启动一个新活动时都应该这样做,不是吗?

MainActivity

public class MainActivity extends AppCompatActivity
{
    LocalService mService;
    Boolean mBound = false;
    TextView tv;

    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        tv = (TextView)findViewById(R.id.textView);    
    }

    @Override
    protected void onStart()
    {
        super.onStart();
    }

    @Override
    protected void onStop()
    {
        super.onStop();
    }

    @Override
    protected void onDestroy()
    {
        super.onDestroy();
    }

    public void onButtonStart(View v)
    {
        String str;

        // Bind to LocalService
        if (!mBound)
        {
            Intent intent = new Intent(this, LocalService.class);

            if (!bindService(intent, mConnection, Context.BIND_AUTO_CREATE))
            {
                unbindService(mConnection);
                str = "bindService failed?!";
            }
            else
            {
                str = "bindService started.";
            }
        }
        else
            str = "bindService already Started. Val = " + mService.myval;

        tv.setText(str);
    }  

    public void onButtonStop(View v)
    {
        if (mBound)
        {
            mService.stop();
            unbindService(mConnection);
            mBound = false;

            tv.setText("Stopped Service");
        }
        else
            tv.setText("Service is not running");
    }

    private ServiceConnection mConnection = new ServiceConnection()
    {
        @Override
        public void onServiceConnected(ComponentName className, IBinder service)
        {
            // We've bound to LocalService, cast the IBinder and get LocalService instance
            LocalService.LocalBinder binder = (LocalService.LocalBinder) service;
            mService = binder.getService();
            mBound = true;
        }

        @Override
        public void onServiceDisconnected(ComponentName arg0)
        {
            mBound = false;
        }
    };   
 }

本地服务

public class LocalService extends Service
{
    private final IBinder mBinder = new LocalBinder();
    private final Random mGenerator = new Random();
    public int myval = getRandomNumber();

    @Override
    public void onCreate()
    {
        super.onCreate();
    }

    // Service is being Destroyed
    @Override
    public void onDestroy()
    {
        super.onDestroy();
    }

    public int getRandomNumber()
    {
        return mGenerator.nextInt(100);
    }

    @Override
    public IBinder onBind(Intent intent)
    {
        return mBinder;
    }

    // Client is Unbinding via the unbindService() call
    @Override
    public boolean onUnbind(Intent intent)
    {
        return super.onUnbind(intent);
    }

    public class LocalBinder extends Binder
    {
        public LocalService getService()
        {
            return LocalService.this;
        }
    }   
}

2 个答案:

答案 0 :(得分:1)

“如果你用startService(..)启动一个android服务,那么服务将一直运行,直到你明确地调用stopService(..)。系统可以运行服务有两个原因。如果有人调用Context。 startService()然后系统将检索服务(创建它并在需要时调用其onCreate()方法),然后使用客户端提供的参数调用其onStartCommand(Intent,int,int)方法。此时服务将继续运行,直到调用Context.stopService()或stopSelf()。注意,对Context.startService()的多次调用不会嵌套(尽管它们会导致多次对onStartCommand()的相应调用),所以无论多少次它启动后,一旦调用了Context.stopService()或stopSelf(),服务就会停止;但是,服务可以使用它们的stopSelf(int)方法来确保在处理完启动意图之前不停止服务。

客户端还可以使用Context.bindService()来获取与服务的持久连接。如果服务尚未运行(在执行此操作时调用onCreate()),这同样会创建服务,但不会调用onStartCommand()。客户端将接收服务从其onBind(Intent)方法返回的IBinder对象,允许客户端然后回调该服务。只要建立连接,服务将保持运行(无论客户端是否保留对服务的IBinder的引用)。通常,IBinder返回的是一个用AIDL编写的复杂接口。

服务既可以启动,也可以绑定连接。在这种情况下,只要系统启动或者使用Context.BIND_AUTO_CREATE标志有一个或多个连接,系统就会保持服务运行。一旦这些情况都不成立,就会调用Service的onDestroy()方法并有效终止服务。从onDestroy()返回时,应完成所有清理(停止线程,取消注册接收器)。“

答案 1 :(得分:0)

我可以看到你正在使用bindService()

  

绑定服务通常只在服务于另一个应用程序组件时才存在,并且不会无限期地在后台运行。

因此,如果您的活动(绑定到服务)已经完成,那么服务将不再运行。

要在后台运行服务,您必须使用标记STICKY创建START_STICKY服务。

 @Override
public int onStartCommand(Intent intent, int flags, int startId) {
  // Do your task here
  return START_STICKY;
 }

START_STICKY服务可以在后台运行而不存在任何活动。您可以通过回调与服务进行通信。

创建Sticky service阅读Service