1.何为远程监控:
对于远程监控我们的第一反应就是通过这台手机控制别的手机,但是在Android中实际意思为一台手机中的多个应用程序通用一个服务端。当每个应用都需要用到相同的功能时,我们就不需要多次写相同的操作了,这个时候我们就可以通过远程监控把同样的功能提取出来,其它应用需要时就可以绑定到远程服务中了,比如QQ登录,它不仅可以在QQ中登录,你的微信也可以通过QQ登录,还有像斗地主等等都可以实现与QQ连接,我们把这种操作称为远程监控。
Android采用了远程过程调用的方式来实现的, 远程过程的调用(Remote Procedure Call 简称RPC),它通过网络从远程计算机程序上请求服务。Android采用了一种接口自定义的语言(Interface Definition Language,IDL)来公开服务的接口。因此我们把它称为AIDL(Android Interface Definition Language),下面我们就来实现QQ端和微信端登录接口的操作。
2.如何实现远程监控:
2.1:应用程序的绑定:
首先我们应该先把登录界面先实现了
<EditText android:layout_width="match_parent" android:layout_height="wrap_content" android:hint="请输入用户名" android:id="@+id/et_main_qqname" /> <EditText android:layout_width="match_parent" android:layout_height="wrap_content" android:hint="请输入密码" android:id="@+id/et_main_qqpwd" android:inputType="numberPassword" /> <Button android:layout_width="match_parent" android:layout_height="wrap_content" android:text="登录" androi
d:onClick="login" />
然后在获取控件的值,这个就不用显示代码了,通过id获取就可以了。
1.接下来我们需要的是定义一个接口,声明你需要提供的方法,
2.然后在写一个服务类继承Service,它需要重写一个onBind()方法在方法中我们需要返回值,这个值从哪里来呢?
3.这时我们就需要在方法外面写个继承Binder(IBinder的子类)的方法来实现你写的接口,在这个方法中就像写dao方法一样把你需要的业务方法写进去就可以。
4.Activity中调用bandService()绑定服务,传递一个ServiceConnection用来接收onBind()方法返回过来的值,强转为接口类型,即可调用方法。
代码如下:
public interface QQLoginInterface { //接口类 public boolean login(String qqname,String qqpwd); }
public class QQLoginService extends Service { //服务类class MyBinder extends Binder implements QQLoginInterface{ //登录方法 public boolean login(String qqname,String qqpwd){ //判断输入的值与实际值 if("admin".equals(qqname) && "123".equals(qqpwd)){ return true; }else{ return false; } } }@Nullable @Override public IBinder onBind(Intent intent) { Toast.makeText(this, "绑定了", Toast.LENGTH_SHORT).show(); return new MyBinder(); }}
public class MainActivity extends AppCompatActivity { private EditText et_main_qqname; private EditText et_main_qqpwd; private Intent intent; private QQLoginService.MyBinder myBinder; private QQLoginInterface qqlogininterface; private QQLoginInterAidl qqLoginInterAidl; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); initView(); intent = new Intent(this,QQLoginService.class); } private void initView() { //获取输入框控件 et_main_qqname = (EditText) findViewById(R.id.et_main_qqname); et_main_qqpwd = (EditText) findViewById(R.id.et_main_qqpwd); } //连接服务 ServiceConnection serviceConnection=new ServiceConnection() { @Override public void onServiceConnected(ComponentName componentName, IBinder iBinder) { Toast.makeText(MainActivity.this, "连接上了", Toast.LENGTH_SHORT).show(); //调用服务类 //调用接口类 qqlogininterface = (QQLoginInterface) iBinder; } @Override public void onServiceDisconnected(ComponentName componentName) { } }; @Override protected void onResume() { super.onResume(); //绑定服务 bindService(intent,serviceConnection, Service.BIND_AUTO_CREATE); } @Override protected void onDestroy() { super.onDestroy(); //解绑服务 unbindService(serviceConnection); } public void login(View view){ //获取值 String qqname=et_main_qqname.getText().toString(); String qqpwd=et_main_qqpwd.getText().toString(); //调用方法 boolean b= false; try { b = qqlogininterface.login(qqname,qqpwd); Toast.makeText(this, ""+b, Toast.LENGTH_SHORT).show(); } catch (RemoteException e) { e.printStackTrace(); } } }
当你把这些方法写完时你的QQ端登录方也就完成了,下面就要把QQ端和微信端联系起来了
注意:记得要配置好服务类<service android:name=".QQLoginService" android:enabled="true" android:exported="true" ></service>
服务端:(在QQ端项目里面)
1.在Android工程的java包目录中建立一个扩展名为aidl的文件中建立一个类(在上面已经说过了adil是什么),语法与java接口的语法类似
interface QQLoginInterAidl { boolean login(String qqname,String qqpwd); }当你建好后点击Build中的Make Modulw重新编译一下它会自动生成一个QQLoginInterAidl.java的文件,这个文件是自动生成的它不需要我们去修改。
2.然后把最开始我们写的服务端中实现接口改为 extends QQLoginInterAidl.Stub并重写里面的方法,其它方法的代码我们就不需要改了,然后就是在Activity里面重新写下调用的方法
把连接服务的代码改为qqLoginInterAidl = QQLoginInterAidl.Stub.asInterface(iBinder);在调用点击事件时把相对应的应用改为 qqLoginInterAidl 就可以了。客服端:
1.我们要把服务端中aidl中自动生成的文件导入微信端项目中(你把Android转换为project,在你的项目中找到build/generated/source/aidl/debug,然后复制自动生成的那个接口类就可以了),在java中建一个包,包名为QQ端的包名(如果你找不到的话可以去QQ端的配置文件中有一个package属性,把里面的值复制过去就可以了),然后再把文件复制进来就可以了
2.在Activity中,绑定服务、调用服务、解除绑定就可以了
public class MainActivity extends AppCompatActivity { private Intent intent; private QQLoginInterAidl qqLoginInterAidl; private EditText et_main_qqname; private EditText et_main_qqpwd; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); //实例化绑定需要的参数 intent = new Intent(); ComponentName componentName=new ComponentName("com.example.g160828_android21_qq","com.example.g160828_android21_qq.QQLoginService"); intent.setComponent(componentName); //初始化 initView(); } private void initView() { //得到控件 et_main_qqname = (EditText) findViewById(R.id.et_main_qqname); et_main_qqpwd = (EditText) findViewById(R.id.et_main_qqpwd); } ServiceConnection serviceConnection=new ServiceConnection() { //连接 @Override public void onServiceConnected(ComponentName componentName, IBinder iBinder) { qqLoginInterAidl = QQLoginInterAidl.Stub.asInterface(iBinder); } @Override public void onServiceDisconnected(ComponentName componentName) { } }; @Override protected void onResume() { //绑定 super.onResume(); bindService(intent,serviceConnection, Service.BIND_AUTO_CREATE); } @Override protected void onDestroy() { //解除绑定 super.onDestroy(); unbindService(serviceConnection); } public void login(View view){ //调用方法 String qqname=et_main_qqname.getText().toString(); String qqpwd=et_main_qqpwd.getText().toString(); try { boolean b=qqLoginInterAidl.login(qqname,qqpwd); Toast.makeText(this, ""+b, Toast.LENGTH_SHORT).show(); } catch (RemoteException e) { e.printStackTrace(); } } }