Services



    • Services

        • A service can essentially take two forms
    • startService开启服务
      • startService开启服务示例
    • bindService开启服务
      • bindService示例
      • bindService示例2
    • IntentService
    • 混合方式开启服务
      • 混合方式开启服务示例
  • 代码下载

Services

A Service is an application component that can perform long-running operations in the background and does not provide a user interface. Another application component can start a service and it will continue to run in the background even if the user switches to another application. Additionally, a component can bind to a service to interact with it and even perform interprocess communication (IPC). For example, a service might handle network transactions, play music, perform file I/O, or interact with a content provider, all from the background.

服务后台长时间运行,无界面,组件可以绑定一个服务与它交互

A service can essentially take two forms:

Started

A service is “started” when an application component (such as an activity) starts it by calling startService(). Once started, a service can run in the background indefinitely(无限期地), even if the component that started it is destroyed. Usually, a started service performs a single operation and does not return a result to the caller. For example, it might download or upload a file over the network. When the operation is done, the service should stop itself.

Bound

A service is “bound” when an application component binds to it by calling bindService(). A bound service offers a client-server interface that allows components to interact with the service, send requests, get results, and even do so across processes with interprocess communication (IPC). A bound service runs only as long as another application component is bound to it. Multiple components can bind to the service at once, but when all of them unbind, the service is destroyed.


  • 服务通过startService开启,将一直在后台运行,服务一般不返回值,在后台完成任务,最好关闭服务
  • 服务是“绑定”当一个应用程序组件绑定到它通过调用bindService(),绑定服务提供了一个客户机-服务器接口,允许组件与服务交互,多个组件可以绑定到服务,但是当他们解开,服务被摧毁。

Caution: A service runs in the main thread of its hosting process—the service does not create its own thread and does not run in a separate process (unless you specify otherwise). This means that, if your service is going to do any CPU intensive work or blocking operations (such as MP3 playback or networking), you should create a new thread within the service to do that work. By using a separate thread, you will reduce the risk of Application Not Responding (ANR) errors and the application’s main thread can remain dedicated to user interaction with your activities.


警告:一个服务运行在主线程的托管进程(服务不创建自己的线程和不运行在一个单独的进程(除非您指定)。这意味着,如果你的服务要做任何CPU密集型工作或阻塞操作(如MP3播放或网络),您应该创建一个新线程内的服务工作。通过使用一个单独的线程,你会减少应用程序没有响应的风险(ANR)错误和应用程序的主线程可以继续致力于用户交互活动。



Service生命周期图

startService开启服务

startService开启服务示例

public class DemoService extends Service {
    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
    //必须要重写的方法
        return null;
    }

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

    @Override
    public void onCreate() {
        super.onCreate();
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
    }

}
 //开启服务
    public void click1(View view) {
        Intent intent = new Intent(this,DemoService.class);
        startService(intent);

    }
    //关闭服务
    public void click2(View view) {
        Intent intent = new Intent(this,DemoService.class);
        stopService(intent);

    }

<manifest ... >
  ...
  <application ... >
      <service android:name=".DemoService" />
      ...
  </application>
</manifest>
  • onCreate–onStartCommand
  • onCreate在在第一次创建时执行,多次开启服务,只会开启onStartCommand 方法
  • 服务开启后,会长期执行,直到用户手工停止

bindService开启服务

