参考:
https://blog.csdn.net/guolin_blog/article/details/11952435

bindService+startService Demo

清单文件

注意注册service

        <service android:name=".MyService" ><intent-filter><action android:name="com.test.chj" /></intent-filter></service>

布局文件

非常简单,四个按钮。最外面是个相对布局

    <Buttonandroid:id="@+id/start"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="start service" /><Buttonandroid:id="@+id/stop"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_below="@id/start"android:text="stop service" /><Buttonandroid:id="@+id/bind"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_below="@id/stop"android:text="bind service" /><Buttonandroid:id="@+id/unbind"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_below="@id/bind"android:text="unbind service" />

Java文件

先创建Service类,onBind和MyBinder可以先不看后面会说,所以主要就是三个方法:onCreate onStartCommand onDestroy

public class MyService extends Service {private static final String TAG = "MyService";@Overridepublic void onCreate() {Log.v(TAG, "onCreate");Log.d(TAG, "MyService thread id is " + Thread.currentThread().getId());super.onCreate();}@Overridepublic int onStartCommand(Intent intent, int flags, int startId) {Log.v(TAG, "onStartCommand");return super.onStartCommand(intent, flags, startId);}@Overridepublic void onDestroy() {Log.v(TAG, "onDestroy");super.onDestroy();}@Overridepublic IBinder onBind(Intent intent) {return new MyBinder();}class MyBinder extends Binder {public void startDownload() {Log.d("TAG", "startDownload() executed");}}
}

主界面内容也很简单,就是4个按钮,一个标志位。在onCreate初始化,设置点击事件。注意内部类ServiceConnection只服务于bind的service

public class MainActivity extends Activity implements OnClickListener {protected static final String TAG = "MainActivity";Button start, stop, bind, unbind;boolean isBound =false;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);Log.d(TAG, "MainActivity thread id is " + Thread.currentThread().getId());setContentView(R.layout.activity_main);start = (Button) findViewById(R.id.start);stop = (Button) findViewById(R.id.stop);bind = (Button) findViewById(R.id.bind);unbind = (Button) findViewById(R.id.unbind);start.setOnClickListener(this);stop.setOnClickListener(this);bind.setOnClickListener(this);unbind.setOnClickListener(this);}@Overridepublic void onClick(View v) {Intent i = new Intent();i.setAction("com.test.chj");switch (v.getId()) {case R.id.start:startService(i);break;case R.id.stop:stopService(i);break;case R.id.bind:bindService(i, conn, Context.BIND_AUTO_CREATE);isBound = true;break;case R.id.unbind:if(isBound){unbindService(conn);isBound= false;}break;default:break;}}ServiceConnection conn = new ServiceConnection() {@Overridepublic void onServiceDisconnected(ComponentName name) {Log.v(TAG, "onServiceDisconnected");}@Overridepublic void onServiceConnected(ComponentName name, IBinder service) {Log.v(TAG, "onServiceConnected");}};}

Service 启动方式startService

依次点击start service和stop service:
点击start service触发Service的 onCreate和 onStartCommand
点击stop service触发Service的 onDestroy
多次点击start service
onCreate只会触发一次,onStartCommand会触发多次
多次点击start service后多次点击stop service
onDestroy只会触发一次

Service启动方式bindService

依次点击bind service和unbind service:
点击bind service会触发Service的 onCreate和内部类ServiceConnection的onServiceDisconnected方法
点击unbind service触发Service的 onDestroy
多次点击bind service后多次点击unbind service
onCreate onServiceDisconnected onDestroy都只会调用一次。
注意:如果没有bindService就unbind会报错:

java.lang.IllegalArgumentException: Service not registered:

所以需要加个bool变量,确保解绑前确实调用过bind

Service混合启动

实验:
点击bind Service后点击stop Service不会触发Service的onDestroy
点击start Service后点击unbind Service也不会触发Service的onDestroy
无论先点击的bind Service还是start Service,需要stop Service和unbind Service都点击之后onDestroy才会触发
结论:
如果一个Service既通过start方法启动,又通过bind启动,则必须调用两个方法对应的接触Service方法,Service才会销毁。

