您的位置:首页 > 移动开发 > Android开发

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

2017-06-18 14:19 881 查看

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这个方法不会被执行。

绑定服务,在系统的设置里头的应用列表用不到。

绑定的服务会跟绑定者的生命周期一样结束。

服务只可解除绑定一次,否则多次进行解绑的话,就会崩掉啦!

绑定的回调要跟解绑的回调一一对应。

网易云视频:





社区网站:



内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
相关文章推荐