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

1.startservices

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

public class MyServices extends Service  {

    private static final String TAG="TestTag";

    @Override
public IBinder onBind(Intent arg0) {
// TODO Auto-generated method stub
return null;
} @Override
public void onCreate() {
Log.i(TAG, "onCreate");
super.onCreate();
} @Override
public void onStart(Intent intent, int startId) {
Log.i(TAG, "onStart");
super.onStart(intent, startId);
} @Override
public void onDestroy() {
Log.i(TAG, "onDestroy");
super.onDestroy();
} @Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.i(TAG, "onStartCommand");
return super.onStartCommand(intent, flags, startId);
} }

b.声明AndroidManifest

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

c.启动关闭

switch(v.getId()){
case R.id.btnStart:
startService(intent);
break;
case R.id.btnStop:
stopService(intent);
break;
}

后记:

服务生命周期: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

public class BindService extends Service {

    private static final String TAG="BindService";

    private BindServiceX myBinderServiceX=new BindServiceX();
public class BindServiceX extends Binder{
public BindService getBindService() {
return BindService.this;
}
} @Override
public IBinder onBind(Intent arg0) {
// TODO Auto-generated method stub
Log.i(TAG, "onBind");
return myBinderServiceX;
} @Override
public void onCreate() {
Log.i(TAG, "onCreate");
super.onCreate();
} @Override
public boolean onUnbind(Intent intent) {
Log.i(TAG, "onUnbind");
return super.onUnbind(intent);
} @Override
public void onDestroy() {
Log.i(TAG, "onDestroy");
super.onDestroy();
} @Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.i(TAG, "onStartCommand");
return super.onStartCommand(intent, flags, startId);
} public void ShowLog(){
Log.i(TAG, "BindService=>ShowLog");
} }

b.声明AndroidManifest

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

c.启动使用