目的是为了调用服务里的方法

   //点击按钮 绑定服务 开启服务的第二种方式
    public void click3(View view) {
        Intent intent = new Intent(this,DemoService.class);
        //连接到demoservice 这个服务
        conn = new Myconn();
        bindService(intent, conn,BIND_AUTO_CREATE);

    }
     @Override
    protected void onDestroy() {
        //当activity销毁时要解绑服务
        unbindService(conn);
        super.onDestroy();
    }

    //定义一个类来监视服务的状态
    private class Myconn implements ServiceConnection{

        @Override
        public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
            System.out.println("onServiceConnected");
        }

        @Override
        public void onServiceDisconnected(ComponentName componentName) {
            System.out.println("onServiceDisconnected");
        }
    }

  • 第一次点击按钮时会执行服务的onCreate方法和onBind方法
  • 当onBind方法返回为null时,onServerConnected方法是不执行的
  • 第二次点击bind服务时,服务没有响应
  • bind方式开启的服务,activity和service同生共死
  • 服务不能多次解绑,多次解绑会有异常
  • 通过bind方式开启服务,服务不能在设置里找到 相当于是一个隐形的服务

bindService示例

BanZhengService .java

public class BanZhengService  extends Service{
    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return new MyBinder();
    }
    public  void banZheng(int money) {
        if(money>1000){
            Toast.makeText(getApplicationContext(),"我是领导 把证给你办了",Toast.LENGTH_LONG).show();
        }else{
            Toast.makeText(getApplicationContext(),"就这点钱 还想办事...",Toast.LENGTH_LONG).show();
        }
    }
    //定义中间人ibinder
    public class MyBinder extends Binder {
        public void callbanZheng(int money){
            //调用办证的方法
            banZheng(money);
        }
    }
}

配置service

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


MainActivity.java

public class MainActivity extends AppCompatActivity {

    private MyConn conn;
    private BanZhengService.MyBinder myBinder;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Intent intent= new Intent(this,BanZhengService.class);
        conn = new MyConn();
        bindService(intent,conn,BIND_AUTO_CREATE);
    }
    public void click(View view) {
        myBinder.callbanZheng(100000);
    }

    @Override
    protected void onDestroy() {
        //解绑服务
        unbindService(conn);
        super.onDestroy();
    }

    //监视服务的状态
    public  class MyConn implements ServiceConnection{

        @Override
        public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
            myBinder = (BanZhengService.MyBinder) iBinder;
        }

        @Override
        public void onServiceDisconnected(ComponentName componentName) {

        }
    }
}

在BanZhengService里定义中间人MyBinder,定义一个方法调用service里的方法

bindService示例2

DemoService.java

public class DemoService extends Service {
    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return new MyBinder();
    }

    public void banZheng(int money) {
        if (money > 1000) {
            Toast.makeText(getApplicationContext(), "我是领导 把证给你办了", Toast.LENGTH_LONG).show();
        } else {
            Toast.makeText(getApplicationContext(), "就这点钱 还想办事...", Toast.LENGTH_LONG).show();
        }
    }

    public void playMajing() {
        System.out.println("陪领导打麻将");
    }

    public void 洗桑拿() {
        System.out.println("陪领导洗桑拿");
    }

    //定义中间人ibinder
    public class MyBinder extends Binder implements Iservice {

        public void callbanZheng(int money) {
            //调用办证的方法
            banZheng(money);
        }

        public void callPlayMajing() {
            playMajing();
        }

        public void callXiSanNa() {
            洗桑拿();
        }
    }
}

Iservice.java

public interface Iservice {

    //把领导想暴露的方法
    public void callbanZheng(int money);
}

MainActivity.java

public class MainActivity extends AppCompatActivity {

    private MyConn conn;
    private Iservice myBinder;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Intent intent = new Intent(this, DemoService.class);
        conn = new MyConn();
        bindService(intent, conn, BIND_AUTO_CREATE);
    }

    public void click(View view) {
        myBinder.callbanZheng(100000);
        //只有领导才能调桑拿
        //myBinder.callPlayMajing();
        // myBinder.callXiSanNa();
    }

    @Override
    protected void onDestroy() {
        //解绑服务
        unbindService(conn);
        super.onDestroy();
    }

    //监视服务的状态
    private class MyConn implements ServiceConnection {

        @Override
        public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
            myBinder = (Iservice) iBinder;
        }

        @Override
        public void onServiceDisconnected(ComponentName componentName) {

        }
    }
}

