首页 > 程序开发 > 移动开发 > Android >

Android服务Service详解(作用,生命周期,AIDL)系列文章--进一步封装绑定服务(私有化代理类)

2017-06-19

Android服务Service详解(作用,生命周期,AIDL)系列文章--进一步封装绑定服务(私有化代理类)。

Android服务Service详解(作用,生命周期,AIDL)系列文章--进一步封装绑定服务(私有化代理类)

前面文章我们讲了服务的绑定,那么接下来,我们就看看对服务绑定再进一步的封装,把这个代理类私有化,为我们后面的跨进程通讯做准备!

前面,我们代码中,创建了个CommnunicationBinder,其实这个呢是一个内部的代理类。以前是Public的,所以在调里可以直接使用。
那么现在我们改成私有的,如下:

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 {
 
        //这个方法供外部调用,用于调用内部的方法。
        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 void onDestroy() {
        super.onDestroy();
        Log.d(TAG, "服务被销毁了....");
    }
 
    private void innerMethod() {
        Log.d(TAG, "我是服务内部的方法被调用啦...");
    }
}

改成私有的以后,MainActivity里就没法使用了,对吧!如图:

\

那怎么样才可以使用呢?其实呀,很简单,既然它内部private了,也就是不想让外部知道。我们小时候就知道,外部要知道里面的方法怎么办呢?当然是实现特定的接口啦!

所以,我们只要写一个接口,里面有一个方法是调用内部方法的,这样子。 我们就可以直接通过接口来调用啦!

好的,看码,第一步,写一个接口:

package com.sunofbeaches.servicetestdemo;
 
/**
 * Created by TrillGates on 17/4/16.
 * God bless my code!
 */
public interface IProxyInterface {
    void callInnerMethod();
}
话不多说,是吧,就那么一行代码,调用内部方法。
第二步:内部的私有CommunicationBinder要实现这个接口,如下:
//继承自Binder,其实Binder就是IBinder的一个子类嘛。
private class CommunicationBinder extends Binder  implements IProxyInterface{
 
    //这个方法供外部调用,用于调用内部的方法。
    @Override
    public void callInnerMethod() {
        //调用内部的方法
        innerMethod();
    }
 
}
然后, 我们的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";
 
    @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) {
                //调用内部方法
                ((IProxyInterface) service).callInnerMethod();
            } else {
                throw new RuntimeException("服务的内部代理方法没有实现IProxyInterface借口");
            }
 
        }
 
        @Override
        public void onServiceDisconnected(ComponentName name) {
            Log.d(TAG, "服务断开连接....");
        }
    };
 
    /**
     * 解除服务绑定...
     */
    public void unbind(View view) {
        Log.d(TAG, "点击了解绑服务按钮..");
        unbindService(mConnection);
    }
 
}

最后,我们把代码跑起来,点击绑定服务:

\

和前面我们做的效果一样吧,也是成功地调用了内部的方法了!
PS:最后的话,传授一些小时候的经验给大家:

  • 如果服务中的onBind方法,返回值为null的话,那么onServiceConnect这个方法不会被执行。
  • 绑定服务,在系统的设置里头的应用列表用不到。
  • 绑定的服务会跟绑定者的生命周期一样结束。
  • 服务只可解除绑定一次,否则多次进行解绑的话,就会崩掉啦!
  • 绑定的回调要跟解绑的回调一一对应。

相关文章
最新文章
热点推荐