Android中Service基础知识

Service基础

Service并没有实际界面。而是一直运行在Android系统的后台运行。一般使用Service为应用程序提供一些服务。 或者不需要界面的功能。
- Service的生命周期
Service从启动到销毁的过程

  • 1.创建服务
  • 2.开始服务
  • 3.销毁服务

    Service需要在AndroidManifest.xml 文件的 中添加注册的代码

 <receiver android:name=".receiver.BootBroadcastReceiver">

android:name 属性是唯一必需的属性,用于指定服务的类名,
还可将其他属性包括在 < service > 元素中以定义一些特性

  • onStartCommand()
    当组件通过调用 startService() 请求启动服务时,系统将调用此方法(如果是绑定服务则不会调用此方法)。
    一旦执行此方法,服务即会启动并可在后台无限期运行。 在指定任务完成后,通过调用
    stopSelf() 或 stopService() 来停止服务
  • onBind()
    当一个组件想通过调用 bindService() 与服务绑定时,系统将调用此方法(如果是启动服务则不会调用此方法)。
    在此方法的实现中,必须通过返回 IBinder 提供一个接口,供客户端用来与服务进行通信
  • onCreate()
    首次创建服务时,系统将调用此方法来执行初始化操作(在调用 onStartCommand() 或 onBind() 之前)。
    如果在启动或绑定之前Service已在运行,则不会调用此方法
  • onDestroy()
    当服务不再使用且将被销毁时,系统将调用此方法,这是服务接收的最后一个调用,
    在此方法中应清理占用的资源

为了确保应用的安全性,最好始终使用显式 Intent 启动或绑定 Service,且不要为服务声明 Intent 过滤器。
启动哪个服务存在一定的不确定性,而如果对这种不确定性的考量非常有必要,
则可为服务提供 Intent 过滤器并从 Intent 中排除相应的组件名称,
但随后必须使用 setPackage() 方法设置 Intent 的软件包,这样可以充分消除目标服务的不确定性
此外,还可以通过添加 android:exported 属性并将其设置为 “false”,确保服务仅适用于本应用。
这可以有效阻止其他应用启动本应用内的服务,即便在使用显式 Intent 时也是如此

IntentService

IntentService 执行以下操作:

创建默认的工作线程,用于在应用的主线程外执行传递给 onStartCommand() 的所有 Intent
创建工作队列,用于将 Intent 逐一传递给 onHandleIntent() 实现,这样就不必担心多线程问题
在处理完所有启动请求后停止服务,因此不必自己调用 stopSelf()方法
提供 onBind() 的默认实现(返回 null)
提供 onStartCommand() 的默认实现,可将 Intent 依次发送到工作队列和 onHandleIntent()

因此,只需实现构造函数与 onHandleIntent() 方法即可

实现 ServiceConnection接口

重写两个回调方法:

onServiceConnected()
系统会调用该方法以传递服务的onBind() 方法返回的 IBinder
onServiceDisconnected()
Android 系统会在与服务的连接意外中断时,例如当服务崩溃或被终止时调用该方法。当客户端取消绑定时,系统不会调用该方法

调用 bindService(),传递 ServiceConnection 对象
当系统调用了 onServiceConnected() 的回调方法时,就可以通过IBinder对象操作服务了
要断开与服务的连接需调用 unbindService()方法。如果应用在客户端仍处于绑定状态时销毁客户端
会导致客户端取消绑定,更好的做法是在客户端与服务交互完成后立即取消绑定客户端,
这样可以关闭空闲服务

利用系统广播BroadcastReceiver 直接启动Service

 public class BootBroadcastReceiver extends BroadcastReceiver {
    public final static String ACTION_BOOT_COMPLETED = "android.intent.action.BOOT_COMPLETED";

    public BootBroadcastReceiver() {
        super();
    }

    @Override
    public void onReceive(Context context, Intent intent) {
        if(intent.getAction().equals(ACTION_BOOT_COMPLETED)){
            // 后边的XXX.class就是要启动的服务
            Intent actIntent = new Intent(context.getApplicationContext(), MainActivity.class);
            actIntent.setAction("android.intent.action.MAIN");
            actIntent.addCategory("android.intent.category.LAUNCHER");
            actIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            context.startActivity(actIntent);
            Log.v("TAG", "开机自动服务自动启动.....");
            // 启动应用,参数为需要自动启动的应用的包名
            Intent serIntent= new Intent(context, TestService.class);
            serIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            context.startService(serIntent);
            Log.v("TAG", "开机程序自动启动.....");
        }
    }
}

    <service android:name=".service.TestService"></service>

        <receiver android:name=".receiver.BootBroadcastReceiver">
            <intent-filter>
            <action android:name="android.intent.action.BOOT_COMPLETED" />
            <category android:name="android.intent.category.HOME" />
            </intent-filter>
        </receiver>

        添加权限:
         <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />

对Service状态进行判断

package com.example.administrator.androidtestdemo.service;

import android.annotation.SuppressLint;
import android.app.ActivityManager;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.util.Log;

import java.util.List;

public class ServiceManager {

  public static final String TAG="ServiceManager";


    /**
     * 判断Service是否注册
     * @param context
     * @param serviceAction
     * @return
     */
    public static boolean isRegistererService(Context context,String serviceAction){
        PackageManager packageManager=context.getPackageManager();
        //指定要查询的Service Action
        Intent intent=new Intent(serviceAction);
        //查询服务
        @SuppressLint("WrongConstant")
        List<ResolveInfo>resolveInfos=packageManager.queryIntentServices(intent,PackageManager.GET_INTENT_FILTERS);
        if(resolveInfos.size()>0){
            ResolveInfo resolveInfo=resolveInfos.get(0);
            Log.i(TAG,"服务信息:"+resolveInfo.toString());
            return true;
        }
        return false;
    }


    /**
     * 判断service是否正在运行
     * @param context
     * @param serviceNmae
     * @return
     */
    public static boolean isStartService(Context context,String serviceNmae){
        ActivityManager activityManager= (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
        //返回正在运行的Service
        List<ActivityManager.RunningServiceInfo> runningServiceInfos=activityManager.getRunningServices(100);
        for(int i=0;i<runningServiceInfos.size();i++){
            ActivityManager.RunningServiceInfo runningServiceInfo=runningServiceInfos.get(i);
            if(serviceNmae.equals(runningServiceInfo.service.getClassName())){
                Log.i(TAG,"服务正在运行:"+runningServiceInfo.service.getClassName());
                return true;

            }
        }
        return false;
    }

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值