本地服务点这里本地服务(附Demo)
1.为什么要使用远程服务?
例如QQ 微信 都需要登录,QQ有自己的登录,微信也有自己的登录,我们可以把登录功能提取出来。
哪个程序需要使用就调用这个提取出来的部分,而这个部分就需要用到远程服务。今天实现的Demo是比较偏向于底层的做法可以把QQ看做服务器,微信看做客户端。
2.多进程间启动Services
Android 5.0 之后,启动其他应用程序的服务,不允许使用隐式
ComponentName componentName=new ComponentName(“cn.veryedu.android_services”,”cn.veryedu.android_services.MyServices”);
intent.setComponent(componentName);
3.远程服务实现步骤
- QQ登录最简单实现(原生态)
- 加入服务
- 使用接口实现
- AIDLAIDL详诉
- 客户端(调用QQ登录服务)
1.原生态
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" android:id="@+id/activity_main"
android:layout_width="match_parent" android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:orientation="vertical"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="com.example.zy_service02.MainActivity">
<EditText
android:id="@+id/et_main_number"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="admin" />
<EditText
android:id="@+id/et_main_pwd"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="123456" />
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="登录"
android:onClick="login"
/>
</LinearLayout>
MainActivity
public class MainActivity extends AppCompatActivity {
private EditText et_main_number;
private EditText et_main_pwd;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
et_main_number = (EditText) findViewById(R.id.et_main_number);
et_main_pwd = (EditText) findViewById(R.id.et_main_pwd);
}
public void login(View view){
String number=et_main_number.getText().toString();
String pwd=et_main_pwd.getText().toString();
boolean flag = false;
if("admin".equals(number)&&"123456".equals(pwd)){
flag = true;
}
Toast.makeText(this, ""+flag, Toast.LENGTH_SHORT).show();
}
2.加入服务
新建一个类继承自Service
QQLoginService
public class QQLoginService extends Service{
//类似 WEB 业务逻辑类
class MyIBinder extends Binder{
public boolean login(String number,String pwd){
if("admin".equals(number)&&"123456".equals(pwd)){
return true;
}
return false;
}
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
return new MyIBinder();
}
}
AndroidManifest.xml 在清单文件中配置
<service android:name=".QQLoginService"
android:exported="true"
></service>
MainActivity
public class MainActivity extends AppCompatActivity {
private EditText et_main_number;
private EditText et_main_pwd;
private Intent intent;
private QQLoginService.MyIBinder myIBinder;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
et_main_number = (EditText) findViewById(R.id.et_main_number);
et_main_pwd = (EditText) findViewById(R.id.et_main_pwd);
intent = new Intent(this,QQLoginService.class);
}
ServiceConnection connection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder iBinder) {
myIBinder = (QQLoginService.MyIBinder) iBinder;
}
@Override
public void onServiceDisconnected(ComponentName name) {
}
};
@Override
protected void onResume() {
super.onResume();
//绑定服务
bindService(intent,connection, Service.BIND_AUTO_CREATE);
}
public void login(View view){
String number=et_main_number.getText().toString();
String pwd=et_main_pwd.getText().toString();
boolean flag = qqLoginInterface.login(number,pwd);
Toast.makeText(this, ""+flag, Toast.LENGTH_SHORT).show();
}
}
3.使用接口
新建一个QQLoginInterface接口
public interface QQLoginInterface {
public boolean login(String number,String pwd);
}
QQLoginService
public class QQLoginService extends Service{
// //WEB 业务逻辑类
class MyIBinder extends Binder implements QQLoginInterface{
@Override
public boolean login(String number, String pwd) {
if("admin".equals(number)&&"123456".equals(pwd)){
return true;
}
return false;
}
// public boolean login(String number,String pwd){
// if("admin".equals(number)&&"123456".equals(pwd)){
// return true;
// }
//
// return false;
// }
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
return new MyIBinder();
}
}
MainActivity
public class MainActivity extends AppCompatActivity {
private EditText et_main_number;
private EditText et_main_pwd;
private Intent intent;
private QQLoginService.MyIBinder myIBinder;
private QQLoginInterface qqLoginInterface;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
et_main_number = (EditText) findViewById(R.id.et_main_number);
et_main_pwd = (EditText) findViewById(R.id.et_main_pwd);
intent = new Intent(this,QQLoginService.class);
}
ServiceConnection connection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder iBinder) {
//myIBinder = (QQLoginService.MyIBinder) iBinder;
qqLoginInterface = (QQLoginInterface) iBinder;
}
@Override
public void onServiceDisconnected(ComponentName name) {
}
};
@Override
protected void onResume() {
super.onResume();
//绑定服务
bindService(intent,connection, Service.BIND_AUTO_CREATE);
}
public void login(View view){
String number=et_main_number.getText().toString();
String pwd=et_main_pwd.getText().toString();
boolean flag = qqLoginInterface.login(number,pwd);
Toast.makeText(this, ""+flag, Toast.LENGTH_SHORT).show();
}
}
4.AIDL
AIDL 即 android interface define language 安卓接口定义语音,如果要实现经常间的通讯 就要使用到AIDL,接下来看如何实现的。
右击MainActivity所对应的包,找到AIDL,新建一个(该名字不能与刚刚新建的接口名字一样).aidl文件夹
QQLoginInterfaceOut.aidl
interface QQLoginInterfaceOut {
boolean login(String number,String pwd);
}
这里重新编译项目,然后切换到project在build下面的generated下面的 sourse 找到aidl 。
系统会自动帮你创建一个名为QQLoginInterfaceOut.java的类 注意不要去修改这个类的任何代码,如果其他应用程序需要使用到我们的应用,就需要这个类。
QQLoginService
public class QQLoginService extends Service{
class MyIBinder extends QQLoginInterfaceOut.Stub{
@Override
public boolean login(String number, String pwd) throws RemoteException {
if("admin".equals(number)&&"123456".equals(pwd)){
return true;
}
return false;
}
}
// //WEB 业务逻辑类
// class MyIBinder extends Binder implements QQLoginInterface{
// @Override
// public boolean login(String number, String pwd) {
// if("admin".equals(number)&&"123456".equals(pwd)){
// return true;
// }
//
// return false;
// }
// public boolean login(String number,String pwd){
// if("admin".equals(number)&&"123456".equals(pwd)){
// return true;
// }
//
// return false;
// }
//}
@Nullable
@Override
public IBinder onBind(Intent intent) {
return new MyIBinder();
}
}
MainActivity
public class MainActivity extends AppCompatActivity {
private EditText et_main_number;
private EditText et_main_pwd;
private Intent intent;
private QQLoginService.MyIBinder myIBinder;
private QQLoginInterface qqLoginInterface;
private QQLoginInterfaceOut qqLoginInterfaceOut;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
et_main_number = (EditText) findViewById(R.id.et_main_number);
et_main_pwd = (EditText) findViewById(R.id.et_main_pwd);
intent = new Intent(this,QQLoginService.class);
}
ServiceConnection connection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder iBinder) {
//myIBinder = (QQLoginService.MyIBinder) iBinder;
//qqLoginInterface = (QQLoginInterface) iBinder;
qqLoginInterfaceOut = QQLoginInterfaceOut.Stub.asInterface(iBinder);
}
@Override
public void onServiceDisconnected(ComponentName name) {
}
};
@Override
protected void onResume() {
super.onResume();
//绑定服务
bindService(intent,connection, Service.BIND_AUTO_CREATE);
}
public void login(View view){
String number=et_main_number.getText().toString();
String pwd=et_main_pwd.getText().toString();
// boolean flag = qqLoginInterface.login(number,pwd);
boolean flag = false;
try {
flag = qqLoginInterfaceOut.login(number,pwd);
} catch (RemoteException e) {
e.printStackTrace();
}
Toast.makeText(this, ""+flag, Toast.LENGTH_SHORT).show();
}
}
5.我们再来看客户端
1)重新新建一个项目
2)将QQ登录服务器这个项目切到project 将 系统为我们自动生成的QQLoginInterfaceOut.java的类连同包copy到新建的项目中(非常重要)。下面附代码
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" android:id="@+id/activity_main"
android:layout_width="match_parent" android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:orientation="vertical"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="com.example.zy_service02wx.MainActivity">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="WX"
android:textSize="30sp"
/>
<EditText
android:id="@+id/et_main_number"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="admin" />
<EditText
android:id="@+id/et_main_pwd"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="123456" />
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="登录"
android:onClick="login"
/>
</LinearLayout>
MainActivity
public class MainActivity extends AppCompatActivity {
private EditText et_main_number;
private EditText et_main_pwd;
private Intent intent;
private QQLoginInterfaceOut qqLoginInterfaceOut;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
et_main_number = (EditText) findViewById(R.id.et_main_number);
et_main_pwd = (EditText) findViewById(R.id.et_main_pwd);
intent = new Intent();
//多进程间服务的启动 com.example.zy_service02为qq登录服务器包名(将要启动应用程序的包名)
//com.example.zy_service02.QQLoginService 你要启动该应用程序下面的哪个类
ComponentName componentName = new ComponentName("com.example.zy_service02","com.example.zy_service02.QQLoginService");
intent.setComponent(componentName);
}
ServiceConnection serviceConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
qqLoginInterfaceOut = QQLoginInterfaceOut.Stub.asInterface(service);
}
@Override
public void onServiceDisconnected(ComponentName name) {
}
};
@Override
protected void onResume() {
super.onResume();
//绑定服务
bindService(intent,serviceConnection, Service.BIND_AUTO_CREATE);
}
public void login(View view){
String number = et_main_number.getText().toString();
String pwd= et_main_pwd.getText().toString();
boolean flag=false;
try {
flag = qqLoginInterfaceOut.login(number,pwd);
} catch (RemoteException e) {
e.printStackTrace();
}
Toast.makeText(this, ""+flag, Toast.LENGTH_SHORT).show();
}
}
这里客户端并没有创建服务,而是使用了服务器的登录服务。不知道大家理解了没有呢,希望多多评论吧,给点谩骂也行啊- -