android学习笔记service介绍

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

    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可以找到相应的优先级划分。

    



评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值