当Activity被销毁时,为什么Service会破坏自我?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了当Activity被销毁时,为什么Service会破坏自我?相关的知识,希望对你有一定的参考价值。
我想从一个Activity启动一个服务,然后让它继续运行,即使活动退出/结束。然后,当我再次启动应用程序活动时,它会重新连接到现有服务。
我已经阅读了关于bindService的文档,但是每次按下后退按钮退出活动时,服务的onUnBind都会被自动调用,从而有效地终止服务。我想我必须在服务未绑定之前手动调用unbindService。
我不知道,一旦Activity被销毁,成员变量mService,mBound和tv必须在创建新Activity时重新填充,所以下面的简单代码将显示“bindService started”并不奇怪。但我认为LocalService实例中的所有成员变量都是相同的,没有变化,所以“bindService已经开始.Val =”+ mService.myval;每次重新启动一项新活动应该保持不变,不是吗?
主要信息
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;
}
}
}
“如果你用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()返回时,应完成所有清理(停止线程,取消注册接收器)。“
我可以看到你正在使用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。
以上是关于当Activity被销毁时,为什么Service会破坏自我?的主要内容,如果未能解决你的问题,请参考以下文章