Android服务Service详解(作用,生命周期,AIDL)系列文章--服务绑定和开启混合使用

来源:互联网 发布:淘宝卖家的钱在哪儿看 编辑:程序博客网 时间:2024/05/01 00:22
前面我们知道 了服务的开始方式有两种,一种是直接通过startService来开启,另外一种是通过bindService来开启服务。
这两种方式,各有种的优缺点。


比如说:startService的话,优点,可以长期运行着服务;缺点,没办跟服务进行通讯。
而bindService的话则是生命周期跟随绑定者一起结束,优点 是可以跟服务进行通讯。


那么我们需要达到既可以长期运行,又可以进行通讯怎么办呢?很简单,两种开启方式混合使用即可!

其实,这才是服务真正的生命周期呢!

假如我们的开启方式是:startService()----->stopService()
那么它的生命周期是这样子的:onCreate()----->onStartCommand----->onDestroy()
假如我们的开启方式是:bindService()------>unbindService()
那么它的生命周期是这样子的:onCreate()-----> onBind()----->onUnbind()---->onDestroy

我们先上代码,这次的话,我们只是添加多了一个按钮,调用服务内部方法的按钮而已。代码修改如下:布局文件代码:

<?xml version="1.0" encoding="utf-8"?><LinearLayout    xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:tools="http://schemas.android.com/tools"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:orientation="vertical"    tools:context=".MainActivity">     <Button        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:onClick="start"        android:text="开启服务"/>     <Button        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:onClick="stop"        android:text="停止服务"/>     <Button        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:onClick="bind"        android:text="绑定服务"/>     <Button        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:onClick="unbind"        android:text="解绑服务"/>     <Button        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:onClick="call"        android:text="调用服务内部的方法"/> </LinearLayout>
MainActivity的代码:

package com.sunofbeaches.servicetestdemo; import android.content.ComponentName;import android.content.Intent;import android.content.ServiceConnection;import android.os.Bundle;import android.os.IBinder;import android.support.v7.app.AppCompatActivity;import android.util.Log;import android.view.View; public class MainActivity extends AppCompatActivity {     private static final String TAG = "MainActivity";    private IProxyInterface mRemoteServiceBinder;     @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);     }     /**     * 开始服务     *     * @param view     */    public void start(View view) {        Intent intent = new Intent(this, SOBTestService.class);        startService(intent);    }     /**     * 停止服务     *     * @param view     */    public void stop(View view) {        Intent intent = new Intent(this, SOBTestService.class);        stopService(intent);    }      /**     * 绑定服务     *     * @param view     */    public void bind(View view) {        Log.d(TAG, "点击绑定服务按钮..");         Intent intent = new Intent(this, SOBTestService.class);         /**         * 这里面需要三个参数,第一个是意图对象,第二个是回调,第三个是创建模式。         */        bindService(intent, mConnection, BIND_AUTO_CREATE);    }     private ServiceConnection mConnection = new ServiceConnection() {        @Override        public void onServiceConnected(ComponentName name, IBinder service) {            //这里呢,则是绑定上了,那到我们输出它的名字,然后调用它的方法即可。            Log.d(TAG, "services name == " + name);             if (service instanceof IProxyInterface) {                //调用内部方法                mRemoteServiceBinder = (IProxyInterface) service;            } else {                throw new RuntimeException("服务的内部代理方法没有实现IProxyInterface借口");            }         }         @Override        public void onServiceDisconnected(ComponentName name) {            Log.d(TAG, "服务断开连接....");        }    };     /**     * 解除服务绑定...     */    public void unbind(View view) {        Log.d(TAG, "点击了解绑服务按钮..");        unbindService(mConnection);    }     public void call(View view) {        Log.d(TAG, "调用服务内部的方法..");        mRemoteServiceBinder.callInnerMethod();    } }
接口的代码:

package com.sunofbeaches.servicetestdemo; /** * Created by TrillGates on 17/4/16. * God bless my code! */public interface IProxyInterface {    void callInnerMethod();}
服务的代码:
package com.sunofbeaches.servicetestdemo; import android.app.Service;import android.content.Intent;import android.os.Binder;import android.os.IBinder;import android.support.annotation.Nullable;import android.util.Log; /** * Created by TrillGates on 17/4/15. * God bless my code! */public class SOBTestService extends Service {     private static final String TAG = "SOBTestService";      //继承自Binder,其实Binder就是IBinder的一个子类嘛。    private class CommunicationBinder extends Binder  implements IProxyInterface{         //这个方法供外部调用,用于调用内部的方法。        @Override        public void callInnerMethod() {            //调用内部的方法            innerMethod();        }     }      @Nullable    @Override    public IBinder onBind(Intent intent) {        //绑定以后,反回CommunicationBinder        return new CommunicationBinder();    }     @Override    public void onCreate() {        super.onCreate();        Log.d(TAG, "服务被创建了....");    }     @Override    public int onStartCommand(Intent intent, int flags, int startId) {        Log.d(TAG, "执行了 onStartCommand...");        return super.onStartCommand(intent, flags, startId);    }     @Override    public boolean onUnbind(Intent intent) {        Log.d(TAG, "执行了onBind方法...");        return super.onUnbind(intent);    }     @Override    public void onDestroy() {        super.onDestroy();        Log.d(TAG, "服务被销毁了....");    }     private void innerMethod() {        Log.d(TAG, "我是服务内部的方法被调用啦...");    }}
接着,我们把程序跑起来,就是这个样子的啦:



于是,我们开心地执行以下操作:

  • 点击开启服务
  • 点击开启服务
  • 点击绑定服务
  • 点击停止服务

我们发现,第一次点击开启服务,则执行了onCreate方法和startCommand方法
第二次点击开启服务,则执行了startCommand方法
点击绑定服务,执行了onBind方法
点击停止服务,则没有反应


结论:如果服务被绑定了,并且没有解绑的话,服务是无活停止的。


接着,我们做以下操作:

  • 开启服务
  • 绑定服务
  • 解绑服务



点击了开启服务,则执行了onCreate方法以及onStartCommand方法
点击了绑定服务,执行了onBind方法
点击了解绑服务,执行了unBind

结论:如果使用startService来开启服务,那么对应的unBind方法则不会停止服务。除非你stopService,这样子服务才会停止。
根据服务中的需求,既要长期运行,又要可以和服务进行通讯,那么推荐的做法如下:
startService()----->bindService()------->communication--------->unBinderService()------->stopService()
按这个套路的话,就可以达到我们目的啦!是不是很简单呢!


网易云视频:



社区网站:



阅读全文
1 0