Service总结

Service与Activity区别:

相同点:都是Android四大组件之一,
不同点:

  1. Activity:用户交互界面
  2. Servict:没有用户界面,一直在后台运行,一旦Service被启动,它就和Activity一样,完全有自己的生命周期

Service应用场景:

  1. 播放多媒体的时候用户启动了其他Activity这个时候程序要在后台继续播放
  2. 比如检测SD卡上文件的变化
  3. 在后台记录你地理信息位置的改变等等

Service的应用步骤:

  1. 定义一个继承Service的子类
  2. 在AndroidMainfest.xml文件中配置该Service
  3. Service的生命周期
    这里写图片描述
public class FirstService extends Service {

    /**
     * 必须实现的方法
     */
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    /**
     * Service被创建时候调用
     */
    @Override
    public void onCreate() {
        super.onCreate();
    }

    /**
     * Service被启动的时候调用
     */
    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        return super.onStartCommand(intent, flags, startId);
    }

    /**
     * Service被关闭之前调用该方法
     */
    @Override
    public void onDestroy() {
        super.onDestroy();
    }
}

定义完了上面的Service之后,在AndroidMainfest.xml文件中配置Service,配置如图:

这里写图片描述

Service的两种启动模式:

  1. 通过Context的startService()方法:通过此方法启动Service,访问者与Service之间没有关联,即时访问者退出了应用,Service也仍在运行
  2. 通过Context的bindService()方法:使用该方法启动Service,访问者与Service绑定在一起,访问者一旦退出,Service也就终止啦

Service的启动与停止:

//启动
startService(intent);
//停止
stopService(intent);

1、Service 是否在 main thread 中执行, service 里面是否能执行耗时的操作?

  • 默认情况,如果没有显示的指 service 所运行的进程, Service 和 activity 是运行在当前 app 所在进程的Main Thread(UI 主线程)里面。

  • 特殊情况 ,可以在清单文件配置 service 执行所在的进程 ,让 service 在另外的进程中执行

<service
    android:name="com.baidu.location.f"
    android:enabled="true"
    android:process=":remote" >
</service>
  • service 里面不能执行耗时的操作(网络请求,拷贝数据库,大文件 )

2、 Activity 怎么和 Service 绑定,怎么在 Activity 中启动自己对应的 Service?

  • Activity 通过 bindService(Intent service, ServiceConnection conn, int
    flags)跟 Service 进行绑定,当绑定成 功的时候 Service 会将代理对象通过回调的形式传给 conn,这样我们就拿到了Service 提供的服务代理对象。

  • 在 Activity 中可以通过 startService 和 bindService 方法启Service。一般情况下如果想获取Service 的服务 对象那么肯定需要通过bindService()方法,比如音乐播放器,第三方支付等。如果仅仅只是为了开启一个后台任 务那么可以使用 startService()方法。

3、 请描述一下 Service 的生命周期

Service 有绑定模式和非绑定模式:

  • 非绑定模式:当第一次调用 startService 的时候执行的方法依次为 onCreate()、 onStartCommand(), onStart()当 Service 关闭的时候调用 onDestory 方法。

  • 绑定模式:第一次 bindService()的时候,执行的方法为 onCreate()、 onBind()解除绑定的时候会执行onUnbind()、 onDestory()。

  • 上面的两种生命周期是在相对单纯的模式下的情形。我们在开发的过程中还必须注意 Service 实例只会有一个, 也就是说如果当前要启动的
    Service 已经存在了那么就不会再次创建该 Service 当然也不会调用 onCreate()方法。

  • 一个 Service 可以被多个客户进行绑定,只有所有的绑定对象都执行了 onBind()方法后该 Service 才会销毁,
    不过如果有一个客户执行了 onStart()方法, 那么这个时候如果所有的 bind 客户都执行了 unBind()该 Service也不会 销毁

IntentService的使用:

简述: IntentService 是 Service 的子类,比普通的 Service 增加了额外的功能。先看 Service 本身存在两个问题:

  • Service 不会专门启动一条单独的进程, Service 与它所在应用位于同一个进程中;
  • Service 也不是专门一条新线程,因此不应该在 Service 中直接处理耗时的任务;

IntentService 特征

  • 会创建独立的 worker 线程来处理所有的 Intent 请求;

  • 会创建独立的 worker 线程来处理 onHandleIntent()方法实现的代码,无需处理多线程问题;所有请求处理完成后, IntentService 会自动停止,无需调用 stopSelf()方法停止 Service;

  • 为 Service 的 onBind()提供默认实现,返回 null;

  • 为 Service 的 onStartCommand 提供默认实现,将请求 Intent 添加到队列中;

扩展IntentService实现Service无须重写 onBind()、 onStartCommand()方法,只需要重写 onHandleIntent()方法即可

使用 IntentService
本人写了一个 IntentService 的使用例子供参考。该例子中一个 MainActivity 一个 MyIntentService,这两个类都是四大组件当然需要在清单文件中注册。这里只给出核心代码:

MainActivity.java:

public void click(View view){
    Intent intent = new Intent(this, MyIntentService. class);
    intent.putExtra("start", "MyIntentService");
    startService(intent);
}

MyIntentService.java

