Android中service的介绍和使用

一、简介

Android中service(服务)运行于后台,没有界面。和其他组件一样,service也运行在主线程中,因此不能用它来做耗时的请求或者动作。可以在服务中开启线程,在线程中做耗时操作。可以启动一个服务service来播放音乐,或者记录地理信息位置的改变,或者启动一个服务来运行并一直监听某种动作。

二、Service的种类

服务一般分为两种:

1、本地服务,Local Service用于应用程序内部。

    在Service可以调用Context.startService()启动,调用Context.stopService()结束。在内部可以调用Service.stopSelf() 或Service.stopSelfResult()来停止。无论调用了多少次startService(),都只需调用一次stopService()来停止。调用startForeground()方法可以将服务运行于前台并在通知栏展示。

2、远程服务,Remote Service用于android系统内部的应用程序之间。

    可以定义接口并把接口暴露出来,以便其他应用进行操作。客户端建立到服务对象的连接,并通过那个连接来调用服务。调用Context.bindService()建立连接并启动,调用Context.unbindService()关闭连接。多个客户端可以绑定至同一个服务。如果服务此时还没有加载,bindService()会先加载它。提供给可被其他应用复用,比如定义一个天气预报服务,提供与其他应用调用即可。

三、Service的简单使用

1、startservice方法

        (1)、自定义类继承系统Service,复写生命周期方法,在AndroidManifest.xml文件中通过service标签注册自定义服务

/**
 * 创建Service的步骤:
 * 1、自定义类继承系统Service
 * 2、复写生命周期方法
 * 3、在AndroidManifest.xml文件中通过service标签注册自定义服务
 * 
 * 注意:Service在Application中是一全局的方式存在
 *
 */
public class MyService extends Service{
	
	/**
	 * 创建Service时被调用
	 * 此方法在一个Service的生命周期中只会别调用一次
	 * 一般在此方法中初始化数据
	 */
	@Override
	public void onCreate() {
		super.onCreate();
		android.util.Log.e("danny", "MyService--onCreate");
	}
	
	/**
	 * 每次调用startService时都会调用此方法
	 * @param intent 就是startService时所使用的intent对象
	 * 根据此方法的返回值,决定所创建的Service是否是粘性服务
	 * START_NOT_STICKY			非粘性服务
	 * START_STICKY				粘性不带记忆服务
	 * START_REDELIVER_INTENT	粘性带记忆服务
	 * 一般在此方法中开启线程做耗时操作
	 */
	@Override
	public int onStartCommand(Intent intent, int flags, int startId) {
		android.util.Log.e("danny", "MyService--onStartCommand");
		
		String threadName = Thread.currentThread().getName();
		android.util.Log.e("danny", "threadName is " + threadName);
		
		new Thread(){
			public void run() {
				for(int i = 0; i < 10; i++){
					try {
						Thread.sleep(1000);
						android.util.Log.e("danny", "执行到 " + i);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}
				
				Intent broad = new Intent();
				broad.setAction("MyBroadcas");
				sendBroadcast(broad);
			};
		}.start();
		return START_REDELIVER_INTENT;
	}

	/**
	 * 此方法跟启动服务没有任何关系,只跟绑定服务有关
	 */
	@Override
	public IBinder onBind(Intent intent) {
		android.util.Log.e("danny", "MyService--onBind");
		return null;
	}

	/**
	 * 当Service被销毁时调用此方法
	 * Service销毁的情况;
	 * 	1 Activity.stopService
	 * 	2 Service.stopSelf()
	 */
	@Override
	public void onDestroy() {
		android.util.Log.e("danny", "MyService--onDestroy");
		super.onDestroy();
	}
}

(2)、调用startService方法启动服务;停止时调用stopService方法停止服务

case R.id.startService:
     /*
     * startService启动Service的步骤
     * 1、创建启动服务的Intent对象,并指定目标Service
     * 2、Context.startServie方法启动服务,并传递Intent对象
     * 
     * 特点:
     * 通过startService启动的服务不会跟Activity进行绑定
     * 当销毁Activity时,Service不会被自动销毁
     */
     Intent intent = new Intent(this, MyService.class);
     startService(intent);
     break;
case R.id.stopService:
     Intent stopIntent = new Intent(this, MyService.class);
     stopService(stopIntent);  //调用Context.stopService方法停止目标Service
     break;

2、bindService方法