public void onClick(View v) {
Intent intentBind = new Intent(MainActivity.this, BindService.class); switch (v.getId()) {
case R.id.btnStartBindService:
bindService(intentBind, conn, Context.BIND_AUTO_CREATE);
break;
case R.id.btnStopBindService:
if (isConn) {
unbindService(conn); //不可以多次调用
isConn=false;
}
break;
}

后记:

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文件

package com.example.zcx.servicesdemo;

// Declare any non-default types here with import statements

//interface ICat {
// /**
// * Demonstrates some basic types that you can use as parameters
// * and return values in AIDL.
// */
// void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat,
// double aDouble, String aString);
//}
interface ICat {
String getColor();
double getWeight();
}

b.服务端编写

public class AidlService extends Service {
String[] colors = new String[] { "红色", "黄色", "黑色" };
double[] weights = new double[] { 2.3, 3.1, 1.58 };
private String color;
private double weight;
private CatBinder catBinder;
Timer timer = new Timer(); @Override
public void onCreate() {
super.onCreate();
catBinder = new CatBinder();
timer.schedule(new TimerTask() { @Override
public void run() {
// 随机地改变service组件内的color,weight属性的值
int rand = (int) (Math.random() * 3);
color = colors[rand];
weight = weights[rand];
System.out.println("---------" + rand);
}
}, 0, 800);
} @Override
public IBinder onBind(Intent arg0) {
/**
* 返回CatBinder对象,在绑定本地Service情况下,
* 该catBinder会直接传给客户端的ServiceConnected对象的ServiceConnected
* ()方法的第二个参数;在绑定远程Service的情况下
* ,只将catBinder对象的代理传给客户端的ServiceConnected对象的ServiceConnected()方法的第二个参数
*/
return catBinder;
} @Override
public void onDestroy() {
timer.cancel();
} /**
* 继承Stub,也就是实现了ICat接口,并实现了IBinder接口
*
* @author pengcx
*
*/
public class CatBinder extends ICat.Stub {
@Override
public String getColor() throws RemoteException {
return color;
} @Override
public double getWeight() throws RemoteException {
return weight;
}
}
}

androidmanifest:

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

c.客户端使用

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

// ICat.aidl
package com.example.zcx.servicesdemo; // Declare any non-default types here with import statements //interface ICat {
// /**
// * Demonstrates some basic types that you can use as parameters
// * and return values in AIDL.
// */
// void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat,
// double aDouble, String aString);
//}
interface ICat {
String getColor();
double getWeight();
}

编写客户端:

public class MainActivity extends AppCompatActivity {

    private ICat catService;
private Button getButton;
private EditText colorEditText, weightEditText; private ServiceConnection conn = new ServiceConnection() {
@Override
public void onServiceDisconnected(ComponentName name) {
catService = null;
} @Override
public void onServiceConnected(ComponentName name, IBinder service) {
// 获取远程Service的onBinder方法返回的对象代理
catService = ICat.Stub.asInterface(service);
Log.d("zcx","catService");
}
};
public static Intent getExplicitIntent(Context context, Intent implicitIntent) {
// Retrieve all services that can match the given intent
PackageManager pm = context.getPackageManager();
List<ResolveInfo> resolveInfo = pm.queryIntentServices(implicitIntent, 0);
// Make sure only one match was found
if (resolveInfo == null || resolveInfo.size() != 1) {
return null;
}
// Get component info and create ComponentName
ResolveInfo serviceInfo = resolveInfo.get(0);
String packageName = serviceInfo.serviceInfo.packageName;
String className = serviceInfo.serviceInfo.name;
ComponentName component = new ComponentName(packageName, className);
// Create a new intent. Use the old one for extras and such reuse
Intent explicitIntent = new Intent(implicitIntent);
// Set the component to be explicit
explicitIntent.setComponent(component);
return explicitIntent;
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); getButton = (Button) findViewById(R.id.getbutton);
colorEditText = (EditText) findViewById(R.id.coloredittext);
weightEditText = (EditText) findViewById(R.id.weightedittext); // 创建所需要绑定的Service的Intent
Intent intent = new Intent();
intent.setAction("org.crazyit.aidl.AIDL_SERVICE");
//intent.setPackage(getPackageName());
Intent eintent = new Intent(getExplicitIntent(this,intent));
Log.e("zcx","eintent = "+eintent);
// 绑定远程的服务
Log.e("zcx"," "+bindService(eintent, conn, Service.BIND_AUTO_CREATE)); getButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// 获取并显示远程service的状态
try {
colorEditText.setText(catService.getColor());
weightEditText.setText(catService.getWeight() + "");
} catch (RemoteException e) {
e.printStackTrace();
}
}
});
} @Override
protected void onDestroy() {
super.onDestroy();
// 解除绑定
this.unbindService(conn);
}
}

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. MySQL建表语句+添加注释

    1.建表+注释 CREATE TABLE student( id INT PRIMARY KEY AUTO_INCREMENT COMMENT '学号', name ) COMMENT '姓名', a ...

  2. java性能优化总结

    本人在java中积累了一些性能优化相关的经验,现在总结如下: 批量处理服务性能优化 RTB服务性能优化 BasicData线上问题解决,疯狂FullGC的问题 BasicData线上部分服务器cpu使 ...

  3. 深度学习原理与框架-递归神经网络-时间序列预测(代码) 1.csv.reader(进行csv文件的读取) 2.X.tolist(将数据转换为列表类型)

    1. csv.reader(csvfile) # 进行csv文件的读取操作 参数说明:csvfile表示已经有with oepn 打开的文件 2. X.tolist() 将数据转换为列表类型 参数说明 ...

  4. sys模块的介绍

    sys.argv           命令行参数List,第一个元素是程序本身路径 sys.exit(n)        退出程序,正常退出时exit(0) sys.version        获取 ...

  5. Gitlab安装与备份恢复

    GitHub是2008年由Ruby on Rails编写而成,与业界闻名的Github类似;但要将代码上传到GitHub上面,而且将项目设为私有还要收费.GitLab是一个用于仓库管理系统的开源项目, ...

  6. 最适合入门的Laravel中级教程(一)

    Laravel 是一个全栈框架: 我们使用 Laravel 开发业务常见有 3 个方向: 前端页面和后端逻辑混合的应用 主要是面向对 SEO 有需求的项目: 比如说新闻资讯博客文章等: 一般在控制器中 ...

  7. 4、python常用基础类型介绍

    1.字符串 str 描述性质的一种表示状态的例如名字 word='helloworld' print(type(word),word) <class 'str'> helloworld2. ...

  8. Sentinel统计线程,QPS,RT的方式

    一.Sentinel是阿里开源产品,用于流量监控和管理. 二.对于流量控制,可以通过限制线程数和QPS实现限流 1. 资源进入Sentinel的方式 Entry entry = null; try { ...

  9. JPA和SpringData知识梳理

    一. JPA,全称Java Persistence API,用于对象持久化的API,定义一套接口,来规范众多的ORM框架,所以它是在ORM框架之上的应用. 下面主要讲JPA在Hibernate基础上的 ...

  10. 利用CSS3实现透明边框和多重边框

    使用background-clip属性实现透明边框 .bordertest { border: 30px solid hsla(0,0%,90%,.5); background: #bbb; back ...