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

Android核心基础-11.Android四大组件之Service

2015-09-21 17:04 681 查看

11.1.什么是服务

Service是一个可以长期在后台运行, 没有界面的组件.

它可以被其他组件绑定, 可以在进程之间通信.

11.2.创建Service

定义类继承Service, 实现回调函数.

在清单文件中声明
<service>


public class MyService extends Service {

@Override
public void onCreate() {
System.out.println("onCreate");
super.onCreate();
}

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

@Override
public IBinder onBind(Intent intent) {
System.out.println("onBind");
return null;
}

@Override
public void onDestroy() {
System.out.println("onDestroy");
super.onDestroy();
}
}


Service生命周期



11.3.启动服务,停止服务

在其他组件中可以调用startService()方法启动一个服务, 可以调用stopService()方法停止一个服务

在服务中可以使用stopSelf()方法停止服务

如果不传任何参数, 就是立即停止, 无论是否还有其他未执行结束的, 都会立即停止

传入startId则是等到所有其他的start()执行结束后再停止服务

public class MainActivity extends Activity {

private Intent intent;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
intent = new Intent(this, MyService.class);
}

public void start(View v) {
startService(intent); // 启动服务, onStartCommand()
}

public void stop(View v) {
stopService(intent); // 停止服务, onDestroy()
}
}


1.点击“启动服务”按钮,执行生命周期:

onCreate()->onStartCommand()

2.以后再点击“启动服务”按钮,执行

onStartCommand()

3.点击“停止服务”按钮,执行生命周期:

onDestroy()

示例源码->百度网盘

11.4.耗时操作

如果需要在服务中做耗时的操作, 那么也需要开启新的线程.

如果希望服务长期运行, 即使在内存不足的时候也不要被杀, 那么可以设置为前台服务. startForeground()

新建一个通知,调用startForeground()将服务设置为前台服务

public class MyService extends Service {

@Override
public void onCreate() {
System.out.println("onCreate");
super.onCreate();

Notification n = new Notification(R.drawable.ic_launcher, "MyService", System.currentTimeMillis());
Intent intent = new Intent();
intent.setClassName("net.dxs.service", "net.dxs.service.MainActivity");
PendingIntent pi = PendingIntent.getActivity(this, 0, intent, 0);
n.setLatestEventInfo(this, "MyService", "MyService在后台长期运行", pi);

startForeground(Process.myPid(), n);
}

@Override
public int onStartCommand(Intent intent, int flags, final int startId) {
System.out.println("onStartCommand");

new Thread() {
public void run() {
for (int i = 0; i < 10; i++) {
System.out.println(i);
SystemClock.sleep(1000);
}
// stopSelf();      // 无论调用了多少次start(), 都停止服务
stopSelf(startId);  // 标记当前的这次start()停止, 等到所有start()都停止的时候, 停止服务
}
}.start();
return super.onStartCommand(intent, flags, startId);
}

@Override
public IBinder onBind(Intent intent) {
System.out.println("onBind");
return null;
}

@Override
public void onDestroy() {
System.out.println("onDestroy");
super.onDestroy();
}
}


11.5.绑定服务

11.5.1.应用内部绑定

i.定义接口, 声明要提供的方法

ii.Service中定义一个类继承Binder(IBinder的子类), 实现自定义接口, 实现业务方法, 在onBind()方法中返回该类对象

iii.Activity中调用bindService()绑定服务, 传递一个ServiceConnection用来接收onBind()方法返回的IBinder, 强转为接口类型, 即可调用方法

定义一个接口InvokeInterface.java

public interface InvokeInterface {
/**
* 服务要提供的方法事先写在接口中
*/
public void pay();
public void play();
}


定义服务MyService.java

