Android Services 四大组件之一,主要用于后台长时间运行。没有界面。这里讲解两种services的启动还有AIDL通信方式。

1.startservices

a.建立继承services的类,复写方法(本地服务)

  1. public class MyServices extends Service {
  2.  
  3. private static final String TAG="TestTag";
  4.  
  5. @Override
  6. public IBinder onBind(Intent arg0) {
  7. // TODO Auto-generated method stub
  8. return null;
  9. }
  10.  
  11. @Override
  12. public void onCreate() {
  13. Log.i(TAG, "onCreate");
  14. super.onCreate();
  15. }
  16.  
  17. @Override
  18. public void onStart(Intent intent, int startId) {
  19. Log.i(TAG, "onStart");
  20. super.onStart(intent, startId);
  21. }
  22.  
  23. @Override
  24. public void onDestroy() {
  25. Log.i(TAG, "onDestroy");
  26. super.onDestroy();
  27. }
  28.  
  29. @Override
  30. public int onStartCommand(Intent intent, int flags, int startId) {
  31. Log.i(TAG, "onStartCommand");
  32. return super.onStartCommand(intent, flags, startId);
  33. }
  34.  
  35. }

b.声明AndroidManifest

  1. <service android:name=".MyServices"/>

c.启动关闭

  1. switch(v.getId()){
  2. case R.id.btnStart:
  3. startService(intent);
  4. break;
  5. case R.id.btnStop:
  6. stopService(intent);
  7. break;
  8. }

后记:

服务生命周期:context.startService() ->onCreate()- >onStart()- >onStartCommand()->Service running ->context.stopService()  ->onDestroy() ->Service stop

如果Service还没有运行,则android先调用onCreate()然后调用onStartCommand(),每次调用startService(Intent)的时候,都会调用执行onStartCommand();
如果Service已经运行,则只调用onStartCommand()。

2.bindservices

服务链接(ServiceConnection)或直接获取Service中状态和数据信息 
服务链接能够获取Service的对象,因此绑定Service的组件可以调用Service中的实现的函数 
使用Service的组件通过Context.bindService()建立服务链接,通过Context.unbindService()停止服务链接 
如果在绑定过程中Service没有启动,Context.bindService()会自动启动Service 
同一个Service可以绑定多个服务链接,这样可以同时为多个不同的组件提供服务

a.创建BindService继承Service

  1. public class BindService extends Service {
  2.  
  3. private static final String TAG="BindService";
  4.  
  5. private BindServiceX myBinderServiceX=new BindServiceX();
  6. public class BindServiceX extends Binder{
  7. public BindService getBindService() {
  8. return BindService.this;
  9. }
  10. }
  11.  
  12. @Override
  13. public IBinder onBind(Intent arg0) {
  14. // TODO Auto-generated method stub
  15. Log.i(TAG, "onBind");
  16. return myBinderServiceX;
  17. }
  18.  
  19. @Override
  20. public void onCreate() {
  21. Log.i(TAG, "onCreate");
  22. super.onCreate();
  23. }
  24.  
  25. @Override
  26. public boolean onUnbind(Intent intent) {
  27. Log.i(TAG, "onUnbind");
  28. return super.onUnbind(intent);
  29. }
  30.  
  31. @Override
  32. public void onDestroy() {
  33. Log.i(TAG, "onDestroy");
  34. super.onDestroy();
  35. }
  36.  
  37. @Override
  38. public int onStartCommand(Intent intent, int flags, int startId) {
  39. Log.i(TAG, "onStartCommand");
  40. return super.onStartCommand(intent, flags, startId);
  41. }
  42.  
  43. public void ShowLog(){
  44. Log.i(TAG, "BindService=>ShowLog");
  45. }
  46.  
  47. }

b.声明AndroidManifest

  1. <service android:name=".BindService"/>

