当前位置: 代码迷 >> Android >> Android 四大组件学习之Service4
  详细解决方案

Android 四大组件学习之Service4

热度:99   发布时间:2016-04-27 23:51:58.0
Android 四大组件学习之Service四

本节学习Service的生命周期。 既然Activity有生命周期,那同理Service也有自己的生命周期。

和学习Activity一样,我们先贴出Google官网给Service下的定义,以及生命周期图

从图中可以看到,左面一路下来是我们第二节课中说的用StartServer启动服务的流程。右面一路下来的是第三节中说的用BindService启动服务的流程。

在上两节中都看到了如何启动服务,同时销毁服务。既然这年代是混搭的年代,那当然也需要这两种服务混搭起来使用。

先来看看MyActivity的代码:

public class MyActivity extends Activity {	private Button btn_start;	private Button btn_end;	private Button btn_bind;	private Button btn_unbind;	private MyServiceConnection sConnection;		@Override	protected void onCreate(Bundle savedInstanceState) {		// TODO Auto-generated method stub		super.onCreate(savedInstanceState);		setContentView(R.layout.activity_myservice);				btn_start = (Button)findViewById(R.id.button1);		btn_end = (Button)findViewById(R.id.button2);		btn_bind = (Button)findViewById(R.id.button3);		btn_unbind  = (Button)findViewById(R.id.button4);		btn_start.setOnClickListener(new OnClickListener() {						@Override			public void onClick(View arg0) {				// 启动服务				Intent intent = new Intent(MyActivity.this, MyService.class);				startService(intent);				Log.i("MyActivity", "创建服务按钮被按下!");			}		});				btn_end.setOnClickListener(new OnClickListener() {						@Override			public void onClick(View arg0) {				// 销毁服务				Intent intent = new Intent(MyActivity.this, MyService.class);				stopService(intent);				Log.i("MyActivity", "销毁服务按钮被按下!");			}		});				btn_bind.setOnClickListener(new OnClickListener() {						@Override			public void onClick(View arg0) {				// 启动服务				Intent intent = new Intent(MyActivity.this, MyService.class);				Log.i("MyActivity", "绑定服务按钮被按下!");				bindService(intent, sConnection, Service.BIND_AUTO_CREATE);			}		});				btn_unbind.setOnClickListener(new OnClickListener() {						@Override			public void onClick(View arg0) {				// 启动服务				Intent intent = new Intent(MyActivity.this, MyService.class);				Log.i("MyActivity", "解绑服务按钮被按下!");				unbindService(sConnection);			}		});	}		public class MyServiceConnection implements ServiceConnection	{		@Override//当连接服务成功后调用		public void onServiceConnected(ComponentName arg0, IBinder arg1) {			// TODO Auto-generated method stub			Log.i("MyActivity", "onServiceConnected");					}		@Override//当server所在的进程由于异常终止或者其他原因终止调用		public void onServiceDisconnected(ComponentName arg0) {			// TODO Auto-generated method stub			Log.i("MyActivity", "onServiceDisconnected");		}	}}

MyService的代码:(和上节的MyService代码是样的)
public class MyService extends Service {	private MyThread thread;	private boolean stopFlag = false;		@Override//必须实现的方法	public IBinder onBind(Intent arg0) {		// TODO Auto-generated method stub				//服务运行后,启动线程		if(!stopFlag)		{			thread.start();			thread.setFlag(true);			}		Log.i("MyService", "onBind------------");		return null;	}		@Override//被创建时的调用	public void onCreate() {		// TODO Auto-generated method stub				//服务创建时,实例化MyThread		thread = new MyThread();		Log.i("MyService", "onCreate------------");				super.onCreate();	}		@Override	@Deprecated//OnStart方法现在被OnStartCommd已经取代,其实在OnStartCommand也调用了OnStart	public void onStart(Intent intent, int startId) {		// TODO Auto-generated method stub		super.onStart(intent, startId);		Log.i("MyService", "onStart------------");	}			@Override//启动时会调用	public int onStartCommand(Intent intent, int flags, int startId) {		// TODO Auto-generated method stub		Log.i("MyService", "onStartCommand------------");		//服务运行后,启动线程		if(!stopFlag)		{			thread.start();			thread.setFlag(true);			}		return super.onStartCommand(intent, flags, startId);	}		@Override	public void onDestroy() {		// TODO Auto-generated method stub				//服务销毁时,停止线程任务		thread.setFlag(false);		Log.i("MyService", "onDestroy------------");				super.onDestroy();	}		@Override	public boolean onUnbind(Intent intent) {		// TODO Auto-generated method stub		Log.i("MyService", "onUnbind------------");		return super.onUnbind(intent);	}		class MyThread extends Thread	{		//设置flag		public void setFlag(Boolean flag)		{			stopFlag = flag;		}				@Override		public void run() {			super.run();			while(stopFlag)			{				//设置时间的输出方式				SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");				String  time = format.format(new Date());								//显示时间				Log.i("MyService", time);								try {					//延迟一秒					Thread.sleep(1000);				} catch (InterruptedException e) {					// TODO Auto-generated catch block					e.printStackTrace();				}			}		}	}


那既然要学习两者混搭,那就看有几种混搭的方式:

1: 用StartServer启动服务,然后再去用BindService绑定服务

可以看到是先StartServer启动服务,在用BindService绑定服务

接着,我们用stopservice停止服务

可以看到服务是无法停止的

那如果我们用unbindService先解绑服务

可以看到用解绑服务是可以停止服务 的。

2: 用BindService绑定服务,然后再去用StartServer启动服务

可以看到依然按停止服务是不行的,必须先解绑服务


那总结一下: 混合调用时,不论是先启动服务还是绑定服务,最后都需要解绑服务,不过不解绑服务,服务是停止不了的。


那再看一个现象,如果服务正在运行,我将当前Activity直接按Back键退出,会有怎么样的效果?

首先在MyActivity中增加如下方法

	@Override	public boolean onKeyDown(int keyCode, KeyEvent event) {		// TODO Auto-generated method stub		if(keyCode == KeyEvent.KEYCODE_BACK)		{			Log.i("MyActivity", "KEYCODE_BACK is pressed!");		}		return super.onKeyDown(keyCode, event);	}    @Override    protected void onDestroy() {        Log.i("MyActivity", "onDestroy");        super.onDestroy();    }

1:用Startservice启动服务,然后退出Activity


可以看到当我按下back键后Activity是销毁了,但是我们的服务依然是运行的。这可以说明StartServer启动服务与Activity没有关系

如果停止服务,必须要设置->app->正在运行中停止服务


2:用BindService启动服务,然后退出

可以看到用BindService启动服务,当Activity退出时,服务就停止了。说明BindService启动的服务是和Actiivty是相关的。



那这个问题,看完后,我们再次回到我们的混搭service上。

如果,让我们用混搭的方式启动服务后, 而没有解绑,是直接退出Activity了。

因为bindService启动服务和Activity是有关联的,Activity销毁也会解绑的。但是我们中间有用StartServer启动服务,所以服务依旧在运行。关于直接退出有异常。我们可以在Activity退出的Destory方法中调用onunbindService

	@Override	protected void onDestroy() {		Log.i("MyActivity", "onDestroy");		unbindService(sConnection);		super.onDestroy();	}
然后直接退出就不会有异常打印。



好,关于serive的生命周期就说到这里。




版权声明:本文为博主原创文章,未经博主允许不得转载。

  相关解决方案