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

Android Service 之绑定服务和AIDL

2017-02-12 19:39 411 查看
今天在这里给大家介绍Android 四大组件中service中的绑定模式onBind(),Activity和Service 之间可以绑定然后做到数据的交互,比如我做一个登录然后在服务中去进行判断,在这里演示一个简单点的Demo就是一个普通的登录:

布局如下,二个EditText和一个登录的Button:

<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/main_qqname_edit"
android:hint="请输入用户名/QQ/电话号码"/>
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/main_qqpwd_edit"
android:hint="请输入密码"/>
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:onClick="login"
android:text="登录"/>
在MainActivity中拿到几个控件然后获取值,再进行与服务之间的绑定

private EditText main_qqname_edit;
private EditText main_qqpwd_edit;
private Intent intent;
private QQLoginInterface qqLoginInterface;
private QQLoginInterfaceOut qqLoginInterfaceOut;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//用户名的控件
main_qqname_edit = (EditText) findViewById(R.id.main_qqname_edit);
//密码的控件
main_qqpwd_edit = (EditText) findViewById(R.id.main_qqpwd_edit);
//绑定服务需要的Intent
intent = new Intent(this,QQLoginServices.class);
}
//服务需要的ServiceConnection
ServiceConnection connection=new ServiceConnection() {
//绑定服务成功会调用的方法
@Override
public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
qqLoginInterface = (QQLoginInterface) iBinder;

// qqLoginInterfaceOut = QQLoginInterfaceOut.Stub.asInterface(iBinder);
}
//绑定服务失败会调用的方法
@Override
public void onServiceDisconnected(ComponentName componentName) {

}
};
//进行交互时绑定服务
@Override
protected void onResume() {
super.onResume();
//绑定服务
bindService(intent,connection, Service.BIND_AUTO_CREATE);
}


具体的详解在注释中写清楚就不具体解释了,服务的类中内容如下,注释状态中的代码不予本次内容有关:
public class QQLoginServices extends Service {
//    class MyIBinder extends QQLoginInterfaceOut.Stub{
//
//        @Override
//        public boolean login(String qqname, String qqpwd) throws RemoteException {
//            if("100".equals(qqname)&&"123".equals(qqpwd)){
//                return true;
//            }
//            return false;
//        }
//    }

//onBind()方法中需要一个IBinder的返回类型值,所以我们在这里实例化一个IBinder的子类Binder然后继承一个接口来重写这个方法提高安全性
class MyIBinder extends Binder implements QQLoginInterface{

@Override
public boolean login(String qqname, String qqpwd) {
if("100".equals(qqname)&&"123".equals(qqpwd)){
return true;
}
return false;
}
}

//绑定服务时需要的生命周期:绑定
@Nullable
@Override
public IBinder onBind(Intent intent) {
return new MyIBinder();
}
}
在点击按钮的时候进行如下操作:

//点击按钮的方法
public void login(View view){
String qqname=main_qqname_edit.getText().toString();
String pwd=main_qqpwd_edit.getText().toString();
boolean flag=qqLoginInterface.login(qqname,pwd);
//  boolean flag= false;
// try {
//    flag = qqLoginInterfaceOut.login(qqname,pwd);
// } catch (RemoteException e) {
//     e.printStackTrace();
// }

Toast.makeText(this,""+flag,Toast.LENGTH_LONG).show();

}
这里的qqLoginInterface是我们之前绑定服务成功时里面的那个接口,然后拿到接口里面的登录方法把值给传回去,在清单文件中配置一下Service:

<service android:name=".QQLoginServices"
android:exported="true"
></service>
那么这里的Service中的绑定就这样了,要注意我们的绑定中的交互会放回Binder中写入方法的放回类型,如要需要改动可以自己更改类型。

好了,现在说一下AIDL ,Android接口语言,就是进程与进程之间的通信,比如demo1和demo2都可以使用一个登录的方法,那么就可以在demo2中去调用demo1的登录方法,就是提供一个接口你去调用。那么这里的布局就如上 只是多做一个demo,然后什么都不需要做很多的改变。

先创建一个AIDL,在Android studio中右击可以new 一个AIDL 然后输入一个名字,会产生一个AIDL的文件,并且会产生一个相对应的java文件。

在AIDL文件中吧我们接口中的方法放进去也就是如下:

interface QQLoginInterfaceOut {
boolean login(String qqname,String qqpwd);

}
在服务类中需要更改由我们的AIDL作为IBinder返回,代码如下:

class MyIBinder extends QQLoginInterfaceOut.Stub{

@Override
public boolean login(String qqname, String qqpwd) throws RemoteException {
if("100".equals(qqname)&&"123".equals(qqpwd)){
return true;
}
return false;
}
}
直接继承我们的AIDL类点出其中的Stub就可以,然后在MainActivity中不需要我们之前的那个接口来接收了,由我们的AIDL来接收,需要更改的代码如下:

//服务需要的ServiceConnection
ServiceConnection connection=new ServiceConnection() {
//绑定服务成功会调用的方法
@Override
public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
//qqLoginInterface = (QQLoginInterface) iBinder;

qqLoginInterfaceOut = QQLoginInterfaceOut.Stub.asInterface(iBinder);
}
//绑定服务失败会调用的方法
@Override
public void onServiceDisconnected(ComponentName componentName) {

}
};


在点击事件中直接用qqLoginInterfaceOut点出其中的方法就可以。第一个demo就是这样,和上面介绍的在这里看不出什么变化,但是在第二个demo中我们可以直接访问这里的服务传回来值在这里做判断了,

第二个demo中布局什么的和上面的demo一样,只说一下需要改变的地方,首先把demo1中由AIDL产生的接口类同包名和类名Copy到与MainActivity的包同级目录下,

MainActivity下的需要更改的代码如下:

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
main_qqname_edit = (EditText) findViewById(R.id.main_qqname_edit);
main_qqpwd_edit = (EditText) findViewById(R.id.main_qqpwd_edit);
intent = new Intent();
ComponentName componentName=new ComponentName("com.example.android_services_bind_aidl","com.example.android_services_bind_aidl.QQLoginServices");
intent.setComponent(componentName);
}
ServiceConnection connection=new ServiceConnection() {

@Override
public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
//  qqLoginInterface = (QQLoginInterface) iBinder;

qqLoginInterfaceOut = QQLoginInterfaceOut.Stub.asInterface(iBinder);
}

@Override
public void onServiceDisconnected(ComponentName componentName) {

}
};


重点是Intent跳转通过ComponentName来进行跳转到demo1,ComponentName第一个参数是包名,第二个是包名加类名。

然后就可以轻松访问到demo1中的那个服务了。

今天的分享就到这了,可能有些地方说的不清楚,但是在demo1中代码中的注释希望大家看下可能可以帮助到。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