IntentService

服务中的代码都是默认运行在主线程当中的,如果直接在服务里去处理一些耗时的逻辑,就很容易出现ANR(Application Not Responding)的情况。

所以这个时候就需要用到Android多线程编程的技术了,我们应该在服务的每个具体的方法里开启一个子线程,然后在这里去处理那些耗时的逻辑。因此,一个比较标准的服务就可以写成如下形式:

public class MyService extends Service {

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

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
    //开启一个子线程
     new Thread(new Runnable() {
            @Override
            public void run() {
                // 处理具体的逻辑
            }
        }).start();
        return super.onStartCommand(intent, flags, startId);
    }

}

但是,这种服务一旦启动之后,就会一直处于运行状态,必须调用stopService()或者stopSelf()方法才能让服务停止下来。所以,如果想要实现让一个服务在执行完毕后自动停止的功能,就可以这样写:

public class MyService extends Service {

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

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

        new Thread(new Runnable() {
            @Override
            public void run() {
                // 处理具体的逻辑
                stopSelf();
            }

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

}

虽说这种写法并不复杂,但是总会有一些程序员忘记开启线程,或者忘记调用stopSelf()方法。为了可以简单地创建一个异步的、会自动停止的服务,Android专门提供了一个IntentService类,这个类就很好地解决了前面所提到的两种尴尬,下面我们就来看一下它的用法。

public class MyIntentService extends IntentService {
    public MyIntentService() {
        super("MyIntentService");
        // 调用父类的有参构造函数
    }

   /* public MyIntentService(String name) {
        super(name);
    }*/

    @Override
    protected void onHandleIntent(Intent intent) {
        // 打印当前线程的id
        Log.d("MyIntentService", "Thread id is " +
                Thread.currentThread().getId());
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        Log.d("MyIntentService", "onDestroy executed");
    }
}

开启MyIntentService

 public void click5(View view) {
        // 打印主线程的id
        Log.d("MainActivity", "Thread id is " + Thread.currentThread(). getId());
        Intent intentService = new Intent(this, MyIntentService.class);
        startService(intentService);
    }

可以看到,不仅MyIntentService和MainActivity所在的线程id不一样,而且onDestroy()方法也得到了执行,说明MyIntentService在运行完毕后确实自动停止了。这就是集开启线程和自动停止于一身IntentService.

混合方式开启服务

我们知道,通过startservice开启服务,服务会一直运行下去,除非自己stopservice;而bindservice开启服务,可以调用服务里的方法,但服务的生命周期和activity是绑定的,同生共死;可是我想服务长期运行,又想调用服务里的方法,这就需要混合方式开启服务

开启流程

- 先调用startService方法开启服务,让服务长期运行

- 调用bindService方法开启服务 ,去获取中间人对象

关闭流程

- unbindService 解绑服务

- stopService 关闭服务

混合方式开启服务示例



MainActivity.java

public class MainActivity extends AppCompatActivity {

    private IService iService;
    private Myconn conn;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        //混合开启服务
        //先调用startService 目的是可以保证服务在后台长期运行
        Intent intent = new Intent(this,MusicService.class);
        startService(intent);
        //调用bindservice 目的是获取我们定义的中jian人对象 就可以间接的调用服务
        conn = new Myconn();
        bindService(intent, conn,BIND_AUTO_CREATE);
    }

    @Override
    protected void onDestroy() {
        //当activity销毁的时候 解绑服务 不报红色日志
        unbindService(conn);
        super.onDestroy();
    }

    public void click1(View view) {
    //播放
        iService.callplayMusic();
    }
    public void click2(View view) {
    //暂停
        iService.callpauseMusic();
    }
    public void click3(View view) {
    //继续播放
        iService.callreplayMusic();
    }

    private class Myconn implements ServiceConnection {
        //当服务连接成功
        @Override
        public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
            //获取我们定义的中间人Ibinder
            iService = (IService) iBinder;

        }

        @Override
        public void onServiceDisconnected(ComponentName componentName) {

        }
    }
}


