当前位置: 代码迷 >> Android >> Android四大组件之—— 使用服务开展后台操作
  详细解决方案

Android四大组件之—— 使用服务开展后台操作

热度:268   发布时间:2016-04-28 02:26:38.0
Android四大组件之—— 使用服务进行后台操作

 

什么是服务

       服务是一个没有可视化界面的组件,它可以在后台长期运行并进行各种操作。

 

服务的创建

       我们只需要继承Service类并实现相应的方法即可创建服务

       要想启动服务,还得在AndroidManifest中注册服务

 

服务类的示例代码

 

package com.whathecode.servicedemo;import android.app.Service;import android.content.Intent;import android.os.IBinder;import android.widget.Toast;public class ExtendsionService extends Service{	/**	 * 当服务第一次被创建的时候调用此方法	 */	@Override	public void onCreate()	{				super.onCreate();		Toast.makeText(getBaseContext(), "服务被创建了", Toast.LENGTH_SHORT).show();	}		/**	 * 当通过startService方法启动服务时此方法被调用	 */	@Override	public int onStartCommand(Intent intent, int flags, int startId)	{		Toast.makeText(getBaseContext(), "服务被启动了", Toast.LENGTH_SHORT).show();		return super.onStartCommand(intent, flags, startId);	}	@Override	public IBinder onBind(Intent intent)	{		return null;	}	@Override	public void onDestroy()	{		super.onDestroy();	}}

 

使用startService启动服务

主界面的逻辑代码:

 

package com.whathecode.servicedemo;import android.app.Activity;import android.content.Intent;import android.os.Bundle;import android.view.View;public class MainActivity extends Activity{	Intent service = null;	@Override	protected void onCreate(Bundle savedInstanceState)	{		super.onCreate(savedInstanceState);		setContentView(R.layout.activity_main);				//创建服务		service = new Intent(this, ExtendsionService.class);	}	public void start(View view)	{		//启动服务		startService(service);	}		public void stop(View view)	{		//停止服务		stopService(service);	}}

 

注册服务:

 

<service android:name="com.whathecode.servicedemo.BackgroundService"></service>

 

运行效果:

 

startService

 

注意:

         当我们第一次点击启动服务按钮的时候,onCreate方法和onStartCommand方法依次执行,

         但在第二次点击启动服务按钮的时候,这个服务已经处于运行状态,onCreate方法不再执行第二次,

         而onStartCommand方法总是在调用startService启动服务的时候执行。

         onDestroy方法在stopService方法被调用后执行。

 

除了使用startService方法启动服务外,我们还可以使用Bind的方式启动服务。

前者和后者的不同在于:

      服务的生命周期不依赖于启动者。服务被启动后一直在后台运行直到调用stopService被停止。

       使用Bind方式启动服务,服务的生命周期依赖于启动者。即服务在启动者退出后自动销毁。

 

使用Bind方式启动服务

主要使用bindService方法启动服务,unbindService方法销毁服务。

使用此方式启动服务的好处是,bind定成功的时候服务返回一个IBinder对象,

我们可以通过在服务类里面实现这个对象,从而访问服务里面的具体方法。

从而达到和服务沟通的目的。

 

注意:

        我们不能以直接实例化服务的方式调用里面的方法。

 

另外:

       如果在退出服务的时候没有解绑,那么程序就会抛出异常IllegalArgumentException异常。

       因此,每次调用bindService启动服务,完成后需要退出服务都需要使用unbindService 解绑。  

 

示例代码:

package com.whathecode.servicedemo;import android.app.Activity;import android.content.ComponentName;import android.content.Intent;import android.content.ServiceConnection;import android.os.Bundle;import android.os.IBinder;import android.view.View;public class MainActivity extends Activity{	Intent service = null;	IReceptionist rpst;	/**	 * bindService和unbindService方法使用的参数	 */	private ServiceConnection conn = new ServiceConnection()	{				//此方法在服务连接被意外终止的时候被调用,		@Override		public void onServiceDisconnected(ComponentName name)		{				}				//当服务被连接上的时候自动调用这个方法,第二个参数是服务类onBind方法中返回的对象		@Override		public void onServiceConnected(ComponentName name, IBinder service)		{			rpst = (IReceptionist) service;			rpst.callExtendsionNumber();		}	};		@Override	protected void onCreate(Bundle savedInstanceState)	{		super.onCreate(savedInstanceState);		setContentView(R.layout.activity_main);				//创建服务		service = new Intent(this, ExtendsionService.class);	}	public void start(View view)	{		//启动服务		startService(service);	}		public void stop(View view)	{		//停止服务		stopService(service);	}		public void bind(View view)	{		//绑定服务		bindService(service, conn , BIND_AUTO_CREATE);	}		public void unBind(View view)	{		//解绑服务		unbindService(conn);	}}

 

继承ServiceBinder对象,并实现自定义接口:

通过这个方式,我们可以暴露只需要的方法,实现代码的保护。

 

IReceptionist接口代码:
package com.whathecode.servicedemo;public interface IReceptionist {	public void callExtendsionNumber();}

 

ExtendsionService服务类代码:

 

package com.whathecode.servicedemo;import android.app.Service;import android.content.Intent;import android.os.Binder;import android.os.IBinder;import android.util.Log;import android.widget.Toast;public class ExtendsionService extends Service{	private static final String TAG = "ExtendsionService";	/**	 * 当服务第一次被创建的时候调用此方法	 */	@Override	public void onCreate()	{				super.onCreate();		Toast.makeText(getBaseContext(), "服务被创建了", Toast.LENGTH_SHORT).show();	}		/**	 * 当通过startService方法启动服务时此方法被调用	 */	@Override	public int onStartCommand(Intent intent, int flags, int startId)	{		Toast.makeText(getBaseContext(), "服务被启动了", Toast.LENGTH_SHORT).show();		return super.onStartCommand(intent, flags, startId);	}	@Override	public IBinder onBind(Intent intent)	{		return new ServiceBinder();	}	@Override	public void onDestroy()	{		Toast.makeText(getBaseContext(), "服务被销毁了", Toast.LENGTH_SHORT).show();		Log.d(TAG, "服务被销毁了");		super.onDestroy();	}		public void putExtendsion()	{		Toast.makeText(getBaseContext(), "正在帮你转接分机", Toast.LENGTH_SHORT).show();	}		/**	 * 	 * 继承Binder并实现IReceptionist接口	 * 继承Binder类的目的是onBind方法中需要返回这个类型的对象	 * 	 * 实现IReceptionist接口是暴露方法的需要	 */	private class ServiceBinder extends Binder implements IReceptionist	{		public void callExtendsionNumber()		{			putExtendsion();		}				private void otherMethod()		{					}	}}

 

运行效果:

bindService

 

注意看上图,我们在按下返回键的时候,Activity被销毁,由它启动的服务也跟着被销毁。

这样的服务貌似作用不大,有没有办法在退出Activity的时候不退出服务呢?

答案是有的:Android允许我们先启动一个服务,然后再调用bindService绑定到服务,

                    这样,我们既可以达到和服务沟通的目的,也可以使服务长期在后台运行。

 

看下图:

bindService

 

通过下面的图,就可以更清楚地理解上面代码的工作原理:

 

Service

  相关解决方案