android有四大组件,Activity,Broadcast Receiver,Service,Content Providers;
今天我先介绍下Service,Service功能和Activity类似(这个会在后续的文章中详细说明),Service可以说是一个没有试视图的Activity,就是隐藏的activity。
下面是官网给出的:
A Service is an application component representing either an application's desire to perform a longer-running operation while not interacting with the user or to supply functionality for other applications to use. Each service class must have a corresponding <service> declaration in its package's AndroidManifest.xml. Services can be started with Context.startService() and Context.bindService().
Note that services, like other application objects,A service runs in the main thread of its hosting process—the service does not create its own thread and does not run in a separate process (unless you specify otherwise). This means that, if your service is going to do any CPU intensive (such as MP3 playback) or blocking (such as MP3 playback or networking) operations, you should create a new thread within the service to do that work. By using a separate thread, you will reduce the risk of Application Not Responding (ANR) errors and the application's main thread can remain dedicated to user interaction with your activities.
(大概的意思:作为组建之一的Service,他代表是一个应用需要一个比较长时间的操作且用户不交互,或者给另外一个应用使用。而每个service都需要在AndroidManifest.xml中注册。service通过 Context.startService()和 Context.bindService()启动。
注意事项:
Service是在主线程中的自己 hosting process中运行,没有创建自己的线程而且没有在另外的进程中(除非自己指定一个)。这就意味着,如果service做与cpu交互频繁(CPU高负荷的操作)或者阻塞的操作,这是就需要在新建一个自己的线程来做这些工作。IntentService继承于service,拥有自己的线程,在线程处理想要的事情。)
)
下面会介绍下关于service的内容:
service的生命周期;
Lcoal Service;
Remote Service;
先介绍生命周期(LifeCircile)
系统有两种启动Service的方法。如果调用Context.startService(),那么系统将会得到这个Service(如果必要则创建它并调用它的onCreate()方法),然后使用客户端传递的参数调用它的onStartCommand(Intent,int)方法。Service开始运行直到Context.stopService()或者stopSelf()方法被调用。注意,多次调用Context.startservice()不会嵌套(即oncreate只会被调用一次(service只会被创建一次,如果已经创建则不创建)这时会有相应的onStart()方法被调用),所以无论同一个服务被启动了多少次,一旦调用Context.stopService()或者stopSelf(),他都会被停止。
客户端也可以使用context.bindservice()来得到一个Service的永久链接。这个方法也会在服务没有运行的条件下创建服务(调用onCreate()),但是不调用onStart()。客户端会得到服务的onBind(Intent)方法返回的IBinder对象,用来允许客户端回调服务的方法。只要连接已经建立服务会一直运行下去(无论客户端是否保留服务的IBinder对象的引用)。通常返回的IBinder对象是AIDL中定义的复杂接口。
service还可以在启动的情况下绑定,或者绑定的情况下启动;
简单总结下:
1.通过startservice启动,onCreate->onStartCommand->onStart,(如果service已经创建过了,则就不会在调用onCreate);
2.通过调用onDestroy->stopService,停止service;(调用者自己直接退出,没有调用stopService,那么service一直会在后台运行)
3.通过bindservice启动,只调用onCreate,这个时候会绑定serviceDemo和service;
4.通过调用调用onUnbind->onDestroy,如果与activity绑定,则与activity共存亡;
5 . 混合启动:
/**
* 1.无论绑定和创建service,service只会被创建一次(就是oncreate只会被调用一次)
* 2.如果已经start,则可以bind
* 3.如果已经bind,则可以start
* 4.如果已经start,且bind,则不能使用stopservice,只能用unbind,然后在调用onstop(这个不会调用)
* 5.如果已经bind,且start,则stopservice不起作用,只能用unbind,然后在调用onstop(这个不会调用)
*/
6.启动service,根据onStartCommand的返回值不同,有两个附加的模式:
这是本地service启动和绑定
上代码:
PotatoService.java
package com.potato; import java.io.FileDescriptor; import java.io.PrintWriter; import android.app.Notification; import android.app.NotificationManager; import android.app.PendingIntent; import android.app.Service; import android.content.Context; import android.content.Intent; import android.content.res.Configuration; import android.os.Binder; import android.os.IBinder; import android.util.Log; public class PotatoService extends Service { private final static String TAG = "PotatoService"; private NotificationManager mNotificationManger; // This is the object that receives interactions from clients. See // RemoteService for a more complete example. private final IBinder mBinder = new LocalBinder(); @Override public IBinder onBind(Intent arg0) { // TODO Auto-generated method stub Log.d(TAG, "onBind"); return mBinder; } @Override protected void dump(FileDescriptor fd, PrintWriter writer, String[] args) { // TODO Auto-generated method stub super.dump(fd, writer, args); } @Override protected void finalize() throws Throwable { // TODO Auto-generated method stub super.finalize(); } @Override public void onConfigurationChanged(Configuration newConfig) { // TODO Auto-generated method stub super.onConfigurationChanged(newConfig); } @Override public void onCreate() { // TODO Auto-generated method stub super.onCreate(); Log.d(TAG, "onCreate"); mNotificationManger = (NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE); showNotification(); } @Override public void onDestroy() { // TODO Auto-generated method stub super.onDestroy(); Log.d(TAG, "onDestroy"); mNotificationManger.cancel(notification_id); } @Override public void onLowMemory() { // TODO Auto-generated method stub super.onLowMemory(); Log.d(TAG, "onLowMemory"); } @Override public void onRebind(Intent intent) { // TODO Auto-generated method stub super.onRebind(intent); Log.d(TAG, "onRebind"); } @Override public void onStart(Intent intent, int startId) { // TODO Auto-generated method stub super.onStart(intent, startId); Log.d(TAG, "onStart"); } @Override public int onStartCommand(Intent intent, int flags, int startId) { // TODO Auto-generated method stub Log.d(TAG, "onStartCommand"); String data = ""; data = intent.getExtras().getString("pass_data_to_service"); Log.d(TAG, data); return super.onStartCommand(intent, flags, startId); } @Override public boolean onUnbind(Intent intent) { // TODO Auto-generated method stub Log.d(TAG, "onUnbind"); return super.onUnbind(intent); } // 调用者(serviceDemo)得到service并操作它 public class LocalBinder extends Binder { PotatoService getService() { return PotatoService.this; } } int notification_id = 119527; public void showNotification() { Notification notification = new Notification(R.drawable.ic_launcher, "PotatoService Started", System.currentTimeMillis()); PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, new Intent(this, ServiceDemoActivity.class), 0); notification.setLatestEventInfo(this, "Potato Service", "Service Start", pendingIntent); mNotificationManger.notify(notification_id, notification); } }
ServiceDemoActivity.java
package com.potato; import android.app.Activity; import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.ServiceConnection; import android.os.Bundle; import android.os.IBinder; import android.view.View; import android.widget.Button; /** * * @author Justin * 1. service 其实就是一个不显示的activity(不能看到的activity) * * 2. 如果在service的oncreate和onstart中执行比较费时的操作时,最好起一个新线程来运行service * (因为service是在主线程里运行,否则阻塞ui操作或者主线程里的其他事情) * */ public class ServiceDemoActivity extends Activity { /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); init(); } PotatoService mPotatoService; boolean mIsAutoBind = false; /** * 把activity和service绑定,共同生存 */ private ServiceConnection mServiceConnection = new ServiceConnection() { @Override public void onServiceConnected(ComponentName name, IBinder service) { // TODO Auto-generated method stub mPotatoService = ((PotatoService.LocalBinder)service).getService(); } @Override public void onServiceDisconnected(ComponentName name) { // TODO Auto-generated method stub mPotatoService = null; } }; void init() { Button btnStartService = (Button)findViewById(R.id.btn_start_service); btnStartService.setOnClickListener(new View.OnClickListener(){ @Override public void onClick(View arg0) { // TODO Auto-generated method stub startService(); } }); Button btnStopService = (Button)findViewById(R.id.btn_stop_service); btnStopService.setOnClickListener(new View.OnClickListener(){ @Override public void onClick(View arg0) { // TODO Auto-generated method stub stopService(); } }); Button btnBindService = (Button)findViewById(R.id.btn_bind_service); btnBindService.setOnClickListener(new View.OnClickListener(){ @Override public void onClick(View arg0) { // TODO Auto-generated method stub bindService(); } }); Button btnUnbindService = (Button)findViewById(R.id.btn_unbind_service); btnUnbindService.setOnClickListener(new View.OnClickListener(){ @Override public void onClick(View arg0) { // TODO Auto-generated method stub unbindService(); } }); } /** * onCreate->onStartCommand->onStart */ private void startService() { Intent intent = new Intent(this, PotatoService.class); intent.putExtra("pass_data_to_service", "do you receive?"); startService(intent); } /** * 调用者自己直接退出,没有调用stopService,那么service一直会在后台运行,onDestroy */ private void stopService() { Intent intent = new Intent(this, PotatoService.class); stopService(intent); } /** * 只调用onCreate,这个时候会绑定serviceDemo和service */ private void bindService() { Intent intent = new Intent(this, PotatoService.class); bindService(intent, mServiceConnection, Context.BIND_AUTO_CREATE); mIsAutoBind = true; } /** * 如果serviceDemo退出,那么service会调用onUnbind->onDestroy,共存亡 */ private void unbindService() { if (mIsAutoBind) { unbindService(mServiceConnection); mIsAutoBind = false; } } /** * 1.无论绑定和创建service,service只会被创建一次(就是oncreate只会被调用一次) * 2.如果已经start,则可以bind * 3.如果已经bind,则可以start * 4.如果已经start,且bind,则不能使用stopservice,只能用unbind,然后在调用onstop(这个不会调用) * 5.如果已经bind,且start,则stopservice不起作用,只能用unbind,然后在调用onstop(这个不会调用) */ }
<service android:enabled="true" android:name=".PotatoService"></service>
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical" > <Button android:id="@+id/btn_start_service" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="start_service" /> <Button android:id="@+id/btn_stop_service" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="stop_service" /> <Button android:id="@+id/btn_bind_service" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="bind_service" /> <Button android:id="@+id/btn_unbind_service" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="unbind_service" /> </LinearLayout>
By implementing these methods, you can monitor two nested loops of the service's lifecycle:
The entire lifetime of a service happens between the time onCreate() is called and the time onDestroy() returns. Like an activity, a service does its initial setup in onCreate() and releases all remaining resources in onDestroy(). For example, a music playback service could create the thread where the music will be played in onCreate(), then stop the thread in onDestroy().
The onCreate() and onDestroy() methods are called for all services, whether they're created by startService() or bindService().
The active lifetime of a service begins with a call to either onStartCommand() or onBind(). Each method is handed the Intent that was passed to either startService() or bindService(), respectively.
If the service is started, the active lifetime ends the same time that the entire lifetime ends (the service is still active even after onStartCommand() returns). If the service is bound, the active lifetime ends when onUnbind() returns.If the service is started, the active lifetime ends the same time that the entire lifetime ends (the service is still active even after onStartCommand() returns). If the service is bound, the active lifetime ends when onUnbind() returns.
Note: Although a started service is stopped by a call to either stopSelf() or stopService(), there is not a respective callback for the service (there's no onStop() callback). So, unless the service is bound to a client, the system destroys it when the service is stopped—onDestroy() is the only callback received.
Figure 2 illustrates the typical callback methods for a service. Although the figure separates services that are created by startService() from those created by bindService(), keep in mind that any service, no matter how it's started, can potentially allow clients to bind to it. So, a service that was initially started with onStartCommand() (by a client calling startService()) can still receive a call to onBind() (when a client calls bindService()).
2012/5/30 Modify
注:
1.Service是在主线程中的自己 hosting process中运行,没有创建自己的线程而且没有在另外的进程中(除非自己指定一个)。
2.这就意味着,如果service做与cpu交互频繁(CPU高负荷的操作)或者阻塞的操作,
3.这是就需要在新建一个自己的线程来做这些工作。IntentService继承于service,拥有自己的线程,在线程处理想要的事情。
有问题请留言
或者发邮件[email protected]
源码下载地址:
http://download.csdn.net/detail/alex0203/3834762