Service之简单使用

来源:互联网 发布:双立人珐琅铸铁锅 知乎 编辑:程序博客网 时间:2024/06/11 21:36

生命周期

这里写图片描述

context.startService() ->onCreate()- >onStartCommand()->Service running--调用context.stopService() ->onDestroy() context.bindService()->onCreate()->onBind()->Service running--调用>onUnbind() -> onDestroy() 

基础知识

服务一般分为两种:

  1. 本地服务, Local Service 用于应用程序内部。在Service可以调用Context.startService()启动,调用Context.stopService()结束。 在内部可以调用Service.stopSelf() 或 Service.stopSelfResult()来自己停止。无论调用了多少次startService(),都只需调用一次 stopService()来停止。

  2. 远程服务, Remote Service 用于android系统内部的应用程序之间。可以定义接口并把接口暴露出来,以便其他应用进行操作。客户端建立到服务对象的连接,并通过那个连接来调用服 务。调用Context.bindService()方法建立连接,并启动,以调用 Context.unbindService()关闭连接。多个客户端可以绑定至同一个服务。如果服务此时还没有加载,bindService()会先加 载它。提供给可被其他应用复用,比如定义一个天气预报服务,提供与其他应用调用即可。

注意事项

同一服务,多次启动,服务实际执行的过程:

第一次 启动服务时,运行 onCreate –>onStartCommand

后面在启动服务时,服务只执行onStartCommand

在实际使用过程中,通过Intent 传递数据,在OnStartCommand中执行。

建议用onStartCommand

查看google 文档

http://developer.android.com/reference/android/app/Service.html

onStart(Intent intent, int startId)

This method was deprecated in API level 5. Implement onStartCommand(Intent, int, int) instead.

onStartCommand(Intent intent, int flags, int startId)

Called by the system every time a client explicitly starts the service by calling startService(Intent), providing the arguments it supplied and a unique integer token representing the start request.
鉴于目前的代码基本都是运行在API5 以上的,所以直接干掉onStart.

服务的类型

按照使用范围分类:

1、本地服务(Local Service):用于应用程序内部

功能:用于实现应用程序自己的一些耗时任务,比如查询升级信息,并不占用应用程序比如Activity所属线程,而是单开线程后台执行,这样用户体验比较好。

使用:在Service可以调用Context.startService()启动,调用Context.stopService()结束。在内部可以调用Service.stopSelf() 或 Service.stopSelfResult()来自己停止。无论调用了多少次startService(),都只需调用一次stopService()来停止。

2、远程服务(Remote Sercie):用于android系统内部的应用程序之间

功能:可被其他应用程序复用,比如天气预报服务,其他应用程序不需要再写这样的服务,调用已有的即可。

使用:可以定义接口并把接口暴露出来,以便其他应用进行操作。客户端建立到服务对象的连接,并通过那个连接来调用服务。调用Context.bindService()方法建立连接,并启动,以调用 Context.unbindService()关闭连接。多个客户端可以绑定至同一个服务。如果服务此时还没有加载,bindService()会先加载它。

按照运行类别分类分:

1、前台服务

前台服务需要调用 startForeground ( android 2.0 及其以后版本 )或 setForeground (android 2.0 以前的版本)使服务成为 前台服务。
使用前台服务可以避免服务在后台运行的时候被系统KILL。

使用:可以看出,我们只需要在onStartCommand里面调用 startForeground方法让服务前台运行,然后再onDestroy里面调用stopForeground解除前台运行既可!
所以,例如手机中的音乐播放器,不管手机是否是在休眠状态,只要开始播放了,系统就不会去KILL这个服务,只有当停止播放音乐时,服务才可能会回收清除。

2、后台服务

后台服务就是处于后台运行的

注意:本地服务中,onStart已经被onStartCommand方法取代,Service和Activity都是由Context类派生的,可以通过getApplicationContext()方法获取上下文对象,和Activity一样,它有着自己的生命周期,可是和Activity相比,它所执行的过程略有不同,如上图所示。

在服务分类中,提到了3种服务通信类型,一种是通过startService()直接启动服务,一种是通过bindService()的方式启动,2种启动方式对应的生命周期如上图所示。3.使用AIDL方式的Service( AIDL解析(一)两个应用之间使用AIDL进行通信的例子、AIDL解析(二 )让Service主动调起Activity吧!)

简单使用,使用广播和接口的两种不同方式传递消息

这里写图片描述

开启服务

这里写图片描述

停止服务

这里写图片描述

绑定服务

这里写图片描述

解绑服务

这里写图片描述

互发消息

这里写图片描述

ServiceActivity

