标签:
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() andContext.bindService(). Note that services, like other application objects, run in the main thread of their hosting process. This means that, if your service is going to do any CPU intensive (such as MP3 playback) or blocking (such as networking) operations, it should spawn its own thread in which to do that work. More information on this can be found in Processes and Threads. The IntentService class is available as a standard implementation of Service that has its own thread where it schedules its work to be done.
? A Service is not a separate process. The Service object itself does not imply it is running in its own process; unless otherwise specified, it runs in the same process as the application it is part of. ? A Service is not a thread. It is not a means itself to do work off of the main thread (to avoid Application Not Responding errors).Service不是一个分隔独立的进程
public class LocalService extends Service { private NotificationManager mNM; // Unique Identification Number for the Notification. // We use it on Notification start, and to cancel it. private int NOTIFICATION = R.string.local_service_started; /** * Class for clients to access. Because we know this service always * runs in the same process as its clients, we don't need to deal with * IPC. */ public class LocalBinder extends Binder { LocalService getService() { return LocalService.this; } } @Override public void onCreate() { mNM = (NotificationManager)getSystemService(NOTIFICATION_SERVICE); // Display a notification about us starting. We put an icon in the status bar. showNotification(); } @Override public int onStartCommand(Intent intent, int flags, int startId) { Log.i("LocalService", "Received start id " + startId + ": " + intent); // We want this service to continue running until it is explicitly // stopped, so return sticky. return START_STICKY; } @Override public void onDestroy() { // Cancel the persistent notification. mNM.cancel(NOTIFICATION); // Tell the user we stopped. Toast.makeText(this, R.string.local_service_stopped, Toast.LENGTH_SHORT).show(); } @Override public IBinder onBind(Intent intent) { return mBinder; } // This is the object that receives interactions from clients. See // RemoteService for a more complete example. private final IBinder mBinder = new LocalBinder(); /** * Show a notification while this service is running. */ private void showNotification() { // In this sample, we'll use the same text for the ticker and the expanded notification CharSequence text = getText(R.string.local_service_started); // Set the icon, scrolling text and timestamp Notification notification = new Notification(R.drawable.stat_sample, text, System.currentTimeMillis()); // The PendingIntent to launch our activity if the user selects this notification PendingIntent contentIntent = PendingIntent.getActivity(this, 0, new Intent(this, LocalServiceActivities.Controller.class), 0); // Set the info for the views that show in the notification panel. notification.setLatestEventInfo(this, getText(R.string.local_service_label), text, contentIntent); // Send the notification. mNM.notify(NOTIFICATION, notification); } }
private LocalService mBoundService; private ServiceConnection mConnection = new ServiceConnection() { public void onServiceConnected(ComponentName className, IBinder service) { // This is called when the connection with the service has been // established, giving us the service object we can use to // interact with the service. Because we have bound to a explicit // service that we know is running in our own process, we can // cast its IBinder to a concrete class and directly access it. mBoundService = ((LocalService.LocalBinder)service).getService(); // Tell the user about this for our demo. Toast.makeText(Binding.this, R.string.local_service_connected, Toast.LENGTH_SHORT).show(); } public void onServiceDisconnected(ComponentName className) { // This is called when the connection with the service has been // unexpectedly disconnected -- that is, its process crashed. // Because it is running in our same process, we should never // see this happen. mBoundService = null; Toast.makeText(Binding.this, R.string.local_service_disconnected, Toast.LENGTH_SHORT).show(); } }; void doBindService() { // Establish a connection with the service. We use an explicit // class name because we want a specific service implementation that // we know will be running in our own process (and thus won't be // supporting component replacement by other applications). bindService(new Intent(Binding.this, LocalService.class), mConnection, Context.BIND_AUTO_CREATE); mIsBound = true; } void doUnbindService() { if (mIsBound) { // Detach our existing connection. unbindService(mConnection); mIsBound = false; } } @Override protected void onDestroy() { super.onDestroy(); doUnbindService(); }
Disconnect from an application service. You will no longer receive calls as the service is restarted, and the service is now allowed to stop at any time.断开应用服务连接,你不会再收到service重启的消息(回调),这个service也可以在任意时间被系统终止了。
package com.example.testservice; 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.util.Log; import android.view.View; import android.view.View.OnClickListener; public class MainActivity extends Activity { private final static String TAG = "MainActivity"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Log.d(TAG, "onCreate"); doBindService(); findViewById(R.id.button).setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { // TODO Auto-generated method stub startActivity(new Intent(MainActivity.this,SecondActivity.class)); } }); } private LocalService mBoundService; private ServiceConnection mConnection = new ServiceConnection() { public void onServiceConnected(ComponentName className, IBinder service) { mBoundService = ((LocalService.LocalBinder)service).getService(); // Tell the user about this for our demo. Log.d(TAG, "service bind"); } public void onServiceDisconnected(ComponentName className) { // This is called when the connection with the service has been // unexpectedly disconnected -- that is, its process crashed. // Because it is running in our same process, we should never // see this happen. mBoundService = null; Log.d(TAG, "service unbind"); } }; void doBindService() { // Establish a connection with the service. We use an explicit // class name because we want a specific service implementation that // we know will be running in our own process (and thus won't be // supporting component replacement by other applications). Log.d(TAG, "do service bind"); bindService(new Intent(this, LocalService.class), mConnection, Context.BIND_AUTO_CREATE); mIsBound = true; } private boolean mIsBound = false; void doUnbindService() { if (mIsBound) { // Detach our existing connection. Log.d(TAG, "do service unbind"); unbindService(mConnection); mIsBound = false; } else { Log.d(TAG, "no necessary to unbind,it is not binding"); } } @Override protected void onDestroy() { Log.d(TAG, "onDestroy"); super.onDestroy(); doUnbindService(); } }
package com.example.testservice; 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.util.Log; public class SecondActivity extends Activity { private final static String TAG = "SecondActivity"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_second); doBindService(); } private LocalService mBoundService; private ServiceConnection mConnection = new ServiceConnection() { public void onServiceConnected(ComponentName className, IBinder service) { mBoundService = ((LocalService.LocalBinder)service).getService(); // Tell the user about this for our demo. Log.d(TAG, "service bind"); } public void onServiceDisconnected(ComponentName className) { // This is called when the connection with the service has been // unexpectedly disconnected -- that is, its process crashed. // Because it is running in our same process, we should never // see this happen. mBoundService = null; Log.d(TAG, "service unbind"); } }; void doBindService() { // Establish a connection with the service. We use an explicit // class name because we want a specific service implementation that // we know will be running in our own process (and thus won't be // supporting component replacement by other applications). Log.d(TAG, "do service bind"); bindService(new Intent(this, LocalService.class), mConnection, Context.BIND_AUTO_CREATE); mIsBound = true; } private boolean mIsBound = false; void doUnbindService() { if (mIsBound) { // Detach our existing connection. Log.d(TAG, "do service unbind"); unbindService(mConnection); mIsBound = false; } else { Log.d(TAG, "no necessary to unbind,it is not binding"); } } @Override protected void onDestroy() { Log.d(TAG, "onDestroy"); super.onDestroy(); doUnbindService(); } }
package com.example.testservice; import android.app.Service; import android.content.Intent; import android.os.Binder; import android.os.IBinder; import android.util.Log; /** * @ClassName: LocalService * @Description: TODO * @date 2016年4月27日 下午3:43:57 * * @author leobert.lan * @version 1.0 */ public class LocalService extends Service { private final static String TAG = "LocalService"; /** * Class for clients to access. Because we know this service always * runs in the same process as its clients, we don't need to deal with * IPC. */ public class LocalBinder extends Binder { LocalService getService() { return LocalService.this; } } @Override public void onCreate() { Log.i(TAG, "service onCreate"); } @Override public int onStartCommand(Intent intent, int flags, int startId) { Log.i(TAG, "Received start id " + startId + ": " + intent); // We want this service to continue running until it is explicitly // stopped, so return sticky. return START_STICKY; } @Override public void onDestroy() { Log.i(TAG, "service destroy"); super.onDestroy(); } @Override public IBinder onBind(Intent intent) { Log.i(TAG, "service onBind"); return mBinder; } // This is the object that receives interactions from clients. See // RemoteService for a more complete example. private final IBinder mBinder = new LocalBinder(); }我截取了一下logcat,但是eclipse的背景。。。
// This is called when the connection with the service has been // established, giving us the service object we can use to // interact with the service. Because we have bound to a explicit // service that we know is running in our own process, we can // cast its IBinder to a concrete class and directly access it.bindService可以获得service对象,并且和它进行交互(说白了就是想调用他的方法)。
IntentService is a base class for Services that handle asynchronous requests (expressed as Intents) on demand. Clients send requests through startService(Intent) calls; the service is started as needed, handles each Intent in turn using a worker thread, and stops itself when it runs out of work. This "work queue processor" pattern is commonly used to offload tasks from an application's main thread. The IntentService class exists to simplify this pattern and take care of the mechanics. To use it, extend IntentService and implement onHandleIntent(Intent). IntentService will receive the Intents, launch a worker thread, and stop the service as appropriate. All requests are handled on a single worker thread -- they may take as long as necessary (and will not block the application's main loop), but only one request will be processed at a time.IntentService是service的子类,设计用来处理异步请求,通过startService函数的调用来发送请求,吧啦吧啦一堆。
This method is invoked on the worker thread with a request to process. Only one Intent is processed at a time, but the processing happens on a worker thread that runs independently from other application logic. So, if this code takes a long time, it will hold up other requests to the same IntentService, but it will not hold up anything else. When all requests have been handled, the IntentService stops itself, so you should not call stopSelf().Intent是有序到达、处理的,先来的先处理,耗时的话后面的等着,不会阻塞主线程之类的,干完活自己干死自己,所以你不要调用stopSelf().
[Android 基础系列]Service、IntentService和习以为常的误解
标签:
原文地址:http://blog.csdn.net/a774057695/article/details/51260991