Service 绑定

    xiaoxiao2021-12-14  21

    一、Activity之间协调: 1.当在同一个进程中从一个Activity开启另一个Activity时,它们的生命周期方法是这样的: A Activity 开启了 B Activity: A调用onPause(),B调用onCreate(),onStart(),onResume(),此时B Activity与用户进行交互, 然后A Activity的onStop()方法调用,所以如果两个界面共享一些数据,如存储在数据库 中的数据,则应该在A Activity的onPause()方法中保存数据,而不是onStop()方法。 2.横竖屏切换 当用户旋转屏幕,切换屏幕状态时,会创建新的Activity实例。 二、Service的onStartCommand()方法返回值 1.一个服务的onStartCommand()方法必须返回一个整数值,这个整数值描述了在系统因为内存等问题杀死 该服务后,该服务在系统获得了可用内存等资源如何继续该服务,返回值必须为以下其中之一: a.START_NOT_STICKY:不要重新创建该服务,除非有意图重新开启该服务; b.START_STICKY:用一个空的意图重新创建该服务,如果有新的意图,则用新的意图开启,适用于媒体播放器等逻辑; c.START_REDELIVER_INTENT:用上一次开启该服务的意图重启该服务,也就是继续进行上次未完成的任务, 适用于文件下载,上传等逻辑。 2.运行一个前台服务: 前台服务是用户主动意识到的一种服务,因此在内存不足时,系统也不会考虑将其终止。 前台服务必须为状态栏 提供通知,放在“正在进行”标题下方,这意味着除非服务停止或从前台移除,否则不能清除通知。 要让服务运行与前台,需调用startForeground()方法,接收两个参数,一个是通知的唯一标志性ID,一个是

    notification对象,如:

    Notification notification = new Notification(R.drawable.icon, getText(R.string.ticker_text), System.currentTimeMillis()); Intent notificationIntent = new Intent(this, ExampleActivity.class); PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0); notification.setLatestEventInfo(this, getText(R.string.notification_title), getText(R.string.notification_message), pendingIntent); startForeground(ONGOING_NOTIFICATION_ID, notification); 注:ID值不能为0; 要从前台移除服务,请调用 stopForeground()。此方法接收一个布尔值,指示是否也移除状态栏通知。 此方法不会停止 服务。 但是,如果在服务正在前台运行时将其停止,则通知也会被移除。 3.定义可绑定的服务: a.定义和客户(client)交互的接口有三种方式,分别是: (1)继承Binder类,适用于此服务为应用进程所私有,且client跟该服务处于同一应用进程中; 实现步骤:服务中定义一个类继承Binder类,在服务的onBind()方法中返回一个自定义Binder实例对象,client在 onServiceConnected()方法中获取该对象; (2)使用Messager类提供跨进程绑定服务: 实现步骤: 服务实现一个 Handler,由其接收来自client的每个调用的回调, Handler 用于创建 Messenger 对象(对 Handler 的引用), Messenger 创建一个 IBinder,服务通过 onBind() 使其返回client, client使用 IBinder 将 Messenger(引用服务的 Handler)实例化,然后使用后者将 Message 对象发送给服务, 服务在其 Handler 中(具体地讲,是在 handleMessage() 方法中)接收每个 Message。 这样,client并没有调用服务的“方法”。而client传递的“消息”(Message 对象)是服务在其 Handler 中接收的。 如:

    service: public class MessengerService extends Service { /** Command to the service to display a message */ static final int MSG_SAY_HELLO = 1; /** * Handler of incoming messages from clients. */ class IncomingHandler extends Handler { @Override 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); } } } /** * Target we publish for clients to send messages to IncomingHandler. */ final Messenger mMessenger = new Messenger(new IncomingHandler()); /** * When binding to the service, we return an interface to our messenger * for sending messages to the service. */ @Override public IBinder onBind(Intent intent) { Toast.makeText(getApplicationContext(), "binding", Toast.LENGTH_SHORT).show(); return mMessenger.getBinder(); } } Activity: public class ActivityMessenger extends Activity { /** Messenger for communicating with the service. */ Messenger mService = null; /** Flag indicating whether we have called bind on the service. */ boolean mBound; /** * Class for interacting with the main interface of the service. */ private ServiceConnection mConnection = new ServiceConnection() { public void onServiceConnected(ComponentName className, 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. mService = new Messenger(service); mBound = true; } public void onServiceDisconnected(ComponentName className) { // This is called when the connection with the service has been // unexpectedly disconnected -- that is, its process crashed. mService = null; mBound = false; } }; public void sayHello(View v) { if (!mBound) return; // Create and send a message to the service, using a supported 'what' value Message msg = Message.obtain(null, MessengerService.MSG_SAY_HELLO, 0, 0); try { mService.send(msg); } catch (RemoteException e) { e.printStackTrace(); } } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); } @Override protected void onStart() { super.onStart(); // Bind to the service bindService(new Intent(this, MessengerService.class), mConnection, Context.BIND_AUTO_CREATE); } @Override protected void onStop() { super.onStop(); // Unbind from the service if (mBound) { unbindService(mConnection); mBound = false; } } }(3)AIDL,有待后续拓展

    4.客户端(client)绑定服务: client调用bindService()方法,然后服务会调用onBind()方法返回IBinder对象,但是因为 这个绑定过程是异步的,bindService()调用后立即结束并不会返回IBinder()对象,因此需要一个ServiceConnection实例, 这个借口提供onServiceConnected()和onServiceDisconnected()回调方法,当服务已经绑定时会调用onServiceConnected()方法, 并获得IBinder实例对象;当服务崩溃或者被系统杀死时onServiceDisconnected()方法调用,而不是用户调用unbindService()时调用。 如:

    LocalService mService; private ServiceConnection mConnection = new ServiceConnection() { // Called when the connection with the service is established public void onServiceConnected(ComponentName className, IBinder service) { // Because we have bound to an explicit // service that is running in our own process, we can // cast its IBinder to a concrete class and directly access it. LocalBinder binder = (LocalBinder) service; mService = binder.getService(); mBound = true; } // Called when the connection with the service disconnects unexpectedly public void onServiceDisconnected(ComponentName className) { Log.e(TAG, "onServiceDisconnected"); mBound = false; } };绑定服务:

    Intent intent = new Intent(this, LocalService.class); bindService(intent, mConnection, Context.BIND_AUTO_CREATE); 5.bind service 生命周期:

    6.Service完整生命周期:

    转载请注明原文地址: https://ju.6miu.com/read-971682.html

    最新回复(0)