public class MyService extends Service {

@Override
public void onCreate() {
System.out.println("onCreate");
super.onCreate();
}

@Override
public IBinder onBind(Intent intent) { // bindService()时会执行
System.out.println("onBind");
return new MyBinder();
}

@Override
public boolean onUnbind(Intent intent) {
System.out.println("onUnbind");
return super.onUnbind(intent);
}

@Override
public void onDestroy() {
System.out.println("onDestroy");
super.onDestroy();
}

private class MyBinder extends Binder implements InvokeInterface {
public void pay() {
System.out.println("进行网络支付!");
}

public void play() {
System.out.println("进行音乐播放");
}
}
}


Activity中调用服务MainActivity.java

public class MainActivity extends Activity {
private InvokeInterface ii;

private ServiceConnection conn = new ServiceConnection() {

@Override
public void onServiceConnected(ComponentName name, IBinder service) {
ii = (InvokeInterface) service; // 绑定成功的时候执行, IBinder就是onBind()方法返回的对象
}

@Override
public void onServiceDisconnected(ComponentName name) { // 在服务被杀的时候执行(解绑时不会执行)
}
};

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
bindService(new Intent(this, MyService.class), conn, BIND_AUTO_CREATE); // 绑定服务, bindService(), 得到IBinder
}

public void pay(View v) {
ii.pay(); // 通过IBinder, 调用Service中的支付
ii.play();
}

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


生命周期:

1,调用服务的MainActivity一启动:

onCreate()->onBind()

2,点击支付按钮:

执行接口中的方法pay()、play()

3,关闭调用服务的MainActivity:

onUnbind()->onDestroy()

示例源码->百度网盘

11.5.2.应用之间绑定

i.使用AIDL定义接口, 刷新工程, Eclipse会自动生成一个Java接口

ii.Service中定义一个类继承Stub类, 实现抽象方法

iii.Activity中收到IBinder之后调用Stub.asInterface()方法把IBinder转为接口类型

定义aidl文件InvokeInterface.aidl

package net.dxs.remoteservice.invokeinterface;

interface InvokeInterface {
/**
* 服务要提供的方法事先写在接口中
*/
void pay();
}


定义服务RemoteService.java

package net.dxs.remoteservice;

import net.dxs.remoteservice.invokeinterface.InvokeInterface.Stub;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.os.RemoteException;

public class RemoteService extends Service {

@Override
public void onCreate() {
System.out.println("Remote onCreate");
super.onCreate();
}

@Override
public IBinder onBind(Intent intent) { // bindService()时会执行
System.out.println("Remote onBind");
return new MyBinder();
}

@Override
public boolean onUnbind(Intent intent) {
System.out.println("Remote onUnbind");
return super.onUnbind(intent);
}

@Override
public void onDestroy() {
System.out.println("Remote onDestroy");
super.onDestroy();
}

private class MyBinder extends Stub {
public void pay() throws RemoteException {
System.out.println("进行网络支付!");
}
}
}


远程Activity中调用服务,远程MainActivity.java

package net.dxs.remoteactivity;

import net.dxs.remoteservice.invokeinterface.InvokeInterface;
import net.dxs.remoteservice.invokeinterface.InvokeInterface.Stub;
import android.app.Activity;
import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.os.RemoteException;
import android.view.View;

public class MainActivity extends Activity {
private InvokeInterface ii;

private ServiceConnection conn = new ServiceConnection() {

@Override
public void onServiceConnected(ComponentName name, IBinder service) {
ii = Stub.asInterface(service); // Stub.asInterface() 可以把IBinder转为接口类型
}

@Override
public void onServiceDisconnected(ComponentName name) {// 在服务被杀的时候执行(解绑时不会执行)
}
};

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
bindService(new Intent("dxs.service.REMOTE_SERVICE"), conn, BIND_AUTO_CREATE); // 绑定服务, bindService(), 得到IBinder
}

public void pay(View v) throws RemoteException {
ii.pay(); // 通过IBinder, 调用Service中的支付
}

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


示例源码->百度网盘

示例源码->百度网盘

11.5.3.aidl中使用自定义类型

aidl中默认只支持基本数据类型和String以及CharSequences

