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文件一块提供,且文件的包名要一致。
实例源码->百度网盘
实例源码->百度网盘
相关文章推荐
- 使用C++实现JNI接口需要注意的事项
- Android IPC进程间通讯机制
- Android Manifest 用法
- [转载]Activity中ConfigChanges属性的用法
- Android之获取手机上的图片和视频缩略图thumbnails
- Android之使用Http协议实现文件上传功能
- Android学习笔记(二九):嵌入浏览器
- android string.xml文件中的整型和string型代替
- i-jetty环境搭配与编译
- android之定时器AlarmManager
- android wifi 无线调试
- Android Native 绘图方法
- Android java 与 javascript互访(相互调用)的方法例子
- android 代码实现控件之间的间距
- android FragmentPagerAdapter的“标准”配置
- Android"解决"onTouch和onClick的冲突问题
- android:installLocation简析