Start和Bind service比较

Android 4.4验证如下
bind service与Activity紧密结合。当Activity销毁时(比如按了返回键),bind方式启动的activity会直接销毁(调用onDestroy),如果从最近列表删除应用程序,Service连onDestroy都不会调用就被销毁了。
而startService和Activity没有关系,除非Activity主动调用stopService,否则该Service与启动它的Activity无关,即使那个Activity已经关闭
另一个区别就是bindService可以和启动它的Activity通信,就是通过上面没有说的onBind方法和MyBinder对象

利用binder进行Service与Activity的进行通信(限bind启动)

其实之前bind启动时,触发的方法应该有三:
Service的onCreate onBind和Activity内部类的onServiceConnected
具体通信方式如下:
给MyBinder添加返回MyService对象的方法,添加MyService和MyBinder的测试方法
在onServiceConnected中既可以获得MyBinder的实例,又可以通过MyBinder获得MyService的实例,所以两者的方法都可以调用,这样就实现了Activity和Service的通信(通过Binder对象)
MyService:

    public void test(){//do sthLog.v(TAG, "test");}class MyBinder extends Binder {public MyService getService(){  return MyService.this;  }public void startDownload() {Log.d(TAG, "startDownload");new Thread(new Runnable() {  @Override  public void run() {  // 执行具体的下载任务  }  }).start();}}

内部类ServiceConnection onServiceConnected的实现

        public void onServiceConnected(ComponentName name, IBinder service) {Log.v(TAG, "onServiceConnected");MyBinder binder = (MyBinder) service;binder.startDownload();MyService serv =binder.getService();serv.test();}

前台Service与后台Service

之前的几种启动方法创建的Service都是后台Service,即没有界面,只能通过开发者选项查看正在运行的服务可以看到这些Service。
那么前台Service区别于后台Service,它有一个通知栏界面
要想把一个后台Service变成一个前台Service很简单,只要在Service的onCreate方法添加如下代码(给Service添加一个通知)

        Notification notification = new Notification(R.drawable.ic_launcher,  "有通知到来", System.currentTimeMillis());  Intent notificationIntent = new Intent(this, MainActivity.class);  PendingIntent pendingIntent = PendingIntent.getActivity(this, 0,  notificationIntent, 0);  notification.setLatestEventInfo(this, "这是通知的标题", "这是通知的内容",  pendingIntent);  startForeground(1, notification);  Log.d(TAG, "onCreate() executed"); 

前台service除了比后台service多了一个通知栏以外,其实最大的区别是前台service优先级高于后台service,不会因为内存不足而被操作系统轻易的kill掉

Service与Thread的关系?

Service的启动给我们一种幻觉,让我们觉得Service是Activity另起的一个线程。其实不然,本地Service仍然是运行在主线程的,我们可以通过在Activity的onCreate和Service的onCreate打印如下log:

        Log.d(TAG, " thread id is " + Thread.currentThread().getId());Log.d(TAG, " process id is " +Process.myPid());

来查看进程号和线程号。打印会发现Service的进程号和线程号都和Activity一致。也就是说,Service同样是运行在主线程的,因此不难得知,在Service中同样是不能直接执行耗时操作的,要另起线程。否则会导致主线程阻塞,发生ANR。
那么,既然如此,为什么不直接在Activity中创建Thread,做耗时操作呢?
原因是:

这是因为Activity很难对Thread进行控制,当Activity被销毁之后,就没有任何其它的办法可以再重新获取到之前创建的子线程的实例。而且在一个Activity中创建的子线程,另一个Activity无法对其进行操作。但是Service就不同了,所有的Activity都可以与Service进行关联,然后可以很方便地操作其中的方法,即使Activity被销毁了,之后只要重新与Service建立关联,就又能够获取到原有的Service中Binder的实例。因此,使用Service来处理后台任务,Activity就可以放心地finish,完全不需要担心无法对后台任务进行控制的情况。

Android Service基本使用相关推荐

  1. Android Service

    Android Service 和BroadCast .Activity.以及ContentProvider并称为安卓四大组件.在日常开发中接触最多的是Activity,因为android其实就是一个 ...

  2. android 浏览器源码分析,从源码出发深入理解 Android Service

    原标题:从源码出发深入理解 Android Service 原文链接: 建议在浏览器上打开,删除了大量代码细节,:) 本文是 Android 系统学习系列文章中的第三章节的内容,介绍了 Android ...

  3. android service 学习(上)

    转载自:http://www.cnblogs.com/allin/archive/2010/05/15/1736458.html Service是android 系统中的一种组件,它跟Activity ...

  4. android service 学习(下)

    android service 学习(下) 通常每个应用程序都在它自己的进程内运行,但有时需要在进程间传递对象,你可以通过应用程序UI的方式写个运行在一个不同的进程中的service.在android ...

  5. android service是单例么,android 使用单例还是service?

    stackover看到的回答,挺不错的. I'm quite new to Android development. When is it a good idea to create an Andro ...

  6. Android Service的思考(1)

    在Android框架中,Service是比较难以理解的一部分,傻蛋查阅了相关资料和经过一系列的代码测试,准备写一个系列文章,尝试着把Service由浅入深的梳理一遍,帮助大家更快的掌握Android ...

  7. Android Service 服务(二)—— BroadcastReceiver

    一. BroadcastReceiver简介 BroadcastReceiver,用于异步接收广播Intent,广播Intent是通过调用Context.sendBroadcast()发送.Broad ...

  8. Android Service完全解析,关于服务你所需知道的一切(下)

    转载请注册出处:http://blog.csdn.net/guolin_blog/article/details/9797169 在上一篇文章中,我们学习了Android Service相关的许多重要 ...

  9. Android Service使用方法--简单音乐播放实例

    Service翻译成中文是服务,熟悉Windows 系统的同学一定很熟悉了.Android里的Service跟Windows里的Service功能差不多,就是一个不可见的进程在后台执行. Androi ...

  10. Android Service的onStartCommand返回值用法

    2019独角兽企业重金招聘Python工程师标准>>> Android Service的onStartCommand返回值用法 本文目的:使读者快速理解 1.START_STICKY ...

