Service 详解
补充:在Activity 与Service中的循环线程并不会因为Activity 、Service的 销毁而终止。IntentService中同样也是
1、启动服务的两种方式:
startService 没有返回,用于播放音乐,下载文件
bingService 有返回,并且可以实现进程间交互。多个组件可以同时与一个Service 绑定,当且仅当所有绑定解除
Service is Destory
2、可以同时使用两种方式调用同一Service
3、在另外一个app中也可以访问Service, 如果不想让其他app访问可以设置android:exported=“false”,或者不设置Intent filter
其中exported属性优先度较高。
4、不管哪种方式启动Service都不会另开线程或者进程运行,而是需要自己另外自定线程。或者继承 IntentService
其中已经封装了一个HandlerThead类,我们只需要实现 onHandlerIntent 就可以了,另外IntentService 的一个
优点就是它会自动调用stopSelf 结束Service
5、两种启动方式的生命周期
startService:onCreate onStartCommand onDestory
bingService onCreate onBind() onUnbind onDestory
其中 onStartService 可以自己在Service 中调用 stopSelf ,或者在其他组件中调用stopService 结束
bindService 可以使用 unBindService 结束
6、前台服务(foreground Service):例如音乐播放器,有一个status notification 可以显示状态并且启动一个Activity
与播放器交互。设置前台服务的方法有: setForegrond/startForeground(int ,Notification) ,移出的方法是stopForeground
但是并不stop service,但是如果stop 一个Service ,前台服务也会被移除
7、service 的process属性 介绍(service默认是在本应用进程的主线程中)
1、android:process=":anyname" 创建一个本应用的私有独立进程。
2、android:process=".anyname" 创建一个全局的独立进程。anyname可以为任意字符串。(也可以为com.anyname)
bindService
1、如果要使用bindService 必须要实现onBind接口;否则可以不用处理,直接在onBind中返回null
2、只有第一次调用bindService的时候才调用onBind方法,其他的直接返回相同的IBinder ,而不会再次调用onBind。
如果没有使用startService ,当最后一个unBind时Service销毁。
3、如果client 与Service 实在同一个进程 可以 在Service 中实现 Binder 接口
否则需要在Service实现Messenger(最简单的实现IPC的方法),同时也可以在client实现Messenger 实现Servcie到client
的命令传递。
Messenger 在一个Thread中创建了一个request queue , 同一时间只能处理一个请求,如果需要同时处理多个请求需要使用
AIDL。(Messenger 也是基于AIDL的 )
public class LocalService extends Service { // Binder given to clients private final IBinder mBinder = new LocalBinder(); // Random number generator private final Random mGenerator = new Random(); /** * Class used for the client Binder. Because we know this service always * runs in the same process as its clients, we don't need to deal with IPC. */ public class LocalBinder extends Binder { LocalService getService() { // Return this instance of LocalService so clients can call public methods return LocalService.this; } } @Override public IBinder onBind(Intent intent) { return mBinder; } /** method for clients */ public int getRandomNumber() { return mGenerator.nextInt(100); } }
public class ServiceSampleActivity extends Activity { LocalService mService; boolean mBound = false; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); } protected void onStart() { super.onStart(); Intent intent = new Intent(this, LocalService.class); bindService(intent, mConnection, Context.BIND_AUTO_CREATE); } protected void onStop() { super.onStop(); if (mBound) { unbindService(mConnection); mBound = false; } } public void onButtonClick(View v) { if (mBound) { int num = mService.getRandomNumber(); Toast.makeText(this, "number: " + num, Toast.LENGTH_SHORT).show(); } } private ServiceConnection mConnection = new ServiceConnection() { public void onServiceConnected(ComponentName className, IBinder service) { LocalBinder binder = (LocalBinder) service; mService = binder.getService(); mBound = true; } public void onServiceDisconnected(ComponentName arg0) { mBound = false; } };
多进程的通信
public class MessengerService extends Service { static final int MSG_SAY_HELLO = 1; class IncomingHandler extends Handler { public void handleMessage(Message msg) { switch (msg.what) { case MSG_SAY_HELLO: Toast.makeText(getApplicationContext(), "hello!", Toast.LENGTH_SHORT).show(); break; default: super.handleMessage(msg); } } } final Messenger mMessenger = new Messenger(new IncomingHandler()); public IBinder onBind(Intent intent) { Toast.makeText(getApplicationContext(), "binding", Toast.LENGTH_SHORT).show(); return mMessenger.getBinder(); } } Messenger mService = null; boolean mBound; private ServiceConnection mConnection = new ServiceConnection() { public void onServiceConnected(ComponentName className, IBinder service) { Log.d("lpl" , "---------onService"); mService = new Messenger(service); mBound = true; } public void onServiceDisconnected(ComponentName className) { mService = null; mBound = false; } }; public void onButtonClick(View v) { if (!mBound) return; Message msg = Message.obtain(null, MessengerService.MSG_SAY_HELLO, 0, 0); try { mService.send(msg); } catch (RemoteException e) { e.printStackTrace(); } } protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); } protected void onStart() { super.onStart(); bindService(new Intent(this, MessengerService.class), mConnection, Context.BIND_AUTO_CREATE); } protected void onStop() { super.onStop(); if (mBound) { unbindService(mConnection); mBound = false; } }