Android Service总结

android里面的Service是四大组件之一,也是项目中必然需要使用的内容。Service分为绑定服务和非绑定服务,绑定服务是与Activity进行绑定,如果Activity结束绑定的Service也结束,非绑定服务理论上除非调用stopService停止服务则服务不会停止。

使用服务时必须在AndroidManifest先进行配置

        <service android:name=".BackGroupService">

        </service>

        <service android:name=".LocalService">

        </service>

        <service android:name=".ForegroundService">

        </service>

        <service android:name=".MyIntentService">

        </service>

 然后再打开服务

Intent intent = new Intent(context,BackGroupService.class);
startService(intent)

首先是非绑定的服务

package com.kkrs.serivce;

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

/**
 * Created by zd on 2018/12/17.
 */

// 非绑定的service
public class BackGroupService extends Service {
    private boolean flag = true;

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

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.e("Service","onStartCommand");
        //在这里开线程来使用耗时操作
        new Thread(){
            @Override
            public void run() {
                super.run();
                while (flag) {
                    try {
                        sleep(2000);
                        Log.e("Service", "doSomeThing");
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }
        }.start();
        return super.onStartCommand(intent, flags, startId);
    }



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

    }

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        Log.e("Service","onBind");
        return null;
    }
}

 打开服务生命周期为 onCreate -> onStartCommand

 如果服务本身是打开的则直接进入 onStartCommand

   关闭服务的生命周期则是进入 onDestory

 

   然后是绑定的服务

   绑定服务需要使用ServiceConnection对服务进行连接,在activity中绑定的部分代码:

 /**
     * ServiceConnection代表与服务的连接,它只有两个方法,
     * onServiceConnected和onServiceDisconnected,
     * 前者是在操作者在连接一个服务成功时被调用,而后者是在服务崩溃或被杀死导致的连接中断时被调用
     */
    private ServiceConnection conn;
    private LocalService mService;
  @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        context = this;
        setContentView(R.layout.activity_main);


        btnBind = (Button)findViewById(R.id.btnBind);
        btnUnBind = (Button)findViewById(R.id.btnUnBind);
        btnGetDatas = (Button)findViewById(R.id.btnGetDatas);
      
        conn = new ServiceConnection() {
            /**
             * 与服务器端交互的接口方法 绑定服务的时候被回调,在这个方法获取绑定Service传递过来的IBinder对象,
             * 通过这个IBinder对象,实现宿主和Service的交互。
             */
            @Override
            public void onServiceConnected(ComponentName name, IBinder service) {
                Log.e("MainActivity", "绑定成功调用:onServiceConnected");
                // 获取Binder
                LocalService.LocalBinder binder = (LocalService.LocalBinder) service;
                mService = binder.getService();
            }
            /**
             * 当取消绑定的时候被回调。但正常情况下是不被调用的,它的调用时机是当Service服务被意外销毁时,
             * 例如内存的资源不足时这个方法才被自动调用。
             */
            @Override
            public void onServiceDisconnected(ComponentName name) {
                mService=null;
            }
        };

        final Intent intent = new Intent(this, LocalService.class);

        btnBind.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Log.e("MainActivity", "绑定调用:bindService");

                bindService(intent, conn, Service.BIND_AUTO_CREATE);

            }
        });

        btnUnBind.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                // 解除绑定
                Log.e("MainActivity", "解除绑定:bindService");

                if(mService!=null) {
                    Log.e("MainActivity", "mService!=null");
                    mService = null;
                    unbindService(conn);
                }
            }
        });

        btnGetDatas.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if (mService != null) {
                    // 通过绑定服务传递的Binder对象,获取Service暴露出来的数据
                    Log.e("MainActivity", "从服务端获取数据:" + mService.getCount());
                } else {

                    Log.e("MainActivity", "还没绑定呢,先绑定,无法从服务端获取数据");
                }
            }
        });
    }

 对于绑定服务的代码

//绑定的service
public class LocalService extends Service {

    private final static String TAG = "LocalService";
    private int count;
    private boolean quit;
    private Thread thread;
    private LocalBinder binder = new LocalBinder();

    @Override
    public void onCreate() {
        super.onCreate();
        Log.e(TAG, "Service is invoke Created");
        thread = new Thread(new Runnable() {
            @Override
            public void run() {
                // 每间隔一秒count加1 ,直到quit为true。
                while (!quit) {
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    count++;
                }
            }
        });
        thread.start();
    }

    public class LocalBinder extends Binder {
        // 声明一个方法,getService。(提供给客户端调用)
        LocalService getService() {
            // 返回当前对象LocalService,这样我们就可在客户端端调用Service的公共方法了
            return LocalService.this;
        }
    }

    /**
     * 公共方法
     * @return
     */
    public int getCount(){
        return count;
    }

    @Override
    public void onDestroy() {
        Log.e(TAG, "Service is onDestroy");

        this.quit = true;
        super.onDestroy();
    }

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

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        Log.e(TAG, "Service is onBind");

        return binder;
    }
}

 绑定 Created->onBind

   绑定时获得数据 onServiceConnected

   解除绑定  onUnbind ->  onDestroy

  

一般来讲在服务中使用耗时操作都会新创建一个线程,在线程中来处理,但是在线程的创建和判断则需要一些逻辑来判断。但是Android提供了一个专门用了执行耗时操作的Service,IntentService,使用这个就不需要在对你创建的线程进行处理,在这里将服务里面创建一个通知来显示服务的运行情况。

//耗时服务
public class MyIntentService extends IntentService {

    private boolean flag = true;
    private int num = 0;

    //需要一个空构造函数
    public MyIntentService() {
        super("MyIntentService"); // 调用父类的有参构造函数
    }

    public MyIntentService(String name) {
        super(name);
        Log.e("MyIntentService","MyIntentService");
    }

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

    @Override
    public void onStart(@Nullable Intent intent, int startId) {
        super.onStart(intent, startId);
        flag = true;
        Log.e("MyIntentService","onStart");
    }

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

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

    //这里进行耗时操作
    @Override
    protected void onHandleIntent(@Nullable Intent intent) {
        Log.e("MyIntentService","onHandleIntent");
        final Context context = this.getApplicationContext();

        while (flag){
            try {
                sleep(2000);
                Log.e("MyIntentService","start Intent");
                if (num > 100){
                    num = 0;
                }
                Notification notification = new Notification.Builder(context)
                        .setContentTitle("前台服务的标题")
                        .setContentText("这是一个前台服务 "+num)
                        .setSmallIcon(R.mipmap.ic_launcher)
                        .setWhen(System.currentTimeMillis())
                        .build();
                startForeground(110, notification);// 开始前台服务
                num = num + 1;
            }catch (Exception e){

            }
        }
    }
}

 打开服务生命周期为 onCreate -> onStartCommand->onStart->onHandleIntent

 如果服务本身是打开的则直接进入 onStartCommand->onStart

   关闭服务的生命周期则是进入 onDestory

  

Android Service总结

上一篇:[转]注释驱动的 Spring cache 缓存介绍


下一篇:CSAPP:第八章 异常控制流1