如果需要使用自定义类型, 那么该类需要实现Parcelable, 需要实现writeToParcel()方法, 需要定义CREATOR对象

再根据这个类定义一个同名的aidl

在aidl接口中使用自定义类型作为参数的时候需要加上in

定义aidl文件InvokeInterface.aidl

package net.dxs.remoteservice.invokeinterface;

import net.dxs.remoteservice.bean.Person;

interface InvokeInterface {

/**
* 服务要提供的方法事先写在接口中
*/
boolean pay(in Person p, int amount);
}


定义服务RemoteService.java

package net.dxs.remoteservice;

import net.dxs.remoteservice.bean.Person;
import net.dxs.remoteservice.invokeinterface.InvokeInterface.Stub;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.os.RemoteException;

public class RemoteService extends Service {

@Override
public void onCreate() {
System.out.println("Remote onCreate");
super.onCreate();
}

@Override
public IBinder onBind(Intent intent) { // bindService()时会执行
System.out.println("Remote onBind");
return new MyBinder();
}

@Override
public boolean onUnbind(Intent intent) {
System.out.println("Remote onUnbind");
return super.onUnbind(intent);
}

@Override
public void onDestroy() {
System.out.println("Remote onDestroy");
super.onDestroy();
}

private class MyBinder extends Stub {

@Override
public boolean pay(Person p, int amount) throws RemoteException {
System.out.println("向" + p.getName() + "支付" + amount);
return amount < 100;
}
}
}


远程Activity中调用服务,远程MainActivity.java

package net.dxs.remoteactivity;

import net.dxs.remoteservice.bean.Person;
import net.dxs.remoteservice.invokeinterface.InvokeInterface;
import net.dxs.remoteservice.invokeinterface.InvokeInterface.Stub;
import android.app.Activity;
import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.os.RemoteException;
import android.view.View;

public class MainActivity extends Activity {
private InvokeInterface ii;

private ServiceConnection conn = new ServiceConnection() {

@Override
public void onServiceConnected(ComponentName name, IBinder service) {
ii = Stub.asInterface(service); // Stub.asInterface() 可以把IBinder转为接口类型
}

@Override
public void onServiceDisconnected(ComponentName name) {// 在服务被杀的时候执行(解绑时不会执行)
}
};

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
bindService(new Intent("dxs.service.REMOTE_SERVICE"), conn, BIND_AUTO_CREATE); // 绑定服务, bindService(), 得到IBinder
}

public void pay(View v) throws RemoteException {
System.out.println(ii.pay(new Person(101, "深情小建", 29), 150));   // 通过IBinder, 调用Service中的支付
}

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


我们的Person类接口Person.aidl

package net.dxs.remoteservice.bean;
parcelable Person;


我们的Person类Person.java

package net.dxs.remoteservice.bean;

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

public class Person implements Parcelable {
private Integer id;
private String name;
private Integer age;

public Person() {
super();
}

public Person(Integer id, String name, Integer age) {
super();
this.id = id;
this.name = name;
this.age = age;
}

@Override
public String toString() {
return "Person [id=" + id + ", name=" + name + ", age=" + age + "]";
}

public Integer getId() {
return id;
}

public void setId(Integer id) {
this.id = id;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public Integer getAge() {
return age;
}

public void setAge(Integer age) {
this.age = age;
}

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

@Override
public void writeToParcel(Parcel parcel, int flags) {
parcel.writeInt(id);
parcel.writeString(name);
parcel.writeInt(age);
}

public static final Parcelable.Creator<Person> CREATOR = new Parcelable.Creator<Person>() {
public Person createFromParcel(Parcel parcel) {
return new Person(parcel.readInt(), parcel.readString(), parcel.readInt());
}

public Person[] newArray(int size) {
return new Person[size];
}
};
}


附:提供给第三方调用的服务,要把aidl接口文件及javabean文件一块提供,且文件的包名要一致。

实例源码->百度网盘

实例源码->百度网盘
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  android 服务 Service