最近在学习AIDL,实现了一个调用第三方登录的功能
主要就是两个APP MyApplication和AIDLServerApplication,MyApplication是客户端,AIDLServerApplication是服务端。客户端就是一个按钮,点击跳转到服务端那边进行登录操作,登录完成给客户端发送一个消息,告知登录成功,登录失败也会告知一个回调
下面是效果图:
客户端:
服务端:
服务端的代码:
interface ILoginAidlInterface {
//登录
void login(String name,String pwd);
//登录的回调
void loginCallback(boolean isSuccess,String username);
}
2、然后build一下,会生成对应的Java文件
3、注册服务端的服务
/**
* 远程调用
*/
public class LoginService extends Service {
public LoginService() {
}
@Override
public void onCreate() {
super.onCreate();
Log.e("firstActivity","service create");
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.e("firstActivity","service onStartCommand");
return super.onStartCommand(intent, flags, startId);
}
@Override
public IBinder onBind(Intent intent) {
Log.e("firstActivity","service bind");
return stub;
}
ILoginAidlInterface.Stub stub = new ILoginAidlInterface.Stub() {
@Override
public void login(String name, String pwd) throws RemoteException {
Log.e("firstActivity","service login");
Intent intent = new Intent(getApplicationContext(),FirstActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
getApplication().startActivity(intent);
}
@Override
public void loginCallback(boolean isSuccess, String username) throws RemoteException {
}
};
}
还需要在manifest中注册
<service
android:name=".LoginService"
android:enabled="true"
android:exported="true" >
<intent-filter>
<action android:name="com.example.aidlservice"/>
</intent-filter>
</service>
4、服务端的登录界面和登录成功的回调
public class FirstActivity extends AppCompatActivity {
private boolean isSuccess;
private String userName;
//创建连接,方便复用
private ILoginAidlInterface iLogin;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_first);
createLoginBackService();
findViewById(R.id.tv_login).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String name = ((EditText) findViewById(R.id.et_name)).getText().toString();
userName = name;
String pwd = ((EditText) findViewById(R.id.et_pwd)).getText().toString();
if ("123".equals(pwd) && "123".equals(pwd)) {
isSuccess = true;
FirstActivity.this.finish();//登录成功将当前activity关闭
} else {
isSuccess = false;
}
try {
iLogin.loginCallback(isSuccess, userName);//登录后的结果回调
} catch (RemoteException e) {
e.printStackTrace();
}
}
});
}
private void createLoginBackService(){
Intent intent = new Intent();
intent.setPackage("com.example.a18045442.myapplication");//必须是manifest中注册的包名,不需要子包名
intent.setAction("com.example.myservice");
getApplicationContext().bindService(intent, conn, Context.BIND_AUTO_CREATE);
}
ServiceConnection conn = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
Log.e("firstActivity", "service connected");
iLogin = ILoginAidlInterface.Stub.asInterface(service);
}
@Override
public void onServiceDisconnected(ComponentName name) {
Log.e("firstActivity", "service disconnected");
}
};
}
以上服务端的代码就写完了
5、将服务端的aidl整个包复制到客户端的main目录下
copy完之后,也需要build一下,然后生成对应的Java文件
6、写客户端的启动服务的代码
public class Main3Activity extends AppCompatActivity {
private ILoginAidlInterface iLogin; //方便复用
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main3);
initService();
findViewById(R.id.aidl).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Log.e("MainActivity", "service onclick");
try {
if (iLogin != null) { //判断之前是否连接过
iLogin.login("123", "123");
}
} catch (RemoteException e) {
e.printStackTrace();
}
}
});
}
private void initService() {
Intent intent = new Intent();
intent.setPackage("com.example.aidlserverapplication");//必须是manifest中注册的包名,不需要子包名
intent.setAction("com.example.aidlservice");
getApplicationContext().bindService(intent, conn, Context.BIND_AUTO_CREATE);
}
ServiceConnection conn = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
Log.e("MainActivity", "service connected");
iLogin = ILoginAidlInterface.Stub.asInterface(service);
}
@Override
public void onServiceDisconnected(ComponentName name) {
Log.e("MainActivity", "service disconnected");
}
};
}
上面的布局文件就不需要写了,就是一个简单的登录页面,两个edittext和一个button
7、注册服务,方便接收登录的回调结果
/**
* 接收登录返回的服务
*/
public class LoginCallbackService extends Service {
@Override
public void onCreate() {
// TODO Auto-generated method stub
Log.e("mainActivity","service onCreate");
super.onCreate();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.e("mainActivity","service onStartCommand");
return super.onStartCommand(intent, flags, startId);
}
@Override
public IBinder onBind(Intent intent) {
Log.e("mainActivity","service bind");
return stub;
}
ILoginAidlInterface.Stub stub = new ILoginAidlInterface.Stub() {
@Override
public void login(String name, String pwd) throws RemoteException {
}
@Override
public void loginCallback(boolean isSuccess, String username) throws RemoteException {
Log.e("mainActivity","service login");
if (isSuccess) { // 当前什么都没有操作,只是打印log出来
// Intent intent = new Intent(getApplicationContext(), FirstActivity.class);
// intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
// getApplication().startActivity(intent);
Log.e("mainActivity","service login success");
}else {
Log.e("mainActivity","service login fail");
}
}
};
}
在manifest中注册
<service
android:name=".service.LoginCallbackService"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="com.example.myservice" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</service>
上面的布局文件就不需要写了,就是一个按钮
这样两边代码都写好了,先安装服务端的app,然后安装客户端的app,这样才能保证能够调起
最后运行的结果:
客户端的四个提示标识:先是登录失败给的提示,后面是登录成功给的提示
TIPS:我在写Demo的时候遇到个问题,用meizu3的5.1系统真机一直有问题,服务端一直调用不起来,换用8.0系统的模拟器之后就可以了,所以可能有的手机启动服务有问题,还需要研究一下。