您的位置:首页 > 移动开发 > Android开发

Android四大组件之Service

2016-05-11 18:42 741 查看

Service

基本概念

Service是Android系统中的四大组件之一, 它跟Activity的级别差不多, 但不能自己运行只能后台运行, 并且可以和其他组件进行交互。Service可以在很多场合的应用中使用,比如播放多媒体的时候用户启动了其他Activity这个时候程序要在后台继续播放,比如检测SD卡上文件的变化,再或者在后台记录你地理信息位置的改变等等,总之服务总是藏在后台的。

Service的生命周期



onStartComand的返回参数



启动和停止一个Service

//启动一个服务
Intent intent = new Intent(this, MyService.class);
startService(intent);
//停止一个服务
Intent intent = new Intent(this, MyService.class);
stopService(intent);


Note:

started service:

1, 服务同时只会被创建一次,可以通过外部调用stopServic或者调用stopSelf终止自己的服务

2, 当执行一个以启动的服务,会直接调用onStartCommand方法来执行业务

3, 默认情况下服务与主线程同一个进程中的同一个线程中执行,如果执行一个比较耗时的操作,我们必须使用子线程完成工作, 避免主线程被阻塞

4, 使用started Service启动的一个服务在没有关闭之前会一直在后台运行!

IntentService



Note:

1, 内部有一个工作线程完成耗时操作, 只需要实现onHandleIntent()方法即可

2,完成工作后停止服务

3,同时执行多个任务时,会以工作队列的方式依次执行

4, 通常使用该类完成本App的耗时工作

public class MyIntentService extends IntentService {

public MyIntentService() {
super("MyIntentService");
}

@Override
protected void onHandleIntent(Intent intent) {
System.out.println(intent.getStringExtra("info"));
for (int i = 0; i < 20; i++) {
System.out.println("onHandleIntent " + i + " " + Thread.currentThread().getName());
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}

}
}


Bind Service



Note:

绑定服务:

通过绑定服务来实现功能的步骤:

1, 客户端通过bindService方法来绑定一个服务对象, 如果绑定成功, 会回调ServiceConnection接口中的onServiceConnected

2, 通过Service组件来暴露业务接口

3, 服务端通过创建一个*.aidl文件, 来定义一个可以被客户端调用的业务接口

一个aidl文件:

  (1) 不能有修饰符, 类似接口的写法

  (2) 支持的类型有8种基本数据类型和 String CharSequence, List, Map, 自定义类型

自定义类型要实现Parcelable接口

定义一个aidl文件声明该类型

在其他aidl文件中使用, 必须要使用import

4, 服务端需要提供一个业务接口的实现类, 通常会extends Stub类

5, 通过Service的onBind方法返回被绑定的方法

6, 客户端如果绑定chenggong,就可以像调用自己的方法一样调用远程的业务对象方法

使用技巧

started启动的服务会长期存在, 只要不停

bind启动的服务通常会在解锁时停止

通常情况下, 先started, 后bind

服务端代码

package com.lulu.admin.lservice;

import android.app.Service;
import android.content.Intent;
import android.os.IBinder;

public class MyBoundService extends Service {
public MyBoundService() {
}

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

//绑定
@Override
public IBinder onBind(Intent intent) {

return new CatImpl();

}

//解除绑定
@Override
public boolean onUnbind(Intent intent) {
return super.onUnbind(intent);
}

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

}
}


客户端代码

MainActivity.java

private ICat cat;
private boolean mBound = false;//是否绑定


//绑定服务的连接回调接口
private ServiceConnection conn = new ServiceConnection() {
//绑定成功后返回的方法
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
//得到cat对象
cat = ICat.Stub.asInterface(service);
mBound = true;
Toast.makeText(MainActivity.this, "绑定成功", Toast.LENGTH_SHORT).show();
}

@Override
public void onServiceDisconnected(ComponentName name) {
//服务异常时调用, 很少使用
mBound = false;
}
};

//绑定一个服务
public void boundClick(View view) {
Intent intent = new Intent(this, MyBoundService.class);
//异步绑定, 立即返回!
//绑定成功后会回调onServiceConnected!!!!!!
bindService(intent, conn, Context.BIND_AUTO_CREATE);  //如果没有创建就自动创建,如果创建了就不用了
}

//解绑的方法
public void unBoundClick(View view) {
if (mBound) {
unbindService(conn);
Toast.makeText(MainActivity.this, "解绑成功", Toast.LENGTH_SHORT).show();
mBound = false;
}
}