MusicService.java

public class MusicService extends Service {
    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        //把我们定义的中间人返回
        return new MyBinder();
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        /**
         * 开启一个线程,验证后台服务是否一直运行
         */
        final Handler handler = new Handler();
        Runnable runnable = new Runnable() {
            @Override
            public void run() {
                // TODO Auto-generated method stub
                //要做的事情
                Log.d("MusicService", new Date().toString());
                //每隔十秒执行一次
                handler.postDelayed(this, 10000);
            }
        };
        //两秒后执行
        handler.postDelayed(runnable, 2000);

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

    @Override
    public void onCreate() {
        super.onCreate();
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
    }

    public void playMusic() {
        Toast.makeText(getApplication(), "音乐播放了", Toast.LENGTH_SHORT).show();
        System.out.println("音乐播放了");
    }

    public void pauseMusic() {
        Toast.makeText(getApplicationContext(), "音乐暂停了", Toast.LENGTH_SHORT).show();
        System.out.println("音乐暂停了");
    }

    public void replayMusic() {
        Toast.makeText(getApplicationContext(), "音乐继续播放了", Toast.LENGTH_SHORT).show();
        System.out.println("音乐继续播放了");
    }

    //定义service和activity的中间人对象(Ibinder)
    private class MyBinder extends Binder implements IService {

        @Override
        public void callplayMusic() {
            playMusic();
        }

        @Override
        public void callpauseMusic() {
            pauseMusic();
        }

        @Override
        public void callreplayMusic() {
            replayMusic();
        }
    }
}


IService.java

public interface IService {
    //在接口里暴露方法
    public void callplayMusic();
    public void callpauseMusic();
    public void callreplayMusic();
}

这样就可以调用service里的方法了

即使把应用程序关闭后,也会定时打印出时间,说明service还在后台运行,只要不把进程关闭,service就会一直运行下去

代码下载

开启服务的两种方式

bind开启服务1

bind开启服务2(引入接口)

混合方式开启服务

时间: 2024-09-30 06:31:21

Services的相关文章

BizTalk调用WS-Security的web services

最近做个项目,biztalk跟OTM(Oracle Transportation Management)系统做对接,双方通过web services通讯,这部分是BizTalk调用OTM的web services. OTM的云服务,仅支持WS-Security的Username Token验证方式. 所以需要使用UsernameToken Web Service Security Policy,并使用HTTPS加密此SOAP消息的传输. OTM发布的web services是基于java的,也就

iPad上用Codea-SCM调用git web services做版本管理

iPad上用Codea-SCM调用git web services做版本管理 目录 说明 安装 Codea-SCM 远端代码仓库设置 本地 Codea-SCM 设置 说明 在 iPad 上使用 Codea 做项目开发,虽然调试.修改代码很方便,但是有一点比较麻烦,就是 Codea 无法做版本管理,所以有时修改错了,想回退到之前的稳定版本,就没办法了,只能手动保存每个版本的代码. 现在有一种方法可以把 Codea 的项目自动提交到 git 服务器上,可以非常方便地管理你的不同版本. 安装 Code

Azure云平台学习之路(三)——Cloud Services

1.什么是云服务? 能够部署高度可用的且可无限缩放的应用程序和API.简而言之,就是你写的CMD程序按照一定的框架进行少量修改就能运行在Azure云平台上. 2.Azure云服务有什么特点? (1)专注应用程序而不是硬件,PaaS的一种. (2)支持多种框架和语言. (3)集成了运行状况监视和负载平衡. (4)自动缩放优化成本和性能 3.建立云服务之前,我们需要建立一个云存储,来记录我们的程序的日志信息(当然,这不是必须的) (1)选择左边导航栏的"存储".主面板上显示的是所有已有的存

