android学习笔记service介绍

来源:互联网 发布:java excel合并行 编辑:程序博客网 时间:2024/05/21 10:01

    半个多月没写总结了,这段时间感觉学了不少东西,但是想总结一下却发现什么也没有。学习过程中没有目的性,见什么看什么,思来想去自己太浮躁,太心急。汇过来梳理一下发现还是有所补救。

    android的SDK相关文档很重要,刚开始确实不知从何看起,也不觉得有多重要,最多就是出现没见过的类了,翻出来看看,但是了解了SDK文档的结构后就知道文档的重要性了。

1.service是什么

    service是android的应用程序的四大组件之一,service是应用程序的一部分不与用户交互的后台操作的集合,同时也可以作为其他程序的被调用者来提供服务。它不是一个进程,它只是运行在主线程的一部分操作的集合。在activity,broadcast receiver,content provider之中,activity与service有最为相似,activity应该是学习android的过程中接触最多的部件,同样的,用户能够直观感受的就是activity,虽然在像播放音乐的时候service的参与能体会到,但是activity是最直接的,它承担着与用户交互的前台工作。而service则是后台数据处理。为什么和activity相似,个人理解在于,service和activity都是在主线程的运行的,从android的单线程安全的角度考虑,在service里面是可以进行UI操作的,同时这也意味这在service里面进行耗时的、耗资源的操作是不可取的。

    说了那么多,就是:service可以作为程序的一个内部部件调用,也可以被其他应用程序调用;service是存在于主线程中的一部分操作的集合,可以进行UI操作,这也意味着不适合耗时的操作,以免阻塞主线程造成不好的用户体验。

2.service的调用方法

    service和activity一样可以显示调用,也可以隐式调用。

    1)显示调用只需要在intent中注明调用的service的class即可:(SDK中摘录的源代码)

Intent intent = new Intent(this, HelloService.class);startService(intent);
  2)  隐式调用,则是通过匹配响应的Intent-filter来完成:

Intent intent = new Intent();intent.setAction(“我的服务的动作名称”);..//设置相应的intentfilter匹配属性.startService(intent);
    service的启动方式也有两种,startService()和bindService();上面说的显示和隐式调用都能通过startService()启动,至于能否通过bindService()启动,可以通过实验验证一下。

    1)startService()方式启动service:

    startService()方式只需要给一个Intent对象参数即可,此种方式启动的service会在后台一直运行,即使启动service的部件被销毁了,service依旧运行,直到service自身调用stopSelf()方法或者程序调用stopService()方法。通过startService()方式启动的service不能与其他应用程序进行通信,如果需要与应用程序通信,就需要通过bindService()方法启动,当然PendingIntent也可以做到与其他应用程序的沟通,详细看SDK文档。如果service是第一次调用,则会运行onCreate()函数,然后运行onStartCommand()函数,之后的每次启动只会调用onStartCommand()方法,也就是service本身存在的情况下,只调用onStartCommand()。前面已经说过service的销毁方法,值得注意的是stopSelfResult(int)形式的函数是匹配最近处理的intentId的情况下才会执行的函数。

    2)bindService()方式启动service:

    bindService较为复杂,不过其使用方式网上都有介绍,主要是理解connection中的IBinder和service中的Ibinder是同一个对象,绑定者和service通过这个binder进行通信。这个binder分别存在于connection的onServiceConnected()中和service的onBinder()中。第一次调用bindService()会执行onCreate()方法,然后是执行onBinder()方法,此时没有执行onStartCommand()方法。service会在绑定着销毁时,撤出绑定从而终止自身的生命周期,多个不同的应用程序可以同时绑定一个service,当service不在被绑定时,将销毁。

    绑定时的应用程序通信,service会通过IBinder来完成,例如activity对象A和service对象S进行通信,则在S中定义一个内部Binder类B,用于封装一部分数据和操作,S在onBinder()方法中实现对B的初始化等相关操作,然后ruturn B。此时是调用bindService()方法后执行的onBinder()方法完成的操作。在对象A中,生成一个ServiceConnection对象SC,此时SC里面的onServiceConnected()有一个IBinder参数service,这个参数即为绑定的对象S的IBinder对象B。代码形式如下(SDK摘录):

Service对象:

public class LocalService extends Service {    // Binder given to clients    private final IBinder mBinder = new LocalBinder();    // Random number generator    private final Random mGenerator = new Random();    /**     * Class used for the client Binder.  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 this instance of LocalService so clients can call public methods            return LocalService.this;        }    }    @Override    public IBinder onBind(Intent intent) {        return mBinder;    }    /** method for clients */    public int getRandomNumber() {      return mGenerator.nextInt(100);    }}
Activity对象:

public class BindingActivity extends Activity {    LocalService mService;    boolean mBound = false;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.main);    }    @Override    protected void onStart() {        super.onStart();        // Bind to LocalService        Intent intent = new Intent(this, LocalService.class);        bindService(intent, mConnection, Context.BIND_AUTO_CREATE);    }    @Override    protected void onStop() {        super.onStop();        // Unbind from the service        if (mBound) {            unbindService(mConnection);            mBound = false;        }    }    /** Called when a button is clicked (the button in the layout file attaches to      * this method with the android:onClick attribute) */    public void onButtonClick(View v) {        if (mBound) {            // Call a method from the LocalService.            // However, if this call were something that might hang, then this request should            // occur in a separate thread to avoid slowing down the activity performance.            int num = mService.getRandomNumber();            Toast.makeText(this, "number: " + num, Toast.LENGTH_SHORT).show();        }    }    /** Defines callbacks for service binding, passed to bindService() */    private ServiceConnection mConnection = new ServiceConnection() {        @Override        public void onServiceConnected(ComponentName className,                IBinder service) {            // We've bound to LocalService, cast the IBinder and get LocalService instance            LocalBinder binder = (LocalBinder) service;            mService = binder.getService();            mBound = true;        }        @Override        public void onServiceDisconnected(ComponentName arg0) {            mBound = false;        }    };}

3.Service生成子线程:

    service本身不能实现耗时操作,所以需要生成子线程来完成耗时操作,SDK提供了两种方式,一种是提供IntentService类来封装子线程的实现;一种是使用handle。  

    关于IntentService:1)会生成一个工作子进程,用于处理发送过来的intent。

                                       2)创建一个工作队列,用于管理众多的intent对象,避免同时处理多个intent的发生。

                                       3)提供默认的onBinder()接口,这就能实现绑定形式的进程通信。

                                       4)当所有请求处理完后,将自行销毁service。

    在IntentService中有接口函数onHandleIntent(),所有发送过来的intent都将会通过此函数生成子线程完成处理,用户只需要在该函数中实现自身定义的操作即可。可以看出IntentService是不能对UI进行操作,UI的单线程安全会组织其它线程的UI操作。

    handle机制是通信机制,虽然有线程生成,但是其机制是可以用于UI操作,这个在多线程和异步操作中有介绍。

4.Service在manifest.xml中的声明和优先级

    Servie和activity一样,需要在manifest中进行声明,器本身也有很多属性设置,可以参看SDK文档的介绍。Service可能被系统kill,就如同activity被kill一样,service也有其优先级,在SDK可以找到相应的优先级划分。

    



原创粉丝点击