最新文章

  1. 【怎样写代码】参数化类型 -- 泛型(七):泛型方法
  2. SAP LSMW 物料主数据导入毛重净重放大1000倍问题之对策
  3. Panda和numpy库和matplotlib库的安装
  4. 实验开篇介绍---开发板介绍
  5. android广告sdk破例,ADT bundle和Android SDK是什么?(能否说的通俗一些,谢谢)
  6. [android] AndroidManifest.xml【 manifest - permission-tree 和 manifest - permission-group】
  7. Hibernate的数据过滤查询
  8. pytorch 语义分割loss_vedaseg:基于pytorch的开源语义分割工具库,更多模型支持,更易拓展...
  9. 西瓜书——极大似然估计和朴素贝叶斯
  10. 朱海舟宣布新一批应用已经适配锤子TNT 网友:救救海舟
  11. java 中的wait notify
  12. 关于CNDotText的配置
  13. 中国工业经济数据库数据整理
  14. 网络时钟系统(子母钟系统)技术应用方案
  15. 趣学python编程下载_父与子的程序编写之旅:与小卡特一起学PythonPDF高清完整版一键下载|百度云盘...
  16. 独立样本t检验及其在SPSS中的实现
  17. 2000-2020年上市公司制造业数据/制造业上市公司数据
  18. 教你如何白嫖1TOneDrive云空间
  19. Nginx (一) --------- Nginx 简介
  20. LogExplore简介

热门文章

  1. canal kafka 环境搭建
  2. golang---文件读写
  3. RMAN catalog 的创建和使用
  4. 利用SuppressMessage来阻止FxCop进行代码分析时报出的警告
  5. 动态规划入门——斐波那契数(Leetcode 509)
  6. C语言课后习题(61)
  7. PAT乙级(1015 德才论)
  8. PAT乙级(1014 福尔摩斯的约会)
  9. python从文件初始化失败_iOS 6:libpython2.7.a初始化导入错误
  10. 最新课程 | openGauss 快速上手指南课程即将开课