`

Android四大组件之Service

 
阅读更多

Android中的Service和windows中的服务是类似的东西,服务一般没有用户操作界面,它运行于系统中不容易被用户发觉,可以使用它开发如监控之类的程序。

概述:

1,Service是Android的四大组件之一

2,Service本质上是后台运行的可执行程序,它没有Activity那样的用户界面

3,Service不能与用户进行交互,不能自己启动、运行在后台,类似于线程的程序。

4,Service 在很多场合中应用:

  1)播放多媒体的时候用户启动了其他Activity,这个时候程序要在后台继续播放。

  2)检测SD卡上文件的变化

  3)在后台记录手机当前的地理信息位置的改变等等。

5,Service具有更高的进程优先级,在Android中进程有5个优先级别,Service位于第三个级别。

1). Foreground process  2).Visible process  3)Service process  4).Background process 5).Empty process

6,Service具有全局唯一性。同一时间系统内只能存在Service的一个实例。

7,Service必须要在AndroidManifest.xml注册才能使用,这一点与Activity相同。

8,Android提供了大量的系统的Service,Service也可以自定义。

 

服务的开发比较简单,常规步骤如下:

 

1,继承android.app.Service类

 public class SmsService extends Service{}

 

2,在AndroidManifest.xml文件中配置

 <service android:name=".MyService"/>

 

3,启动服务:服务不能自己运行,需要Context.startService()或者Context.bindService()方法启动服务。

 

下面我将详细介绍Service的几种用法:

#############################################################

eg1,最简单的Service用法,startService()启动服务,

调用者和服务之间没有联系,即使调用者退出了,服务依然在进行

 

自定义MyService.java,继承Service类。

 

public class MyService extends Service {
	private String tag = "MyService";

	@Override
	public IBinder onBind(Intent intent) {
		Log.i(tag, "MyService onBind()....");// 这里我用的是startService(),故这里返回值我设置为null,因为这里的代码不会被调用
		return null;
	}

	// 创建Service时执行,只会执行一次
	public void onCreate() {
		Log.i(tag, "MyService onCreate().....");
	}

	@Override
	public void onStart(Intent intent, int startId) {
		Log.i(tag, "MyService onStart().....");
		super.onStart(intent, startId);
	}

	@Override
	public int onStartCommand(Intent intent, int flags, int startId) {
		Log.i(tag, "MyService onStartCommand().....");
		return super.onStartCommand(intent, flags, startId);
	}

	@Override
	public void onDestroy() {
		Log.i(tag, "MyService onDestroy().....");
		super.onDestroy();
	}

	@Override
	public void onRebind(Intent intent) {
		Log.i(tag, "MyService onRebind().....");
	};

	@Override
	public boolean onUnbind(Intent intent) {
		Log.i(tag, "MyService onUnbind()");
		return super.onUnbind(intent);
	}
}

 

 

AndroidManifest.xml中注册广播: 

 

 <service android:name="com.example.service03.MyService" >
</service>

 

 

MainAction.java 核心代码

 

protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		try {
			start = (Button) findViewById(R.id.btn_start);
			stop = (Button) findViewById(R.id.btn_stop);
			// bindService(intent, mConn, BIND_AUTO_CREATE);
			start.setOnClickListener(new OnClickListener() {
				@Override
				public void onClick(View v) {
					try {
						Log.i("MainActivity", "点击了Button_Start ..");
						intent = new Intent(MainActivity.this, MyService.class);
						startService(intent);
					} catch (Exception e) {
						e.printStackTrace();
					}
				}
			});
			stop.setOnClickListener(new OnClickListener() {
				@Override
				public void onClick(View v) {
					stopService(intent);
					Log.i("MainActivity", "点击了Button_Stop ..");
				}
			});
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

 

 

结果:

 当点击按钮START 时,依次调用onCreate()---> onStartCommand()---->onStart();

再次点击按钮START时,调用   onStartCommand()---->onStart();

点击按钮STOP时,调用onDestory();

再次点击按钮START时,调用   onCreate()---->onStartCommand()---->onStart();

 

分析得出结论:

采用Context.startService()方法启动服务,只能调用Context.stopService()方法结束服务,服务结束时会调用onDestroy()方法。onCreate()方法只在第一次创建服务时执行,之后无论启动多少次服务都不会再执行。

 

补充:onStartCommand()和onStart()的区别。

1.onstartCommand其实就是onstart的代替,之前是用的onstart,新的api中用onstartCommand。onstartCommand中会回调onstart(),

 

2.onstartCommand有3个参数,onstart只有2个参数。

 

############################################################ 

Service的启动也可以这样设置(类似BroadcastReceiver中的隐式广播):

代码中:

//Constant.ACTION_MYSERVICE = "com.lydia.service.ACTION_MYSERVICE";
intent = new Intent(Constant.ACTION_MYSERVICE);
startService(intent);

 AndroidManifest.xml中

<service android:name=".MyService" >
        <intent-filter >
               <action android:name="com.lydia.service.ACTION_MYSERVICE"/>
        </intent-filter>
</service>

 

#############################################################

 

eg2,bindService(intent,conn,int)启动服务,

调用者和绑定者绑在一起,调用者一旦退出服务也就终止了。

 

 bindService()的方式去绑定服务会调用public IBinder onBind(Intent intent){},会返回一个IBinder对象,我们需要Ibinder对象返回具体的Service对象才能操作,所以获取的必定是实现了Binder的对象,所以这是我们必须使用Binder的方式去获取Service的方式而不是直接使用。

 

具体代码步骤如下:

1,自定义MyService.java,继承Service类,并且Service中要创建IBinder对象。

 

public class MyService extends Service {
	private String tag = "MyService";
	MyBinder mBinder; 

	public class MyBinder extends Binder {
		public void print(String text) {
			MyService.this.print(text);
		}
	}

	// 自定义方法
	private void print(String text) {
		Log.i(tag, text);
	}

	@Override
	public IBinder onBind(Intent intent) {
		Log.i(tag, "MyService onBind()");
		return new MyBinder(); //因为是bindService()方式启动,这里需要返回一个Ibinder对象来操作
	}

	@Override
	public void onRebind(Intent intent) {
		Log.i(tag, "MyService onRebind()");
		super.onRebind(intent);
	}

	// 服务创建时调用
	@Override
	public void onCreate() {
		Log.i(tag, "MyService onCreate()");
		mBinder = new MyBinder();
		super.onCreate();
	}
	// 服务
	@Override
	public void onStart(Intent intent, int startId) {
		Log.i(tag, "MyService onStart()");
		super.onStart(intent, startId);
	}

	//服务启动时调用,在onCreate()方法之后
	@Override
	public int onStartCommand(Intent intent, int flags, int startId) {
		Log.i(tag, "MyService onStartCommand()");
		return super.onStartCommand(intent, flags, startId);
	}
	//解除绑定
	@Override
	public boolean onUnbind(Intent intent) {
		Log.i(tag, "MyService onUnbind()");
		return super.onUnbind(intent);
	}
}
 

 

MainActivity.java

 

public class MainActivity extends Activity {
	Button start, stop;
	Intent intent;
	MyBinder mBinder;
	private ServiceConnection mConn = new ServiceConnection() {
		@Override
		public void onServiceDisconnected(ComponentName name) {
		}
		@Override
		// 绑定成功时触发本方法
		public void onServiceConnected(ComponentName name, IBinder service) {
			// 获得MyService.onBind()方法返回的对象(service)
			mBinder = (MyService.MyBinder) service;
		}
	};

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		try {
			start = (Button) findViewById(R.id.btn_start);
			stop = (Button) findViewById(R.id.btn_stop);
			start.setOnClickListener(new OnClickListener() {
				@Override
				public void onClick(View v) {
					try {
						Log.i("MainActivity", "点击了Button_Start ..");
						intent = new Intent(MainActivity.this, MyService.class);
						bindService(intent, mConn, BIND_AUTO_CREATE);
						mBinder.print("------------绑定服务-----------");
					} catch (Exception e) {
						e.printStackTrace();
					}
				}
			});
			stop.setOnClickListener(new OnClickListener() {
				@Override
				public void onClick(View v) {
					Log.i("MainActivity", "点击了Button_Stop ..");
//					stopService(intent);
					unbindService(mConn);
					mBinder.print("------------解除绑定-----------");
				}
			});
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}
    AndroidManifet.xml中配置和案例eg1中一样。

结果:

 当点击按钮START 时,依次调用onCreate()---> onBind()

再次点击按钮START时,不会调用onCreate()、onBind()和其他方法。

点击按钮STOP时,依次调用 onUnbind() ---->onDestroy();

再次点击按钮START时,调用  onCreate()---> onBind()

 

分析得出结论:

采用Context.bindService()方法启动服务,只能调用Context.unbindService(mConn);方法结束服务。

 

注意:关于onServiceDisconneted()方法的调用

1、当Activity与Service绑定时,若出现进程崩溃,则onServiceDisconnected()被触发。

2、当进程被终止时,将触发onServiceDisconnected()方法。

3、onServiceDisconnected方法由Android系统调用,不要程序触发,不要再此方法中编写业务逻辑代码。

#######################################

常见问题:

1,再次解绑定异常

 原因:未绑定服务,不能解绑定

 解决:增加标志位,当绑定后把标志位设置为true

            解绑定判断,如果为true,则执行解绑定,并把标志设置为false

 

2,第一次绑定异常

  原因:onServiceConnection对象不是一个

  解决:bindService(intent,conn,Context.BIND_AUTO_CREATE);

             unbindService(conn);

             这两个方法的conn参数要是同一个对象实例,conn这个对象要在类中声明为成员变量。

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics