`
zhenzxie
  • 浏览: 68331 次
  • 性别: Icon_minigender_1
  • 来自: 济南
社区版块
存档分类
最新评论

Android学习之路——7.Service

阅读更多
(一)注意的细节:
(1)Service不是一个单独的Process,除非特别指派了,也不是一个Thread,但也不是运行在Main Thread中。

(2)Service的使用有两个目的,一是告诉系统要后台执行程序,一般是用Context.startService()来开启Service的(注意即使开启Service的Activity什么的destroy了,Service还是存在的,直到Context.stopService()或stopSelf()的调用),二是向其他的类,进程提供功能,这个一般是Context.bindService()来开启Service。

(3)Service的生命周期:
调用的Context.startService()   oncreate() --> onStartCommand ()--> Service is running --> The service is stopped by its or a client--> onDestroy() --> Service is shut down 
调用Context.bindService()   onBind() -->  Service is running(clients are bound to it) --> All client unbind by calling unbindService() -->onUnbind() --> onDestroy()
在Service生命周期中要注意的有:
①不管调用几次Context.startService(),即使这样导致多次调用onStartCommand(),但是一旦调用了Context.stopService() 或者stopSelf() ,这个Service就会停止。
②onStartCommand()返回一个int值,在Service类里有定义,比如START_STICKY,START_NOT_STICKY,START_REDELIVER_INTENT。
③onBind()需要返回一个IBinder对象,以便Context和Service交互
④当Service因为系统内存低而被杀死后,系统会重启去启动它
⑤当一个有连接到Service的Context要销毁时,要调用unbindService(ServiceConnection)来断开连接

(4)当一个Service运行在前台时,必须为状态栏提供一个notification,并且这个notification一直存在直到这个Service停止或转移到后台。要让一个Service运行在前台,只要调用startForeground()方法,这个方法有两个参数,一个是唯一的标识,另一个是Notification,比如:

Notification notification = new Notification(R.drawable.icon, getText(R.string.ticker_text), System.currentTimeMillis());
Intent notificationIntent = new Intent(this, ExampleActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(this,0,notificationIntent,  0);
notification.setLatestEventInfo(this, getText(R.string.notification_title),getText(R.string.notification_message), pendingIntent);
startForeground(ONGOING_NOTIFICATION, notification);
(从前台移除只要调用stopForeground()方法,这个方法有一个boolean参数,表示是否移除notification。

(二)Service的使用:
(1)startService
如果只是简单的开启一个Service来完成一些工作,那只要使用Context.startService()来启动一个Service。继承Service,然后复写onCreate(),onStartCommand(Intent, int, int),onDestroy() 来实现一些自定义动作。实现起来很简单。

(2)bindService
这是一般的使用方法吧。
首先要在Service中实现一个Binder的子类,用来实现客服端对Service的调用,示例如下:

protected class BoundBinder extends Binder {

		/**
		 * 返回当前Service实例,将公有方法暴露给客户端,当然也可以是其他对象
		 * 
		 * @return Service实例
		 */
		BoundService getService() {

			return BoundService.this;
		}
}

然后在onBind()方法中返回一个Binder的实例。示例如下:
 /**
	 * @see android.app.Service#onBind(android.content.Intent)
	 */
	@Override
	public IBinder onBind(Intent intent) {

		Log.i(TAG, TAG + " onBind");
		return mBind;
	}

接着在客户端实现一个ServiceConnection的接口实现类,其中onServiceConnected(ComponentName, IBinder)是当客服端连接到Service时调用的回调方法,而onServiceDisconnected(ComponentName )是当断开连接时调用的。示例如下:
private class Connection1 implements ServiceConnection {

		@Override
		public void onServiceConnected(ComponentName name, IBinder service) {

			BoundBinder binder = (BoundBinder) service;
			boundService = binder.getService();//这个方法在BoundBinder类中实现
			mText.setText(boundService.getText());// BoundService暴露给客户端的方法
			stopService(boundIntent);// 停止服务
			unbindService(connection1);// 断开连接,记得加这句话
		}

		@Override
		public void onServiceDisconnected(ComponentName name) {

			Log.i(TAG, TAG + " Contact1 onServiceDisconnected");
		}
}

最后就是连接到这个Service了,示例如下:
 /**
	 * bind to a service
	 * 
	 * @param v
	 */
 public void bound(View v) {

		connection1 = new Connection1();
		boundIntent = new Intent(this, BoundService.class);
		bindService(boundIntent, connection1, BIND_AUTO_CREATE);
 }

(3)messengerService
当需要在不同的process中工作时,可以使用利用Messenger来和Service交互。
首先是在Service中实现一个Handler子类,用来出来从客服端发过来的Message,实现Handler的handleMessage(Message)方法来处理事务。使用这个Handler的实例来创建出一个Messenger对象,在onBind(Intent)中返回Messenger.getBinder()的结果。示例如下:

 /**
	 * 当客户端的Messenger发来Message则用这个Handler处理 这里简单的打印一句话。
	 * 然后通过Message绑定的Messenger对象再给客服端发送一个消息
	 */
	private Handler mHandler = new Handler() {

		/**
		 * @see android.os.Handler#handleMessage(android.os.Message)
		 */
		@Override
		public void handleMessage(Message msg) {

			Log.i(TAG, TAG + " Handler handlemessage");
			Messenger m = msg.replyTo;
			try {
				m.send(Message.obtain());
			} catch (RemoteException e) {
				e.printStackTrace();
			}
		}
	};
 private Messenger mMessenger = new Messenger(mHandler);
        /**
	 * @see android.app.Service#onBind(android.content.Intent)
	 */
	@Override
	public IBinder onBind(Intent intent) {

		Log.i(TAG, TAG + " onBind");
		return mMessenger.getBinder();
	}

接着是在客户端,和bundService一样也是实现一个ServiceConnection的接口实现类,实现两个接口回调方法,(和在bundService不太一样,主要是获得了一个Messenger对象,用它发送Message,同时实现一个Handler子类,处理来自Service的Message,并使用这个Handler创建一个Messenger对象,绑定到要发送给MessengerService的Message中。示例如下:
 private class Connection2 implements ServiceConnection {

		/**
		 * 向MessengerService发送一个Message,这个Message中含有当前类中的一个Messenger实例,方便MessengerService和这个类通信
		 * 
		 * @see android.content.ServiceConnection#onServiceConnected(android.content.ComponentName,android.os.IBinder)
		 */
		@Override
		public void onServiceConnected(ComponentName name, IBinder service) {

			messenger = new Messenger(service);
			Message message = Message.obtain();
			message.replyTo = mMessenger;// 将Message的replyTo绑定到客户端定义的Messenger,以便于MessengerService向客户端发送信息
			try {
				messenger.send(message);
			} catch (RemoteException e) {
				e.printStackTrace();
			}
		}

		@Override
		public void onServiceDisconnected(ComponentName name) {

			Log.i(TAG, TAG + " Contact2 onServiceDisconnected");
		}

	}
 private Handler mHandler = new Handler() {

		/**
		 * 处理从MessengerService返回的Message,提示服务,断开连接
		 * 
		 * @see android.os.Handler#handleMessage(android.os.Message)
		 */
		@Override
		public void handleMessage(Message msg) {

			Log.i(TAG, TAG + " Handler handleMessage");
			stopService(messengerIntent);
			unbindService(connection2);
		}

	};

	/**
	 * 用于MessengerService向Handler发送Message的Messenger
	 */
	private Messenger mMessenger = new Messenger(mHandler);

最后和boundService一样,使用bindService()来连接到Service。

(4)如果Service中需要使用多线程来处理事务,那么可以考虑继承IntentService类。这个类线程安全,而且使用很简单,实现onHandleIntent() 方法就可以了,如果自己实现例如onCreate(), onStartCommand(), onDestroy()这些方法时,记得调用父类里的相应方法。示例如下(来自:
android-sdk\docs\guide\topics\fundamentals\services.html):

public class HelloIntentService extends IntentService {

	/**
	 * A constructor is required, and must call the super IntentService(String)
	 * constructor with a name for the worker thread.
	 */
	public HelloIntentService() {

		super("HelloIntentService");
	}

	/**
	 * The IntentService calls this method from the default worker thread with
	 * the intent that started the service. When this method returns,
	 * IntentService stops the service, as appropriate.
	 */
	@Override
	protected void onHandleIntent(Intent intent) {

		// Normally we would do some work here, like download a file.
		// For our sample, we just sleep for 5 seconds.
		long endTime = System.currentTimeMillis() + 5 * 1000;
		while (System.currentTimeMillis() < endTime) {
			synchronized (this) {
				try {
					wait(endTime - System.currentTimeMillis());
				} catch (Exception e) {
				}
			}
		}
	}
}

(5)AIDL (Android Interface Definition Language) Service
对于AIDL的介绍参考:android-sdk/docs/guide/developing/tools/aidl.html
它能实现把复杂的对象分解成系统能理解的简单对象,然后系统通过他们来实现远程调用Messenger也是基于AIDL来做他的底层结构。顺便一提的是,Messenger创建了一个队列让所以的客户端请求都在同一个线程内,如果需要同时处理多个请求,就使用这种AIDL方法。都是大多数程序都不需要使用这种技术。

下面是Demo运行的截图。
程序的开始,丑陋


以此点击按钮后,注意有点小变化

在Logcat的输出~~~
  • 大小: 19.4 KB
  • 大小: 61.3 KB
2
0
分享到:
评论

相关推荐

    Android学习之路——4.Activity简介

    这篇博客"Android学习之路——4.Activity简介"很可能会详细解释Activity的基本概念、生命周期以及如何在实践中使用它。 Activity作为Android应用程序的一个窗口,它可以显示用户界面,并响应用户的交互。每个...

    Android学习之路——9.Creating an IME(译)

    这篇博客"Android学习之路——9.Creating an IME(译)"可能会探讨如何创建自定义的IME服务,以满足特定的应用场景需求。 首先,我们需要了解IME的基本结构。IME通常由以下组件组成: 1. `InputMethodService`:这...

    安卓Android源码——FloatWindowDemo.zip

    【标题】"安卓Android源码——FloatWindowDemo....总的来说,"安卓Android源码——FloatWindowDemo.zip" 是一个实用的学习资源,可以帮助开发者掌握Android浮动窗口的实现方法,增强其在Android应用开发中的实践能力。

    安卓Android源码——FBReader.zip

    【标题】"安卓Android源码——FBReader.zip" 指的是一个包含了开源电子书阅读器FBReader在Android平台上的源代码压缩包。FBReader是一款流行的电子书阅读应用,它支持多种格式,如EPUB、FB2、MOBI等,并且具有自定义...

    android系统入门了解——main.rar

    "main.rar"这个文件可能是一个包含了入门学习资料的压缩包,其中的核心内容可能包括Android的基本概念、开发环境搭建、UI设计以及程序调试等方面。 一、Android系统基础 1. **架构**:Android系统由Linux内核、系统...

    安卓Android源码——Intent.rar

    本资源“安卓Android源码——Intent.rar”可能包含了Intent的详细源代码分析,帮助开发者深入理解Intent的工作原理。 1. **Intent基础概念**: Intent在Android中扮演着“信使”的角色,它携带数据并指明一个操作...

    安卓Android源码——LedongliDemo.zip

    【标题】"安卓Android源码——LedongliDemo.zip" 提供的是一个Android应用程序的源代码,名为"LedongliDemo"。这个项目可能是由开发者Ledongli创建的一个示例应用,用于展示Android开发中的某些特定功能或技术。通过...

    安卓Android源码——GestureDemo.zip

    【标题】"安卓Android源码——GestureDemo.zip"是一个关于Android手势识别的示例项目,它可以帮助开发者理解和实现用户在Android设备上的各种手势操作。在这个项目中,开发者将学习到如何利用Android SDK中的...

    安卓Android源码——Freegemas.zip

    《安卓Android源码——Freegemas.zip》是一个与Android操作系统相关的源码压缩包,其中包含的是Freegemas项目的核心代码。这个项目可能是针对Android平台的一个定制应用或系统组件,其名称"Freegemas"可能是一个...

    安卓Android源码——KickKick.zip

    "安卓Android源码——KickKick.zip" 提供的可能是一个特定的项目或组件的源代码,它可以帮助我们深入学习Android系统的运行机制,以及应用程序如何与系统交互。下面我们将详细探讨Android源码的相关知识点。 1. **...

    安卓Android源码——BlogForZFB.zip

    【标题】"安卓Android源码——BlogForZFB.zip" 提供的是一个针对安卓平台的开发项目源代码,其中包含了构建和运行一个Android应用的基本结构和文件。这个项目可能是一个博客应用,专为支付宝(ZFB)用户设计,或者与...

    安卓Android源码——Music.rar

    通过详细分析和学习"安卓Android源码——Music.rar",开发者可以深入理解Android音乐播放器的内部工作原理,从而提高自己的编程技能,开发出更高质量的音乐应用。同时,这份源码也是实践和学习Android应用开发、服务...

    安卓Android源码——Circle.zip

    "安卓Android源码——Circle.zip"这个压缩包可能包含了一个与圆形UI元素或图形相关的项目,通过分析其源码,我们可以学习到Android系统中关于图形绘制、自定义View以及动画等方面的知识。 1. **自定义View**: 在...

    安卓Android源码——osChina.zip

    《安卓Android源码深度探索——osChina.zip剖析》 Android操作系统是全球最受欢迎的智能手机平台之一,它的开源特性吸引了无数开发者进行深入研究。本篇文章将基于"osChina.zip"这一压缩包,探讨Android的源码,...

    安卓Android源码——MyWorkText.zip

    总之,"安卓Android源码——MyWorkText.zip"为我们提供了一个研究Android源码的切入点,通过分析其中的代码,我们可以深入理解Android系统的工作机制,学习到如何优化应用性能,增强功能,以及提高应用的安全性。...

    安卓Android源码——Stk.rar

    这个“安卓Android源码——Stk.rar”压缩包可能包含的是Android系统中与STK相关的源代码,用于开发者深入理解STK的工作原理,以及如何在Android平台上实现STK应用。 STK主要由两部分组成:SIM卡上的应用和手机端的...

    安卓Android源码——testBaiduMap.zip

    【标题】"安卓Android源码——testBaiduMap.zip" 提供的是一个基于Android平台的示例项目,主要展示了如何在Android应用中集成并使用百度地图API。这个压缩包包含了开发过程中常用的各种文件,让我们来深入了解一下...

    Android应用案例开发大全——源码.rar

    "Android应用案例开发大全——源码.rar"提供了一套宝贵的实践项目,适合开发者深入理解Android应用的构建过程。这个压缩包包含了书后12个案例的完整源码,为初学者和有经验的开发者提供了丰富的学习材料。 首先,...

    安卓Android源码——TankWar.zip

    《安卓Android源码——TankWar....总的来说,分析和学习《安卓Android源码——TankWar.zip》不仅能帮助开发者掌握Android游戏开发的基本技能,还能深入理解Android应用的各个层面,对于提高Android开发能力大有裨益。

Global site tag (gtag.js) - Google Analytics