Android基础篇(二),Service及IntentService

一,概述

上篇文章讲到了四大组件之activity的生命周期,这篇文章将介绍与activity最相似的另外一个组件service以及它的一个子类intentService,service组件是android四大组件中与activity最为相似的组件了,它和activity最大的区别在于没有界面,长期运行在后台,还有它的生命可以是四大组件中最长的一个了,没有界面,生命周期持续长是service作为android开发中必不可可少的四大组件之一,也是选择activity还是service的关键。要想学习service,我们首先得知道service的生命周期

二,service的生命周期

service根据启动方式的不一样,走的生命周期也不一样,下面我们看一张两种方式启动service的service的生命周期:

两种方式启动service

下面我们做个简单的测试,观察后台日志的打印:

布局文件

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center"
    android:orientation="vertical"
  >

     <LinearLayout 
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">
    <Button
        android:id="@+id/btn_start"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:padding="30dp"
        android:text="startService" />


    <Button
        android:id="@+id/btn_end"
        android:layout_width="0dp"
        android:padding="30dp"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:text="stopService" />

    </LinearLayout>
    <LinearLayout 
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">

    <Button
        android:id="@+id/btn_bind"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:padding="30dp"
        android:text="bindService" />

    <Button
        android:id="@+id/btn_unbind"
        android:layout_width="0dp"
        android:padding="30dp"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:text="unbindService" />
    </LinearLayout>

</LinearLayout>

CommonService.java


package com.example.servicedemo;

import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.util.Log;

public class CommonService extends Service {

    @Override
    public IBinder onBind(Intent arg0) {
        Log.e("onBind", "===============onBind================");
        return null;
    }

    @Override
    public void onCreate() {
        Log.e("onCreate", "===============onCreate================");
        super.onCreate();
    }

    @Override
    public void onDestroy() {
        Log.e("onDestroy", "===============onDestroy================");
        super.onDestroy();
    }

    @Override
    public void onRebind(Intent intent) {
        Log.e("onRebind", "===============onRebind================");
        super.onRebind(intent);
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.e("onStartCommand", "===============onStartCommand================");
        return super.onStartCommand(intent, flags, startId);
    }

    @Override
    public boolean onUnbind(Intent intent) {
        Log.e("onUnbind", "===============onUnbind================");
        return super.onUnbind(intent);
    }
}

MainActivity.java

package com.example.servicedemo;

import android.app.Activity;
import android.app.Service;
import android.content.ComponentName;
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.widget.Button;

public class MainActivity extends Activity implements View.OnClickListener{

    private ServiceConnection conn = new ServiceConnection() {

        /**
         * 当前客户端与服务断开连接的时候回调,在这里客户端就是MainActivity
         * @param name
         */
        @Override
        public void onServiceDisconnected(ComponentName name) {
            Log.e("onServiceDisconnected", "=======断开连接========");
        }

        /**
         * 当客户端与Service连接成功的时候回调,在这里客户端就是MainActivity
         * @param name
         * @param service
         */
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            Log.e("onServiceConnected", "=======连接成功========");
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Button btn_start = (Button) findViewById(R.id.btn_start);
        btn_start.setOnClickListener(this);
        Button btn_bind = (Button) findViewById(R.id.btn_bind);
        btn_bind.setOnClickListener(this);
        Button btn_end = (Button) findViewById(R.id.btn_end);
        btn_end.setOnClickListener(this);
        Button btn_unbind = (Button) findViewById(R.id.btn_unbind);
        btn_unbind.setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
        Intent intent;
        switch (v.getId()) {
        case R.id.btn_start:
            intent = new Intent(this,CommonService.class);
            startService(intent);
            break;
        case R.id.btn_bind:
            intent = new Intent(this,CommonService.class);
            bindService(intent, conn, Service.BIND_AUTO_CREATE);
            break;
        case R.id.btn_end:
            intent = new Intent(this,CommonService.class);
            stopService(intent);
            break;
        case R.id.btn_unbind:
            unbindService(conn);
            break;
        }
    }
}
service的启动和activity类似,别忘了在清单文件中配置service
<service 
      android:name="com.example.servicedemo.CommonService"></service>
startService和stopService:

这里写图片描述

连续点5次startService按钮,我们看到onCreate仅调用了一次,而onStartCommand方法每次都调用了:

这里写图片描述

从上面我们可以看出多次启动一个已有的service只会调用一个onCreate,但每次都会调用onStartCommand方法。下面我们看看bindService和unbindService:

这里写图片描述

连点5次bindService按钮:
这里写图片描述

我们看到,无论我们调用几次bindService,onCreate和onBind只会调用一次

通过上面的图片和测试我们对service的生命周期有了一定的认识,我们来总结一下service生命周期中各方法的调用
  • onBind():该方法是Service子类必须实现的方法,该方法返回一个IBinder对象,应用程序可以通过该对象与Service组件通信
  • onCreate():当service第一次被创建的时候调用,注意是第一次被创建
  • onDestroy():当service被销毁的时候调用
  • onStartCommand():每次客户端调用startService()启动该service的时候都会调用
  • onUnbind:当该service上绑定的所有客户端(通常是activity或broadcast)断开连接的时候都将会回调该方法
关于service的使用和activity的使用类似,当我们程序不需要界面就可以实现我们的需求的时候或者我们需要在某个activity退出后要执行某些操作,这个时候我们得用service而不是activity了,下面我们看一看service的子类intentService。

三,IntentService

IntentService是Service类的子类,用来处理异步请求。客户端可以通过startService(Intent)方法传递请求给IntentService。IntentService在onCreate()函数中通过HandlerThread单独开启一个线程来处理所有Intent请求对象(通过startService的方式发送过来的)所对应的任务,这样以免事务处理阻塞主线程。执行完上一个Intent请求对象所对应的工作之后,如果没有新的Intent请求达到,则自动停止Service;否则执行下一个Intent请求所对应的任务。
  IntentService在处理事务时,还是采用的Handler方式,创建一个名叫ServiceHandler的内部Handler,并把它直接绑定到HandlerThread所对应的子线程。 ServiceHandler把处理一个intent所对应的事务都封装到叫做onHandleIntent的虚函数;因此我们直接实现虚函数onHandleIntent,再在里面根据Intent的不同进行不同的事务处理就可以了。
另外,IntentService默认实现了Onbind()方法,返回值为null。
  使用IntentService需要两个步骤:
  1、写构造函数
  2、实现虚函数onHandleIntent,并在里面根据Intent的不同进行不同的事务处理就可以了。
好处:处理异步请求的时候可以减少写代码的工作量,比较轻松地实现项目的需求
注意:IntentService的构造函数一定是参数为空的构造函数(不然会报无空参数的构造方法初始化异常),然后再在其中调用super(“name”)这种形式的构造函数,那个name是写给我们程序员看的,没有什么实际意义。我们只要给他一个字符串就行了,通常我们会把它的名字作为参数传进去

根据上面的描述,我们可以知道在该service中我们可以处理耗时操作,我们只要把我们要处理的操作放到onHandleIntent方法里面处理。IntentService使用好方便,其他的和普通的service一样。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值