Service 绑定

一、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完整生命周期:


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值