c.启动使用

  1. public void onClick(View v) {
  2. Intent intentBind = new Intent(MainActivity.this, BindService.class);
  3.  
  4. switch (v.getId()) {
  5. case R.id.btnStartBindService:
  6. bindService(intentBind, conn, Context.BIND_AUTO_CREATE);
  7. break;
  8. case R.id.btnStopBindService:
  9. if (isConn) {
  10. unbindService(conn); //不可以多次调用
  11. isConn=false;
  12. }
  13. break;
  14. }

后记:

AndroidServiceActivity绑定方法,Context.BIND_AUTO_CREATE表明只要绑定存在,就自动建立Service;同时也告知Android系统,这个Service的重要程度与调用者相同,除非考虑终止调用者,否则不要关闭这个Service。

如果service没被创建,那么调用一次onCreate(),然后调用onBind(),多次绑定时,不会多次调用onBind()。

通过unbindService()函数取消绑定Servcie时,onUnbind()函数将被调用, 
如果onUnbind()函数的返回true,则表示在调用者绑定新服务时, 
onRebind()函数将被调用

取消绑定仅需要使用unbindService()方法,并将ServiceConnnection传递给unbindService()方法需注意的是,unbindService()方法成功后,系统并不会调用onServiceDisconnected(),因为onServiceDisconnected()仅在意外断开绑定时才被调用

3.AIDL IPC通信 services

Android系统中,各个应用都运行在自己的进程中,进程之间一般无法直接进行通信,为了实现进程通信(interprocess communication,简称IPC),android提供了AIDL Service;

Android需要AIDL(Android Interface Definition Language)来定义远程接口,这种接口定义语言并不是一种真正的变成语言,只是定义两个进程之间的通信接口;

与Java接口相似,但是存在如下几点差异:

  • AIDL定义接口的源代码必须以.aidl结尾;

  • AIDL用到的数据类型,除了基本类型、String、List、Map、CharSequence之外,其它类型全部都需要导包,即使它们在同一个包中也需要导包;

AIDL的步骤:

a.创建AIDL文件

  1. package com.example.zcx.servicesdemo;
  2.  
  3. // Declare any non-default types here with import statements
  4.  
  5. //interface ICat {
  6. // /**
  7. // * Demonstrates some basic types that you can use as parameters
  8. // * and return values in AIDL.
  9. // */
  10. // void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat,
  11. // double aDouble, String aString);
  12. //}
  13. interface ICat {
  14. String getColor();
  15. double getWeight();
  16. }

b.服务端编写

  1. public class AidlService extends Service {
  2. String[] colors = new String[] { "红色", "黄色", "黑色" };
  3. double[] weights = new double[] { 2.3, 3.1, 1.58 };
  4. private String color;
  5. private double weight;
  6. private CatBinder catBinder;
  7. Timer timer = new Timer();
  8.  
  9. @Override
  10. public void onCreate() {
  11. super.onCreate();
  12. catBinder = new CatBinder();
  13. timer.schedule(new TimerTask() {
  14.  
  15. @Override
  16. public void run() {
  17. // 随机地改变service组件内的color,weight属性的值
  18. int rand = (int) (Math.random() * 3);
  19. color = colors[rand];
  20. weight = weights[rand];
  21. System.out.println("---------" + rand);
  22. }
  23. }, 0, 800);
  24. }
  25.  
  26. @Override
  27. public IBinder onBind(Intent arg0) {
  28. /**
  29. * 返回CatBinder对象,在绑定本地Service情况下,
  30. * 该catBinder会直接传给客户端的ServiceConnected对象的ServiceConnected
  31. * ()方法的第二个参数;在绑定远程Service的情况下
  32. * ,只将catBinder对象的代理传给客户端的ServiceConnected对象的ServiceConnected()方法的第二个参数
  33. */
  34. return catBinder;
  35. }
  36.  
  37. @Override
  38. public void onDestroy() {
  39. timer.cancel();
  40. }
  41.  
  42. /**
  43. * 继承Stub,也就是实现了ICat接口,并实现了IBinder接口
  44. *
  45. * @author pengcx
  46. *
  47. */
  48. public class CatBinder extends ICat.Stub {
  49. @Override
  50. public String getColor() throws RemoteException {
  51. return color;
  52. }
  53.  
  54. @Override
  55. public double getWeight() throws RemoteException {
  56. return weight;
  57. }
  58. }
  59. }

androidmanifest:

  1. <service android:name=".AidlService" android:process=":remote">
  2. <intent-filter>
  3. <action android:name="org.crazyit.aidl.AIDL_SERVICE" />
  4. </intent-filter>
  5. </service>

c.客户端使用

首先需要建立aidl,注意要在相同的包名下,否则报错: java.lang.SecurityException: Binder invocation to an incorrect interface

  1. // ICat.aidl
  2. package com.example.zcx.servicesdemo;
  3.  
  4. // Declare any non-default types here with import statements
  5.  
  6. //interface ICat {
  7. // /**
  8. // * Demonstrates some basic types that you can use as parameters
  9. // * and return values in AIDL.
  10. // */
  11. // void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat,
  12. // double aDouble, String aString);
  13. //}
  14. interface ICat {
  15. String getColor();
  16. double getWeight();
  17. }

编写客户端:

  1. public class MainActivity extends AppCompatActivity {
  2.  
  3. private ICat catService;
  4. private Button getButton;
  5. private EditText colorEditText, weightEditText;
  6.  
  7. private ServiceConnection conn = new ServiceConnection() {
  8. @Override
  9. public void onServiceDisconnected(ComponentName name) {
  10. catService = null;
  11. }
  12.  
  13. @Override
  14. public void onServiceConnected(ComponentName name, IBinder service) {
  15. // 获取远程Service的onBinder方法返回的对象代理
  16. catService = ICat.Stub.asInterface(service);
  17. Log.d("zcx","catService");
  18. }
  19. };
  20. public static Intent getExplicitIntent(Context context, Intent implicitIntent) {
  21. // Retrieve all services that can match the given intent
  22. PackageManager pm = context.getPackageManager();
  23. List<ResolveInfo> resolveInfo = pm.queryIntentServices(implicitIntent, 0);
  24. // Make sure only one match was found
  25. if (resolveInfo == null || resolveInfo.size() != 1) {
  26. return null;
  27. }
  28. // Get component info and create ComponentName
  29. ResolveInfo serviceInfo = resolveInfo.get(0);
  30. String packageName = serviceInfo.serviceInfo.packageName;
  31. String className = serviceInfo.serviceInfo.name;
  32. ComponentName component = new ComponentName(packageName, className);
  33. // Create a new intent. Use the old one for extras and such reuse
  34. Intent explicitIntent = new Intent(implicitIntent);
  35. // Set the component to be explicit
  36. explicitIntent.setComponent(component);
  37. return explicitIntent;
  38. }
  39. @Override
  40. protected void onCreate(Bundle savedInstanceState) {
  41. super.onCreate(savedInstanceState);
  42. setContentView(R.layout.activity_main);
  43.  
  44. getButton = (Button) findViewById(R.id.getbutton);
  45. colorEditText = (EditText) findViewById(R.id.coloredittext);
  46. weightEditText = (EditText) findViewById(R.id.weightedittext);
  47.  
  48. // 创建所需要绑定的Service的Intent
  49. Intent intent = new Intent();
  50. intent.setAction("org.crazyit.aidl.AIDL_SERVICE");
  51. //intent.setPackage(getPackageName());
  52. Intent eintent = new Intent(getExplicitIntent(this,intent));
  53. Log.e("zcx","eintent = "+eintent);
  54. // 绑定远程的服务
  55. Log.e("zcx"," "+bindService(eintent, conn, Service.BIND_AUTO_CREATE));
  56.  
  57. getButton.setOnClickListener(new View.OnClickListener() {
  58. @Override
  59. public void onClick(View v) {
  60. // 获取并显示远程service的状态
  61. try {
  62. colorEditText.setText(catService.getColor());
  63. weightEditText.setText(catService.getWeight() + "");
  64. } catch (RemoteException e) {
  65. e.printStackTrace();
  66. }
  67. }
  68. });
  69. }
  70.  
  71. @Override
  72. protected void onDestroy() {
  73. super.onDestroy();
  74. // 解除绑定
  75. this.unbindService(conn);
  76. }
  77. }

Android -Services 使用简介的更多相关文章

  1. Android资源文件简介

    Android资源文件简介 1. Android应用资源的作用 (1) Android项目中文件分类 在Android工程中, 文件主要分为下面几类 : 界面布局文件, Java src源文件, 资源 ...

  2. Android Action Bar简介

    Android Action Bar简介 Design: Action Bar Action Bar是在屏幕顶端的一部分内容,通常在整个app进行中都保持存在. 它提供了几个关键的功能: 1.使得重要 ...

  3. eclipse安装androidSDK地址,Android SDK Manager简介

    eclipse安装android插件地址:https://dl-ssl.google.com/android/eclipse 这个和安装其他插件方式一样:Help—Install New Softwa ...

  4. 【Android 系统开发】 Android 系统启动流程简介

    作者 : 万境绝尘 (octopus_truth@163.com) 转载请注明出处 : http://blog.csdn.net/shulianghan/article/details/3889548 ...

  5. android.net.Uri 简介 API

    android.net.Uri 简介 public abstract class android.net.Uri extends Object implements Parcelable, Compa ...

  6. Android Notification通知简介

    Android Notification通知简介 根据activity的生命周期,在activity不显示时,会执行onStop函数(比如按下home键),所以你在onStop函数(按退出键除外)里面 ...

  7. Android MediaPlayer 基础简介

    本文链接: Android MediaPlayer 基础简介 简单介绍MediaPlayer的基本概念,状态,常用的方法与监听器. 什么是MediaPlayer MediaPlayer类可以用来播放音 ...

  8. Android属性系统简介

    1.简介 在android 系统中,为统一管理系统的属性,设计了一个统一的属性系统.每个属性都有一个名称和值,他们都是字符串格式.属性被大量使用在Android系统中,用来记录系统设置或进程之间的信息 ...

  9. Android属性系统简介【转】

    本文转载自:http://www.cnblogs.com/l2rf/p/6610348.html 1.简介 在android 系统中,为统一管理系统的属性,设计了一个统一的属性系统.每个属性都有一个名 ...

随机推荐

  1. JVM-即时编译JIT

    编译简介 在谈到JIT前,还是需要对编译过程有一些简单的了解. 在编译原理中,把源代码翻译成机器指令,一般要经过以下几个重要步骤: 什么是JIT1.动态编译(dynamic compilation)指 ...

  2. C#设计模式(4)——抽象工厂模式(Abstract Factory)

    简单工厂模式: 简单工厂模式的工厂类随着产品类的增加需要增加额外的代码 工厂方法模式: 工厂方法模式每个具体工厂类只完成单个实例的创建,所以它具有很好的可扩展性 但是在实际应用中,一个工厂不止会创建单 ...

  3. leetcode337

    /** * Definition for a binary tree node. * public class TreeNode { * public int val; * public TreeNo ...

  4. python接收html页面上传的文件

    使用的 flask, 没有安装的先安装 pip install flask 示例代码:示例没有自动创建静态文件夹,需要自己在同级 创建一个名为 static 的文件夹来存放上传的文件 示例展示为图片 ...

  5. 使用jQuery+huandlebars循环遍历中使用索引

    兼容ie8(很实用,复制过来,仅供技术参考,更详细内容请看源地址:http://www.cnblogs.com/iyangyuan/archive/2013/12/12/3471227.html) & ...

  6. tomcat8做成windows服务

  7. 2018面向对象程序设计(Java)第18周学习指导及要求

    2018面向对象程序设计(Java) 第18周学习指导及要求(2018.12.27-2018.12.30)   学习目标 (1) 综合掌握java基本程序结构: (2) 综合掌握java面向对象程序设 ...

  8. 十一、Composite 组合模式

    原理: 代码清单 Entity public abstract class Entry { public abstract String getName(); public abstract int ...

  9. 【Django】关于上传图片遇到的问题

    今天测试上传图片的时候,发现一只报错说找不到文件:FileNotFoundError 通过检查路径的输出,发现首先在settings配置路径的时候有问题 MEDIA_ROOT=os.path.join ...

  10. Python设计模式 - UML - 部署图(Deployment Diagram)

    简介 部署图也称配置图,用来显示系统中硬件和软件的物理架构.从中可以了解到软件和硬件组件之间的物理拓扑.连接关系以及处理节点的分布情况. 部署图建模步骤 - 找出需要进行部署的各类节点,如网络硬件设备 ...