Service 服务

Posted conglingkaishi

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Service 服务相关的知识,希望对你有一定的参考价值。

一.Service是四大组件之一,是没有界面的activity,可以用于做一些耗时的操作,比如后台下载等

生命周期如下

技术分享图片

 

二.如何定义一个Service

  1.创建一个类继承android:app.Service类,并实现抽象方法,onCreate(),OnStartCommand,onBind(),onUnBind(),onDestry;

 1 package com.example.servicetest;
 2 
 3 import android.app.Service;
 4 import android.content.Intent;
 5 import android.os.IBinder;
 6 import android.util.Log;
 7 
 8 public class MyService extends Service {  
 9       
10     public static final String TAG = "MyService";  
11   
12     //创建服务时调用
13     @Override  
14     public void onCreate() {  
15         super.onCreate();  
16         Log.d(TAG, "onCreate");  
17     }  
18   
19     //服务执行的操作
20     @Override  
21     public int onStartCommand(Intent intent, int flags, int startId) {  
22         Log.d(TAG, "onStartCommand");  
23         return super.onStartCommand(intent, flags, startId);  
24     }  
25       
26     //销毁服务时调用
27     @Override  
28     public void onDestroy() {  
29         super.onDestroy();  
30         Log.d(TAG, "onDestroy");  
31     }  
32   
33     @Override  
34     public IBinder onBind(Intent intent) {  
35         return null;  
36     }  
37 }

  2.在清单文件中配置Service

 <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

        <service
            android:name=".MyService"
            android:enabled="true"
            android:exported="true">
            
        </service>

三.服务的启动,停止,绑定,和解绑

  case R.id.start:
                //启动服务  服务创建--->启动
                // 如果服务已经创建再次启动时不会执行创建,操作还是同一个服务,除非销毁已存在的服务
                Intent intent = new Intent(this, MyService.class);
                startService(intent);
                break;
            case R.id.stop:
                //停止服务
                Intent intent1 = new Intent(this, MyService.class);
                stopService(intent1);
                break;
            case R.id.bind:
                //绑定服务
                Intent intent2 = new Intent(this, MyService.class);
                //bindService()中的参数依次是Intent,ServiceConnection和绑定时自动创建服务的标记位
                //如果绑定服务没有被启动,那么他会随着activity的销毁而销毁
                bindService(intent2, serviceConnection, BIND_AUTO_CREATE);
                break;
            case R.id.unbind:
                //解绑服务
                Intent intent3 = new Intent(this, MyService.class);
                unbindService(serviceConnection);
                break;

事实上,onCreate()方法只会在Service第一次被创建的时候调用,而onStartCommand()方法在每次启动服务的时候都会调用

停止服务的两种方式:

  1.在外部使用stopService()

  2.在服务的(onStartCommand方法)内部使用stopSelf()方法

onStartCommand方法执行时,返回的是一个int型。这个整型可以有三个返回值:START_NOT_STICKY、START_STICKY、START_REDELIVER_INTENT

  START_NOT_STICKY:执行完onStartCommand()方法后,服务被异常kill掉了,不会自动重启服务

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

  START_REDELIVER_INTENT:重传Intent。使用这个返回值时,系统会自动重启该服务,并将Intent的值传入。

四:使用Bind Service完成Service和Activity之间的通信

应用程序组件(客户端)通过调用bindService()方法能够绑定服务,然后Android系统会调用服务的onBind()回调方法,则个方法会返回一个跟服务器端交互的Binder对象。

这个绑定是异步的,bindService()方法立即返回,并且不给客户端返回IBinder对象。要接收IBinder对象,客户端必须创建一个ServiceConnection类的实例,并且把这个实例传递给bindService()方法。ServiceConnection对象包含了一个系统调用的传递IBinder对象的回调方法。

注意:只有Activity、Service、Content Provider能够绑定服务;BroadcastReceiver广播接收器不能绑定服务。

进度监控示例

public class MyService extends Service {

    private int i;

    public MyService() {
    }

    @Override
    public void onCreate() {
        Log.d("TAG", "服务创建了");
        //开启一个线程 进度,从1数到100
        new Thread(){
            @Override
            public void run() {
                super.run();
                for (i = 1; i <=100 ; i++) {
                    try {
                        sleep(2000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }.start();
        super.onCreate();
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.d("TAG", "服务启动了");
        return super.onStartCommand(intent, flags, startId);
    }

    @Override
    public IBinder onBind(Intent intent) {
        // TODO: Return the communication channel to the service.
        Log.d("TAG", "绑定");
        return new MyBind();
    }
    /**
     * 由于IBinder接口中需要实现的方法太多,而Binder实现了IBinder接口
     * 所以我么你自定义一个内部类继承他,并写入我们所需要的方法
     */
    class MyBind extends Binder{
        //自定义方法获取进度
        public int getProgress(){
            return i;
        }

    }
    @Override
    public boolean onUnbind(Intent intent) {
        Log.d("TAG", "解绑");
        return super.onUnbind(intent);
    }

    @Override
    public void onDestroy() {
        Log.d("TAG", "销毁");
        super.onDestroy();
    }
}

在MainActivity中

public class MainActivity extends AppCompatActivity {
    //ibind
    //ServiceConnection  一个接口 用于绑定服务与客户端
    //进度监控
    MyHandler myHandler = new MyHandler(this);
    ServiceConnection serviceConnection = new ServiceConnection() {
        //当客户端与服务正常连接时,执行服务的绑定操作会被调用
        @Override
        public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
            MyService.MyBind myBind = (MyService.MyBind) iBinder;
            int progress = myBind.getProgress();
            Log.d("TAg", "handleMessage: " + progress);
            if (progress <= 100) {
                Message message = new Message();
                message.arg1 = progress;
                myHandler.sendMessage(message);
            }

        }

        //当客户端与服务的连接丢失时
        @Override
        public void onServiceDisconnected(ComponentName componentName) {

        }
    };

 

以上是关于Service 服务的主要内容,如果未能解决你的问题,请参考以下文章

Android 从 Service 到 Client 的通信

java [Intent] Intent片段以启动Activity,Service或发送广播。 #android_snippet #android

一个 AsynckTask 的多个回调

Grails 根据环境将 Service 注入到 Controller

代码片段 - Golang 实现简单的 Web 服务器

从片段调用 Google Play 游戏服务