跟我一起学WCF(3)——利用Web Services开发分布式应用

一.引言 在前面文章中分别介绍了MSMQ和.NET Remoting技术,今天继续分享.NET 平台下另一种分布式技术——Web Services 二.Web Services 详细介绍 2.1 Web Services 概述 Web Services是支持客户端与服务器通过网络互操作的一种软件系统,是一组可以通过网络调用的应用程序API.在Web Services中主要到SOAP/UDDI/WSDL这三个核心概念,下面分别介绍下这三个概念的定义. SOAP:SOAP(Simple Object

Develop系列-API Guides-应用组件-Services-Bound Services

Bound Services CS架构,其中C是调用组件,S是Bound Services: C通过bindService来绑定,这个方法立即返回,没有返回值,C需要实现ServiceConnection里面的onServiceConnected和onServiceDisconnected接口. 多个C绑定同一个S时,S只调用一次onBind返回IBinder,后续来绑定S的C,直接得到同一个IBinder,onBind不再重复执行. 创建Bound Services 扩展Binder类:只在应

System Center 2012 R2 CM系列之部署Windows Server Update Services(WSUS)服务器

1. Windows更新服务器(Windows Server Update Service (WSUS))介绍 1) 技术概述: Windows Server Update Services (WSUS) 启用信息技术管理员部署最新的 Microsoft 产品更新.在 Windows Server 2012 中,WSUS 是可安装以管理和分配更新的服务器角色.WSUS 服务器可以作为组织内其他 WSUS 服务器的更新源.充当更新源的 WSUS 服务器被称为上游服务器.在 WSUS 实现过程中,网

《Citrix Provisioning Services 7.13企业虚拟化实战》课程近期发布

基于本人多年的项目经验,加上近期长达半年呕心沥血的总结.近期准备出一期视频教程,总共20课,旨在帮助广大IT技术爱好者掌握使用的技术.历经2周,目前已经讲到14课,预计下周末之前可以发布.课程售价暂定为499RMB.以下是课程目录,欢迎大家给出建议. 1.       云桌面前期规划及硬件采购建议; 2.      服务器虚拟化的建议: 3.      XenServer 安装.本次教学环境介绍: 4.      在XenServer中安装以一台虚拟机: 5.      搭建域控制器并将一台PC

Windows:使用Dos命令管理服务(Services)

一,查看Windows Service 按住组合键“Windows+R”,输入services.msc,打开Windows Services窗口 二,使用net命令 net命令行工具功能十分强大,包含了管理网络环境.服务.用户等重要管理功能,使用这个通用命令来启动和停止服务. 1,启动服务 net start service-name 2,停止服务 net stop service-name 三,使用sc命令 sc 是用于与服务控制器和服务进行通信的命令行程序,调用格式:sc (server)

Qt云服务/云计算平台QTC(Qt Cloud Services)入门(0)

在这个“大数据”的时代,传统的跨平台C++库Qt已经将魔爪丧心病狂的伸向了“云计算”.在2012年的Qt开发者大会上,Qt发布了BaaS(Backend as a Service)服务——Enginio,旨在为用户提供一个NoSQL数据库的后端平台.截至到(2014年9月),Qt云服务(Qt Cloud Services,简称“QTC”)已经发展成为了提供以下三种服务的云平台: Managed Application Runtime (MAR) Enginio Data Storage (EDS

Linux Integration Services 4.1 更新发布

关于linux的学习,请参考书籍<linux就该这么学> 微软已经正式发布了 LIS 4.1,此次更新的新功能特性如下:新增对 Red Hat Enterprise Linux.CentOS 和 Oracle Linux 的 5.2.5.3.5.4 及 7.2 版本的支持支持 Hyper-V Sockets支持内存热插拔支持SCSI WNNlsvmbus 更新增加 LIS 卸载脚本 安装之后,Linux Integration Services 提供 驱动程序支持:LIS 支持 Hyper-V