Android Service
来源:互联网 发布:阿里云视频直播服务器 编辑:程序博客网 时间:2024/06/03 17:53
Android 有四大组件: Activity , Service , BroadcastReceiver , ContentProvider, 这篇主要讲Service
启动Service有两种方式: startService 和 bindService
startService:
Service也有自己的生命周期, startService是会依次调用service的 onCreate(), onStartCommand(),onStart()方法(实际在父类的onStartCommand()方法中主动调用的onStart()),如果Service已经启动了,则只会调用onStartCommand()和onStart().
stopService,停止已经开始的Service,会动用Service的onDestroy();
从log中可以看到,Service是运行与主线程,所以不应做繁重的任务,防止ANR.
bindService:
bindService 需要传三个参数 Intent ,ServiceConnection , flag
Intent 指明需要启动的Service ; ServiceConnection Service连接成功之后的回调; flag bind的方式,一般是1;
bindService 会依次调用Service的onCreate(),onBind()方法, 如果Service已经启动,再次bindService会连接,但不会再调用生命周期的方法
unbindService 会调用Service的onDestroy()。
通过bindService的方式启动Service,可以获取到一个IBinder对象,通过IBinder对象可以调用Service里的方法。
binderService的第二个参数: 通过onServiceConnected()回调 可以获取到IBinder对象。
1 ServiceConnection sc = new ServiceConnection() { 2 @Override 3 public void onServiceDisconnected(ComponentName name) { 4 5 } 6 @Override 7 public void onServiceConnected(ComponentName name, IBinder service) { 8 // TODO Auto-generated method stub 9 10 };
AIDL: android 接口定义语言,通过他可以实现进程间的通信。
要和远端的Service进行交互,可以使用aidl实现进程间的通信:
myService.aidl
1 package com.example.servicelearning.aidl;2 3 interface myService {4 void register();5 int get();6 }
编译之后,会在gen目录对应包名下自动生成一个myService.java的接口,里面有一个内部静态抽象类Stub,实现了myService的接口。
编译之后的myService.java
1 /* 2 * This file is auto-generated. DO NOT MODIFY. 3 * Original file: E:\\vivoCamera\\ServiceLearning\\src\\com\\example\\servicelearning\\aidl\\myService.aidl 4 */ 5 package com.example.servicelearning.aidl; 6 public interface myService extends android.os.IInterface 7 { 8 /** Local-side IPC implementation stub class. */ 9 public static abstract class Stub extends android.os.Binder implements com.example.servicelearning.aidl.myService 10 { 11 private static final java.lang.String DESCRIPTOR = "com.example.servicelearning.aidl.myService"; 12 /** Construct the stub at attach it to the interface. */ 13 public Stub() 14 { 15 this.attachInterface(this, DESCRIPTOR); 16 } 17 /** 18 * Cast an IBinder object into an com.example.servicelearning.aidl.myService interface, 19 * generating a proxy if needed. 20 */ 21 public static com.example.servicelearning.aidl.myService asInterface(android.os.IBinder obj) 22 { 23 if ((obj==null)) { 24 return null; 25 } 26 android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR); 27 if (((iin!=null)&&(iin instanceof com.example.servicelearning.aidl.myService))) { 28 return ((com.example.servicelearning.aidl.myService)iin); 29 } 30 return new com.example.servicelearning.aidl.myService.Stub.Proxy(obj); 31 } 32 @Override public android.os.IBinder asBinder() 33 { 34 return this; 35 } 36 @Override public boolean onTransact(int code, android.os.Parcel data, android.os.Parcel reply, int flags) throws android.os.RemoteException 37 { 38 switch (code) 39 { 40 case INTERFACE_TRANSACTION: 41 { 42 reply.writeString(DESCRIPTOR); 43 return true; 44 } 45 case TRANSACTION_register: 46 { 47 data.enforceInterface(DESCRIPTOR); 48 this.register(); 49 reply.writeNoException(); 50 return true; 51 } 52 case TRANSACTION_get: 53 { 54 data.enforceInterface(DESCRIPTOR); 55 int _result = this.get(); 56 reply.writeNoException(); 57 reply.writeInt(_result); 58 return true; 59 } 60 } 61 return super.onTransact(code, data, reply, flags); 62 } 63 private static class Proxy implements com.example.servicelearning.aidl.myService 64 { 65 private android.os.IBinder mRemote; 66 Proxy(android.os.IBinder remote) 67 { 68 mRemote = remote; 69 } 70 @Override public android.os.IBinder asBinder() 71 { 72 return mRemote; 73 } 74 public java.lang.String getInterfaceDescriptor() 75 { 76 return DESCRIPTOR; 77 } 78 @Override public void register() throws android.os.RemoteException 79 { 80 android.os.Parcel _data = android.os.Parcel.obtain(); 81 android.os.Parcel _reply = android.os.Parcel.obtain(); 82 try { 83 _data.writeInterfaceToken(DESCRIPTOR); 84 mRemote.transact(Stub.TRANSACTION_register, _data, _reply, 0); 85 _reply.readException(); 86 } 87 finally { 88 _reply.recycle(); 89 _data.recycle(); 90 } 91 } 92 @Override public int get() throws android.os.RemoteException 93 { 94 android.os.Parcel _data = android.os.Parcel.obtain(); 95 android.os.Parcel _reply = android.os.Parcel.obtain(); 96 int _result; 97 try { 98 _data.writeInterfaceToken(DESCRIPTOR); 99 mRemote.transact(Stub.TRANSACTION_get, _data, _reply, 0);100 _reply.readException();101 _result = _reply.readInt();102 }103 finally {104 _reply.recycle();105 _data.recycle();106 }107 return _result;108 }109 }110 static final int TRANSACTION_register = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0);111 static final int TRANSACTION_get = (android.os.IBinder.FIRST_CALL_TRANSACTION + 1);112 }113 public void register() throws android.os.RemoteException;114 public int get() throws android.os.RemoteException;115 }
在自己的Service 实现此类里面的抽象方法。在bindService的时候,onBind()方法可以return此对象,通过此对象实现通信。
BindServiceTest.java (记得在Manifest文件里声明Service)
1 package com.example.servicelearning.service; 2 3 import com.example.servicelearning.aidl.myService; 4 5 import android.app.Service; 6 import android.content.Intent; 7 import android.os.IBinder; 8 import android.os.RemoteException; 9 import android.util.Log;10 11 public class BindServiceTest extends Service {12 13 14 private static final String TAG = "BindServiceTestLog.TAG";15 16 17 myService.Stub mStub = new myService.Stub() {18 19 @Override20 public void register() throws RemoteException {21 // TODO Auto-generated method stub22 Log.d(TAG, "register from com.example.servicelearning");23 }24 25 @Override26 public int get() throws RemoteException {27 // TODO Auto-generated method stub28 return 10086;29 }30 };31 32 @Override33 public IBinder onBind(Intent intent) {34 Log.d(TAG, "onBind");35 return mStub;36 }37 38 }
为了验证通过AIDL实现的进程通信,我们可以再编写一个apk,通过这个apk启动之前那个apk里面的Service,并实现通信。
在这个apk里面我们必须写一个同样的aidl文件,包名必须和之前那个一致。
MainActivity.java (布局文件和Manifest文件都比较简单就不贴出来了)
1 /* 2 * This file is auto-generated. DO NOT MODIFY. 3 * Original file: E:\\vivoCamera\\ServiceLearning\\src\\com\\example\\servicelearning\\aidl\\myService.aidl 4 */ 5 package com.example.servicelearning.aidl; 6 public interface myService extends android.os.IInterface 7 { 8 /** Local-side IPC implementation stub class. */ 9 public static abstract class Stub extends android.os.Binder implements com.example.servicelearning.aidl.myService 10 { 11 private static final java.lang.String DESCRIPTOR = "com.example.servicelearning.aidl.myService"; 12 /** Construct the stub at attach it to the interface. */ 13 public Stub() 14 { 15 this.attachInterface(this, DESCRIPTOR); 16 } 17 /** 18 * Cast an IBinder object into an com.example.servicelearning.aidl.myService interface, 19 * generating a proxy if needed. 20 */ 21 public static com.example.servicelearning.aidl.myService asInterface(android.os.IBinder obj) 22 { 23 if ((obj==null)) { 24 return null; 25 } 26 android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR); 27 if (((iin!=null)&&(iin instanceof com.example.servicelearning.aidl.myService))) { 28 return ((com.example.servicelearning.aidl.myService)iin); 29 } 30 return new com.example.servicelearning.aidl.myService.Stub.Proxy(obj); 31 } 32 @Override public android.os.IBinder asBinder() 33 { 34 return this; 35 } 36 @Override public boolean onTransact(int code, android.os.Parcel data, android.os.Parcel reply, int flags) throws android.os.RemoteException 37 { 38 switch (code) 39 { 40 case INTERFACE_TRANSACTION: 41 { 42 reply.writeString(DESCRIPTOR); 43 return true; 44 } 45 case TRANSACTION_register: 46 { 47 data.enforceInterface(DESCRIPTOR); 48 this.register(); 49 reply.writeNoException(); 50 return true; 51 } 52 case TRANSACTION_get: 53 { 54 data.enforceInterface(DESCRIPTOR); 55 int _result = this.get(); 56 reply.writeNoException(); 57 reply.writeInt(_result); 58 return true; 59 } 60 } 61 return super.onTransact(code, data, reply, flags); 62 } 63 private static class Proxy implements com.example.servicelearning.aidl.myService 64 { 65 private android.os.IBinder mRemote; 66 Proxy(android.os.IBinder remote) 67 { 68 mRemote = remote; 69 } 70 @Override public android.os.IBinder asBinder() 71 { 72 return mRemote; 73 } 74 public java.lang.String getInterfaceDescriptor() 75 { 76 return DESCRIPTOR; 77 } 78 @Override public void register() throws android.os.RemoteException 79 { 80 android.os.Parcel _data = android.os.Parcel.obtain(); 81 android.os.Parcel _reply = android.os.Parcel.obtain(); 82 try { 83 _data.writeInterfaceToken(DESCRIPTOR); 84 mRemote.transact(Stub.TRANSACTION_register, _data, _reply, 0); 85 _reply.readException(); 86 } 87 finally { 88 _reply.recycle(); 89 _data.recycle(); 90 } 91 } 92 @Override public int get() throws android.os.RemoteException 93 { 94 android.os.Parcel _data = android.os.Parcel.obtain(); 95 android.os.Parcel _reply = android.os.Parcel.obtain(); 96 int _result; 97 try { 98 _data.writeInterfaceToken(DESCRIPTOR); 99 mRemote.transact(Stub.TRANSACTION_get, _data, _reply, 0);100 _reply.readException();101 _result = _reply.readInt();102 }103 finally {104 _reply.recycle();105 _data.recycle();106 }107 return _result;108 }109 }110 static final int TRANSACTION_register = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0);111 static final int TRANSACTION_get = (android.os.IBinder.FIRST_CALL_TRANSACTION + 1);112 }113 public void register() throws android.os.RemoteException;114 public int get() throws android.os.RemoteException;115 }
点击按钮之后,启动Service,(启动Service时,Intent必须是显性的),onServiceConnected()方法的回调的Ibinder方法,通过myService.Stub.asInterface()方法获取到myService对象,通过此对象可以调用对端Service的方法,具体可以通过Log看到。
1 01-06 08:07:30.385 30401 30401 D MainActivityLog.TAG: onClick2 01-06 08:07:30.450 30442 30442 D BindServiceTestLog.TAG: onBind3 01-06 08:07:30.452 30401 30401 D MainActivityLog.TAG: ServiceTestHelp onServiceConnected4 01-06 08:07:30.453 30442 30462 D BindServiceTestLog.TAG: register from com.example.servicelearning5 01-06 08:07:30.454 30401 30401 D MainActivityLog.TAG: get = 10086
可以看到是在两个进程里面,也可以正常通信。
- [android]service中再启service
- android service
- Android Service
- android service
- Android Service
- Android service
- android service
- Android Service
- Android Service
- Android service
- Android:Service
- Android Service
- [Android] Service
- android service
- android service
- android service
- android service
- Android Service
- Android — 如何创建和修改 fragment 及相关注意事项
- Android Activity各启动模式的差异
- Swift基础(十)协议的委托代理
- 机器学习实战2:关联规则:议会投票+毒蘑菇
- [hihoCoder太阁最新面经算法竞赛8]B.Dice Possibility
- Android Service
- mappingResources、mappingLocations、mappingDirectoryLocations、mappingJarLocations
- 字符串-10010 Where’s Waldorf
- 最值求解,活动安排,部分背包问题
- C++的简单总结(复制构造函数,深拷贝,前拷贝,默认属性)
- ViewPager + Fragment 实现类微信界面
- 机器学习实战3:逻辑logistic回归:病马实例
- 基数(cardinality)排序算法
- Part3:关联容器(一)