Android:Service

Android:Service

目录

- [一、使用Service](#1) - [二、绑定Service](#2) - [三、Service生命周期](#3) - [四、启动Service并传递数据](#4) - [五、绑定Service进行通信](#5) - [六、跨应用绑定Service](#7)

一、使用Service

  • Service的作用:在后台处理事务(Soecket、Http、与服务器保持推送的连接等)
  • Service的面向特点:不与用户进行交互。

初始创建

下面两个选项分别是:导出(即向外界公开)、启用

效果:

该app的界面:

打开设置中的运行界面:

开始服务后该app的信息界面:

此时运行界面就有LearnService的进程了,而且该进程不与用户进行交互。

  • 运行自己的代码的方法:

在服务的Java程序中重写onStartCommand的方法

public class MyService extends Service {

    private boolean serviceRunning = false;
    public MyService() {
    }

    @Override
    public IBinder onBind(Intent intent) {
        return  new Binder();
    }

    
    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        return super.onStartCommand(intent, flags, startId);
    }
    }

当外界执行StartService(Intentintent)的时候会执行onStartCommand方法,在onStartCommand方法中添加代码,就可以在开始服务的时候执行自己的代码啦~

例:

在开始服务的时候循环输出语句:

MyService.java

 @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
//        例:用线程让服务不断地输出语句
        new Thread(){
            @Override
            public void run(){
                super.run();
                while (serviceRunning) {
                    System.out.println("Code_One's Service is running...");

                    try {
                        //休眠一秒
                        sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }.start();

        return super.onStartCommand(intent, flags, startId);
    }

当启动服务的时候:

返回目录

二、绑定Service

绑定服务是另一种启动服务的方式。

绑定服务与解绑服务的代码

if(view.getId()==R.id.btnBindService){
            bindService(intent,this, Context.BIND_AUTO_CREATE);
        }else if(view.getId()==R.id.btnUnbindService){
            unbindService(this);
        }

写入后会让你重写两个方法:

 //服务被绑定成功后执行
    @Override
    public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
        
    }

    
  //进程崩溃或被杀掉的时候执行
    @Override
    public void onServiceDisconnected(ComponentName componentName) {

    }

往onServiceConnected中添加一行代码,让服务器被绑定的时候输出一句话:

//服务被绑定成功后执行
    @Override
    public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
        System.out.println("Service Connected");
    }

程序执行之后,点击绑定服务,发现会报错了

查看异常原因:

还没有实现。

查找代码错误的地方,是在

这里,说明服务绑定的时候用的是IBind这个方法,因为默认状态下,该方法的返回是抛出异常,因此会导致绑定失败。

当前状态下,可将代码稍改:

  @Override
    public IBinder onBind(Intent intent) {
        return  new Binder();
    }

这样就正常了。

返回目录

三、Service生命周期

onCreate、onDestroy

@Override
    public void onCreate() {
        super.onCreate();
        System.out.println("Service Create");
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        System.out.println("Service Destroy");
    }

点击启动服务的时候:

点击终止服务的时候:

点击绑定服务的时候:

点击解除绑定服务的时候:


点击启动服务之后再点击绑定服务:

然后点击解除绑定服务:

没反应。。。

那试试点击结束服务:

规律1:当你同时启动服务并绑定服务的时候,只有同时解除绑定服务并结束服务这样才能停止服务。



点击启动服务之后手机按后退键:

点击程序回去之后点击停止服务:

点击绑定服务之后手机按后退键:

规律2:Activity绑定某一个服务的时候,退出该Activity会取消与该服务的绑定。


  • 启动服务与绑定服务的差别:

将onStartCommand中的程序语句改成这样:

 @Override
    public int onStartCommand(Intent intent, int flags, int startId) {

        System.out.println("Code_One is struggling");

        return super.onStartCommand(intent, flags, startId);
    }

运行程序并多次点击启动服务:

onCreate只执行了一次,但onStartCommand执行的次数与点击的次数相同。

P.S:点击绑定和解绑是一个效果

返回目录

前三章代码整合:

https://gitee.com/VersionP1/MyAndroidTrack/tree/master/learnservice/src/main/java/com/example/learnservice

四、启动Service并传递数据

视频上这节课是用例子来讲的,我就不细搞了,烦。。。

但里面有个中的重点

例子中有这么一段代码

 if(view.getId()==R.id.btnStartService){
            Intent  i = new Intent(this,MyService.class);
           i.putExtra("data",etdata.getText().toString());
            startService(i);
        }

要将数据传递过去,按照常理的话,要在对应的活动中创建一个Intent来接收数据,但服务不用。服务中有一个方法

@Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        data = intent.getStringExtra("data");
        return super.onStartCommand(intent, flags, startId);
    }

在该方法中自带一个Intent,用该方法中的intent就可以实现数据的传输了。

返回目录

五、绑定Service进行通信


  • 同步数据

q1:何为同步数据?

如图,因为服务的onCreate中有一段线程循环,所以目前打印的都是Default Message。

当我在EditText中做修改后然后同步数据就可以看到

这就实现了数据的同步。

q2:如何实现??

在活动中有这样一段函数

 @Override
    public void onServiceConnected(ComponentName componentName,IBinder iBinder){
        
    }

里面有一个参数:IBinder iBinder(实际上也暗示了想要同步,同时也有要绑定)。同时,服务文件中有这么一个方法:

 @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

该方法是IBinder类,同时也意味着该方法会返回一个IBinder类的对象。因此要在onBind方法中做文章。

实际上

 @Override
    public void onServiceConnected(ComponentName componentName,IBinder iBinder){
        
    }

中IBinder iBinder访问的就是

 @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

因为步骤比较多,需要细看,不然会懵逼。。。

更具体的实例:https://gitee.com/VersionP1/MyAndroidTrack/tree/master/connectservice/src/main/java/com/example/connectservice


返回目录

六、跨应用绑定Service

要实现跨应用绑定Service,就要使用到AIDL。

创建位置:

创建好后要将服务里的onBind的返回改成IAppServiceRemoteBinder的对象,但发现不能找到该AIDL

解决办法:

然后就好了。。。

然后再打一遍:

因为AIDL属于抽象类,因此要将其中的方法给实现:

准备工作做完了,然后就是思考如何跨应用来绑定app:

anotherapp中要和跨应用的服务联系起来,要使用显式Intent将两者联系起来。

在正常的绑定语句之后,我们知道app中的服务返回的是AIDL,也知道onServiceConnected中的IBinder返回的是服务中的onBind方法返回的数据,:

注意:由于两个app都更新了数据,所以两个都要运行一遍

此时已经跨应用绑定服务成功。

代码:

https://gitee.com/VersionP1/MyAndroidTrack/tree/master/anotherapp/src/main/java/com/example/anotherapp

https://gitee.com/VersionP1/MyAndroidTrack/tree/master/app/src/main

返回目录

原文地址:https://www.cnblogs.com/VersionP1/p/7752993.html