package com.bourne.android_common.ServiceDemo;import android.content.BroadcastReceiver;import android.content.ComponentName;import android.content.Context;import android.content.Intent;import android.content.IntentFilter;import android.content.ServiceConnection;import android.os.Bundle;import android.os.IBinder;import android.support.v4.content.LocalBroadcastManager;import android.support.v7.app.AppCompatActivity;import android.view.View;import android.widget.ProgressBar;import com.bourne.android_common.R;import com.bourne.common_library.utils.Logout;public class ServiceActivity extends AppCompatActivity {    MyConn conn;    Intent intent;    MyService.IService iService;    MyService myService;    private LocalBroadcastManager mLocalBroadcastManager;    private MyBroadcastReceiver mBroadcastReceiver;    public final static String ACTION_TYPE_MYSERVICE= "action.type.myservice";    private int progress = 0;    private ProgressBar mProgressBar;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_service);        //注册广播        mLocalBroadcastManager = LocalBroadcastManager.getInstance(this);        mBroadcastReceiver = new MyBroadcastReceiver();        IntentFilter intentFilter = new IntentFilter();        intentFilter.addAction(ACTION_TYPE_MYSERVICE);        mLocalBroadcastManager.registerReceiver(mBroadcastReceiver, intentFilter);        mProgressBar = (ProgressBar) findViewById(R.id.progressBar);    }    /**     * 启动服务     *     * @param view     */    public void start(View view) {        intent = new Intent(ServiceActivity.this, MyService.class);        startService(intent);    }    /**     * 停止服务     */    public void stop(View view) {        stopService(intent);    }    /**     * 绑定服务     */    public void bind(View view) {        conn = new MyConn();        intent = new Intent(ServiceActivity.this, MyService.class);        bindService(intent, conn, BIND_AUTO_CREATE);    }    /**     * 绑定服务     */    public void unbind(View view) {        unbindService(conn);    }    /**     * 使用广播方式发送消息     */    public void brocast(View view) {        iService.callMethodInService();    }    /**     * 连接Service     */    private class MyConn implements ServiceConnection {            //使用广播方式            iService = (MyService.IService) service;            //使用接口方式            myService =  ((MyService.MyBinder)service).getService();            //注册回调接口来接收下载进度的变化            myService.setOnProgressListener(new MyService.OnProgressListener() {                @Override                public void onProgress(int progress) {                    mProgressBar.setProgress(progress);                }            });        }        public void onServiceDisconnected(ComponentName name) {        }    }    /**     * 使用广播方式接受Sercice的消息     */    public class MyBroadcastReceiver extends BroadcastReceiver {        @Override        public void onReceive(Context context, Intent intent) {            switch (intent.getAction()) {                case ACTION_TYPE_MYSERVICE:                    Logout.e("Activity收到来自Service的消息");                    break;            }        }    }    /**     * 使用接口方式发送消息     */    public void listener(View view) {        //开始下载        myService.startDownLoad();    }}

MyService

package com.bourne.android_common.ServiceDemo;import android.app.Service;import android.content.Intent;import android.os.Binder;import android.os.IBinder;import android.support.v4.content.LocalBroadcastManager;import com.bourne.common_library.utils.Logout;public class MyService extends Service {    public interface IService {        void callMethodInService();    }    public class MyBinder extends Binder implements IService {        public void callMethodInService() {            helloInservice();        }        /**         * 获取当前Service的实例         * @return         */        public MyService getService(){            return MyService.this;        }    }    /**     * 广播     */    private LocalBroadcastManager mLocalBroadcastManager;    /**     * 发送消息     */    private void sendBroadcast() {        Intent intent = new Intent(ServiceActivity.ACTION_TYPE_MYSERVICE);        mLocalBroadcastManager.sendBroadcast(intent);    }    public void helloInservice() {        Logout.e("service收到来自activity的消息");        sendBroadcast();    }    public MyService() {        Logout.e("MyService");    }    @Override    public void onStart(Intent intent, int startId) {        Logout.e("onStart");        super.onStart(intent, startId);    }    @Override    public int onStartCommand(Intent intent, int flags, int startId) {        Logout.e("onStartCommand");        return super.onStartCommand(intent, flags, startId);    }    @Override    public void onCreate() {        Logout.e("onCreate");        mLocalBroadcastManager = LocalBroadcastManager.getInstance(this);        super.onCreate();    }    @Override    public void onDestroy() {        Logout.e("onDestroy");        super.onDestroy();    }    @Override    public IBinder onBind(Intent intent) {        Logout.e("onBind");        return new MyBinder();    }    @Override    public boolean onUnbind(Intent intent) {        Logout.e("onUnbind");        return super.onUnbind(intent);    }    public interface OnProgressListener {        void onProgress(int progress);    }    /**     * 进度条的最大值     */    public static final int MAX_PROGRESS = 100;    /**     * 进度条的进度值     */    private int progress = 0;    /**     * 更新进度的回调接口     */    private OnProgressListener onProgressListener;    /**     * 注册回调接口的方法,供外部调用     * @param onProgressListener     */    public void setOnProgressListener(OnProgressListener onProgressListener) {        this.onProgressListener = onProgressListener;    }    /**     * 增加get()方法,供Activity调用     * @return 下载进度     */    public int getProgress() {        return progress;    }    /**     * 模拟下载任务,每秒钟更新一次     */    public void startDownLoad(){        new Thread(new Runnable() {            @Override            public void run() {                while(progress < MAX_PROGRESS){                    progress += 5;                    //进度发生变化通知调用方                    if(onProgressListener != null){                        onProgressListener.onProgress(progress);                    }                    try {                        Thread.sleep(1000);                    } catch (InterruptedException e) {                        e.printStackTrace();                    }                }            }        }).start();    }}

AndroidManifest

     <service android:name=".ServiceDemo.MyService"></service>

参考

  • Android Service 生命周期和使用注意项

  • Android Service与Activity之间通信的几种方式

  • Android 服务类Service 的详细学习

0 0
原创粉丝点击