//
public void callClick(View v) {
if (cat == null) {
return;
}

try {
cat.setName("喵猫");

Toast.makeText(MainActivity.this, cat.desc() + " " + cat.getPerson().toString(), Toast.LENGTH_SHORT).show();

} catch (RemoteException e) {
e.printStackTrace();
}
}


Person.java

package com.lulu.admin.lservice;

import android.os.Parcel;
import android.os.Parcelable;

/**
* Created by Admin on 2016/5/18.
*/
public class Person implements Parcelable{
String name;
String works;

@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", works='" + works + '\'' +
'}';
}

public static final Parcelable.Creator<Person> CREATOR
= new Parcelable.Creator<Person>() {
public Person createFromParcel(Parcel in) {
Person p = new Person();
p.name = in.readString();
p.works = in.readString();
return p;
}
public Person[] newArray(int size) {
return new Person[size];
}
};

@Override
public int describeContents() {
return 0;
}

@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(name);
dest.writeString(works);
}
}


CatImp.java

package com.lulu.admin.lservice;

import android.os.RemoteException;

/**
* 业务接口的具体实现类
* Created by Admin on 2016/5/18.
* Stub是IBind的子类或者说是实现
*/
public class CatImpl extends ICat.Stub {
private String name;
@Override
public void setName(String name) throws RemoteException {
this.name = name;
}

@Override
public String desc() throws RemoteException {
return "hello my is" + name + ", I am a Cat";
}

@Override
public Person getPerson() throws RemoteException {
Person p = new Person();
p.name = "小次郎";
p.works = "强盗";
return p;
}

@Override
public void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat, double aDouble, String aString) throws RemoteException {

}
}


AIDL文件

ICat.aidl

// ICat.aidl
package com.lulu.admin.lservice;
import com.lulu.admin.lservice.Person;
// Declare any non-default types here with import statements

interface ICat {
void setName(String name);
String desc();
Person getPerson();//获取当前猫的主任
/**
* 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);
}


Person.aidl

// Person.aidl
package com.lulu.admin.lservice;

parcelable Person;


Messenger



让我们来大致说一下创建步骤

服务端

1, 首先创建一个handler,需要Service处理的代码在这里处理

2, 创建一个Messenger对象, 传入handler

3, 在onBind方法中返回由Messenger得到的Binder对象

public class MessengerService extends Service {
public static final int SAY_HELLO = 0x1;

public MessengerService() {

}

@Override
public IBinder onBind(Intent intent) {
return messenger.getBinder();
}

Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);

switch (msg.what) {
case SAY_HELLO:
String info = (String) msg.obj;
Toast.makeText(getApplicationContext(), info, Toast.LENGTH_SHORT).show();
break;
}

}
};
private Messenger messenger = new Messenger(handler);
}


客户端

我引用了API文档中的注释, 过程跟跟前面的讲述的绑定服务差不多

//首先声明一个Messenger
private Messenger mService = null;
private boolean mBound2 = false;

@Override
protected void onStart() {
super.onStart();
//绑定Messenger服务
bindService(new Intent(this, MessengerService.class), conn2, Context.BIND_AUTO_CREATE);

}

@Override
protected void onStop() {
super.onStop();
if(mBound2){
unbindService(conn2);
mBound2 = false;
Toast.makeText(MainActivity.this, "解绑成功", Toast.LENGTH_SHORT).show();
}
}

//使用Messenger方法, 绑定服务的连接回调接口
private ServiceConnection conn2 = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
// This is called when the connection with the service has been
// established, giving us the object we can use to
// interact with the service.  We are communicating with the
// service using a Messenger, so here we get a client-side
// representation of that from the raw IBinder object.
//创建一个Messenger对象传入IBinder的对象
mService = new Messenger(service);
mBound2 = true;
}

@Override
public void onServiceDisconnected(ComponentName name) {
// This is called when the connection with the service has been
// unexpectedly disconnected -- that is, its process crashed.
mService = null;
mBound2 = false;
}
};
//使用Messenger方法
public void messengerClick(View v) {
if(!mBound2){
return;
}
// Create and send a message to the service, using a supported 'what' value
Message msg = Message.obtain();
msg.what = MessengerService.SAY_HELLO;
msg.obj = "你好啊";
try {
mService.send(msg);
} catch (RemoteException e) {
e.printStackTrace();
}

}


Demo下载地址: http://download.csdn.net/download/u013144863/9524589

以上纯属个人见解, 如有不足之处希望有高人指出, 定感激不尽, 如有喜欢交流学习经验请给我留言谢谢.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  android service