博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Android 2.2 API Demos -- Service
阅读量:4200 次
发布时间:2019-05-26

本文共 8245 字,大约阅读时间需要 27 分钟。

Service是在后台运行,不可交互的一个组件。它不是一个独立进程,也不是一个线程。它一般在所属的application进程的主线程中运行,除非特别指定。

下面结合示例分析Service的主要特征。
Service Lifecycle
当startService和bindService同时存在:

此外Service可以自己调用stopSelf()或者stopSelfResult()方法来终止自己。

只要还有context与Service绑定,就不能调用stopService来终止Service。
Start Service & Stop Service
参考官方示例,local Service controller:
1. 创建Service,可以暂时忽略onBind方法。
Java代码

public class LocalService extends Service {    private NotificationManager mNM;    /**     * 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(R.string.local_service_started);        // 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.        // We use a layout id because it is a unique number.  We use it later to cancel.        mNM.notify(R.string.local_service_started, notification);    }}

 2. 在Activity中通过startService和startService来启动和终止Service。关键代码如下:
Java代码

private OnClickListener mStartListener = new OnClickListener() {            public void onClick(View v) {                // Make sure the service is started.  It will continue running                // until someone calls stopService().  The Intent we use to find                // the service explicitly specifies our service component, because                // we want it running in our own process and don't want other                // applications to replace it.                startService(new Intent(Controller.this,                        LocalService.class));            }        };        private OnClickListener mStopListener = new OnClickListener() {            public void onClick(View v) {                // Cancel a previous call to startService().  Note that the                // service will not actually stop at this point if there are                // still bound clients.                stopService(new Intent(Controller.this,                        LocalService.class));            }        };

startService:启动Service,如果Service已经处于运行,那么就不会再次执行onCreate方法,直接执行onStartCommand方法。在Service的生命周期中,onCreate只会被执行一次。
stopService:终止Service。不管调用了多少次startService方法,只需要调用一次 stopService就可以终止Service。如果在调用stopService时仍然有context和此Service处于 binding(flag为BIND_AUTO_CREATE)状态,Service救不会被终止。
Binding & Unbinding
参考官方示例,Local service binding:
1. 创建service,重写onBind方法,返回IBinder类型实例。
Java代码

@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();

定义LocalBinder类,
Java代码

/**     * 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;        }    }

 

 之所以使用Binder将service实例传递给clients,是因为有可能跨进程调用,Binder里封装了RPC(remote procedure call)机制。你也可以实现自己的RPC协议。

 

2. 在Activity中通过bindService和unbindService来与service建立和解除连接。

Java代码

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;            }        }

bindService:与service建立连接,如果service未启动,首先启动service。然后回调service的onBind方法。连接成功后回调ServiceConnection的onServiceConnected方法。
unbindService:解除与service的连接,回调service的onUnbind方法。如果解除成功,没有其他context和此service处于binding状态,并且此service不是由startService来启动的(即没有 hosting process),那么就会回调Service的onDestroy方法。
ServiceConnection是负责监控Service的状态。如果连接成功,onServiceConnected会被执行;如果连接意外终止(假如通过RPC调用,Service所处的process终止),onServiceDisconnected会被执行。
Java代码

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();            }};

 

Foreground Service & Background Service

从Android 1.5开始,一个已启动的service可以调用startForeground(int, Notification)将service置为foreground状态,调用stopForeground(boolean)将service置为background状态。
我们会在调用startForeground(int, Notification)传入参数notification,它会在状态栏里显示正在进行的foreground service。background service不会在状态栏里显示。
在Android 1.0中,将一个service置为foreground状态:
Java代码

setForeground(true);mNM.notify(id, notification);

将一个service置为background状态:
Java代码

mNM.cancel(id);setForeground(false);

对比看出,在1.0 API中调用setForeground(boolean)只是简单的改变service的状态,用户不会有任何觉察。新API中强制将notification和改变service状态的动作绑定起来,foreground service会在状态栏显示,而background service不会。
Remote service controller & binding
跨进程调用Service。暂时不研究。

 

转载地址:http://qsfli.baihongyu.com/

你可能感兴趣的文章
面试题:强制类型转换
查看>>
Decorator模式
查看>>
Template模式
查看>>
Observer模式
查看>>
高性能服务器设计
查看>>
图文介绍openLDAP在windows上的安装配置
查看>>
Pentaho BI开源报表系统
查看>>
android中使用TextView来显示某个网址的内容,使用<ScrollView>来生成下拉列表框
查看>>
andorid里关于wifi的分析
查看>>
Spring MVC 教程,快速入门,深入分析
查看>>
Ubuntu Navicat for MySQL安装以及破解方案
查看>>
在C++中如何实现模板函数的外部调用
查看>>
HTML5学习之——HTML 5 应用程序缓存
查看>>
HTML5学习之——HTML 5 服务器发送事件
查看>>
hbase shell出现ERROR: org.apache.hadoop.hbase.ipc.ServerNotRunningYetException
查看>>
解决Rhythmbox乱码
查看>>
豆瓣爱问共享资料插件发布啦
查看>>
kermit的安装和配置
查看>>
linux中cat命令使用详解
查看>>
java中的异常机制
查看>>