       (1)、自定义类继承系统Service,复写生命周期方法,在AndroidManifest.xml文件中通过service标签注册自定义服务

/**
 * 通过bindService绑定的服务
 * 	生命周期:onCreate onBind onUnBind onDestroy
 *
 */
public class MusicService extends Service {
	
	/**
	 * 创建服务时被调用,此方法在一个生命周期中只会被调用一次
	 */
	@Override
	public void onCreate() {
		super.onCreate();
	}

	/**
	 * 当第一次调用bindService时,此方法被调用
	 * note:如果一个服务已经被绑定,则不会被再辞绑定
	 * @param intent		调用bindService时所传递的Intent对象
	 * @return  返回给bindService中ServiceConnection接口参数
	 */
	@Override
	public IBinder onBind(Intent intent) {
		return new  MyBinder();
	}
	
	/**
	 * 当调用UNBindService解绑定一个服务时,此方法被调用
	 * @param intent
	 * @return
	 */
	@Override
	public boolean onUnbind(Intent intent) {
		return super.onUnbind(intent);
	}
	
	
	/**
	 * 当服务被销毁时此方法被调用
	 */
	@Override
	public void onDestroy() {
		super.onDestroy();
	}
	
	private MediaPlayer player;
	
	class MyBinder extends Binder {
		/**
		 * 实现音乐播放的效果
		 */
		public void play(){
			if(player == null) {
				player = MediaPlayer.create(MusicService.this, R.raw.hitta);
				player.start();
			} else if(!player.isPlaying()) {
				player.start();
			}
		}
		
		/**
		 * 实现音乐暂停的效果
		 */
		public void pause() {
			if(player != null && player.isPlaying()) {
				player.pause();
			}
		}
		
		/**
		 * 实现音乐停止的效果
		 */
		public void stop(){
			if(player != null) {
				player.stop();
				player = null;
			}
		}
	}

}

(2)、bindService方法绑定服务,调用unbindService方法解绑服务

public class MainActivity extends Activity {
	
	private MyBinder mBinder;
	
	//声明并创建绑定服务的连接回调接口
	//此接口中包含了绑定服务时的回调函数
	private ServiceConnection conn = new ServiceConnection() {
		
		/**
		 * 当服务因异常被断开连接时调用此方法
		 * 参数是被绑定的服务组件名称
		 */
		@Override
		public void onServiceDisconnected(ComponentName name) {
		}
		
		/**
		 * 当绑定服务连接上,并且返回具体IBinder对象时此方法被调用
		 * 第一个参数 绑定服务的组件名称
		 * 第二个参数 在绑定服务的onBind方法返回的IBinder对象
		 */
		@Override
		public void onServiceConnected(ComponentName name, IBinder service) {
			Toast.makeText(MainActivity.this, "服务绑定成功", Toast.LENGTH_SHORT).show();
			//将Service的onBind方法中返回的IBinder对象保存
			//后续可以调用此Binder中的方法
			mBinder = (MyBinder) service;
		}
	};

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		
		/*
		 * 通过bindService绑定目标Service
		 * 绑定服务会跟Activity进行绑定,当Activity被销毁时,此Activity所绑定的服务也会被销毁
		 */
		// 1 创建Intent意图,并指定目标Service
		Intent intent = new Intent(this, MusicService.class);
		bindService(intent, conn, BIND_AUTO_CREATE);
	}

	public void btnClicked(View view) {
		//添加判断条件,判断服务之前时候绑定成功
		if(mBinder == null) {
			Toast.makeText(this, "服务没有被绑定", Toast.LENGTH_SHORT).show();
			return;
		}
		switch (view.getId()) {
		case R.id.play:
			mBinder.play();
			break;
		case R.id.pause:
			mBinder.pause();
			break;
		case R.id.stop:
			mBinder.stop();
			break;
		default:
			break;
		}
	}
}


猜你喜欢

转载自blog.csdn.net/fang410103/article/details/80102883