public class MyIntentService extends IntentService {
    private String ex = "";
    private Handler mHandler = new Handler() {
    public void handleMessage(android.os.Message msg) {
        Toast. makeText(MyIntentService. this, "-e " + ex,
        Toast. LENGTH_LONG).show();
        }
    };
    public MyIntentService(){
        super("MyIntentService");
    }
    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        ex = intent.getStringExtra("start");
        return super.onStartCommand(intent, flags, startId);
    }
    @Override
    protected void onHandleIntent(Intent intent) {
    /**
    * 模拟执行耗时任务
    * 该方法是在子线程中执行的,因此需要用到 handler 跟主线程进行通信
    */
    try {
        Thread. sleep(1000);
        } catch (InterruptedException e) {
        e.printStackTrace();
    }
    mHandler.sendEmptyMessage(0);
        try {
        Thread. sleep(1000);
        } catch (InterruptedException e) {
        e.printStackTrace();
        }
    }
}

说说 Activity、 Intent、 Service 是什么关系

  • 他们都是 Android 开发中使用频率最高的类。其中 Activity 和 Service 都是 Android四大组件之一。他俩都是Context 类的子类、ContextWrapper的子类,因此他俩可以算是兄弟关系吧。不过兄弟俩各有各自的本领, Activity负责用户界面的显示和交互, Service负责后台任务的处理。 Activity 和 Service 之间可以通过 Intent 传递数据, 因此可以把 Intent看作是通信使者。

Service 和 Activity 在同一个线程吗

  • 对于同一 app 来说默认情况下是在同一个线程中的, main Thread ( UI Thread)。

Service 里面可以弹吐司么?

  • 可以的。弹吐司有个条件就是得有一个 Context 上下文,而 Service 本身就是 Context 的子类,因此在Service里面弹吐司是完全可以的。比如我们在 Service 中完成下载任务后可以弹一个吐司通知用户。

Service 的 onStartCommand 方法有几种返回值?各代表什么意思?

  • START_STICKY: 如果 service 进程被 kill 掉, 保留 service 的状态为开始状态, 但不保留递送的intent 对象。 随 后 系 统 会 尝 试 重 新 创 建 service , 由 于 服 务 状 态 为 开 始 状 态 , 所以 创 建 服 务 后 一 定 会 调 用 onStartCommand(Intent,int,int)方法。如果在此期间没有任何启动命令被传递到 service,那么参数 Intent 将为 null。

  • START_NOT_STICKY: “非粘性的” 。 使用这个返回值时, 如果在执行完 onStartCommand 后, 服务被异常kill 掉,系统不会自动重启该服务。

  • START_REDELIVER_INTENT: 重传 Intent。 使用这个返回值时, 如果在执行完 onStartCommand 后,服务被异 常 kill 掉,系统会自动重启该服务,并将 Intent 的值传入。

  • START_STICKY_COMPATIBILITY: START_STICKY 的兼容版本,但不保证服务被 kill 后一定能重启。

Service 的 onRebind( Intent)方法在什么情况下会执行?**

  • 如果在 onUnbind()方法返回 true 的情况下会执行,否则不执行

Activity 调用 Service 中的方法都有哪些方式?

  • Extending the Binder class

    通过 Binder 接口的形式实现,当 Activity 绑定 Service 成功的时候 Activity 会在 ServiceConnection 的类的 onServiceConnected( ) 回调方法中获取到 Service 的 onBind( ) 方法 return 过来的 Binder 的子类。
    
  • Using a Messenger

  • Using AIDL

    aidl 比较适合当客户端和服务端不在同一个应用下的场景。
    

Service与Thread的区别

  • Thread:程序执行的最小单位,它是分配CPU的基本单位,执行一些异步操作(占用时间长,资源大)
  • Service:处理后台任务、运行在主线程
    简述:
1、完全不依赖UI,即时Activity被销毁了,或者程序被关闭啦,只要进程还在,Service就可以继续运行
2、应用要始终与服务器保持联系,就可在Service中实现,又因Service在主线程,一直执行,难道就不会阻塞线程吗?会,可在里面创建一个子线程,来处理耗时操作
3、那有为什么不在Activity中创建呢,因为不好控制线程,当Activity被销毁后,就没有办法在获取当前现成的实例了,而在一个Activity创建子线程,另里一个Activity无法对其进行操作,但是Service都会与Activity连接,机试Activity被销毁了,也可重新与Service建立连接,就又能获取原有的Service中Buinder的实例了,Activity就可以放心的Finish了
4、当内存不足时,后台Service就会被回收,可用前台Service
5、与后台线程的区别;一直在系统状态栏里显示

如何让一个 Service 成为前置进程

在启动该 Service 的时候可以在添加上如下方法:

@Override
    public int onStartCommand(Intent intent, int flags, int startId) {
    Notification notification = new Notification(R.drawable. ic_launcher, "服务正在运行",System. currentTimeMillis());
    Intent notificationIntent = new Intent(this, MainActivity. class);
    PendingIntent pendingIntent = PendingIntent. getActivity(this, 0,
    notificationIntent,0);
    notification. setLatestEventInfo(this, "消息标题", "消息内容", pendingIntent);
    startForeground(1, notification);
    return super.onStartCommand(intent, flags, startId);
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值