24.远程服务Services

一.简介

何为远程服务?

同一部手机里面的两个应用程序之间相互通信,被称为远程服务
把一个公共的模块给它提取出来,其他手机上面的所有应用程序去调用它。
远程服务两个特点:客户端,服务端



二.案例


远程服务:同一个手机里面两个应用程序之间,一个客户端(微信)一个服务端(QQ)

只要把QQ这个服务端搞定,客户端 微信就很简单了,重点在服务端。

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context="com.zking.android24_myqq.MainActivity">

    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="MyQQ登录界面"
        android:textSize="30sp"
        />

    <EditText
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="请输入用户名:"
        android:id="@+id/et_main_number"
        /><!--number qq号-->
    <EditText
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="请输入密码:"
        android:id="@+id/et_main_pass"
        />
    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="登录"
        android:onClick="login"
        />

</LinearLayout>


MyQQ1.0版本

MainActivity.java

package com.zking.android24_myqq;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.EditText;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity {

    private EditText et_main_number;
    private EditText et_main_pass;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        et_main_number = (EditText) findViewById(R.id.et_main_number);//qq号
        et_main_pass = (EditText) findViewById(R.id.et_main_pass);//密码
    }

    public void login(View view){
         String number=et_main_number.getText().toString();
         String pass=et_main_pass.getText().toString();
         if("766437357".equals(number) && "123456".equals(pass)){
             Toast.makeText(this, "登录成功", Toast.LENGTH_SHORT).show();
         }else{
             Toast.makeText(this, "登录失败", Toast.LENGTH_SHORT).show();
         }
    }

}

MyQQ2.0版本(利用服务)

2.0版本:写一个服务类,专门用来进行QQ登录, 效果与QQ1.0版本一样但所用技术不同

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.zking.android24_myqq">

    <application android:allowBackup="true" android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name" android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true" android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

        <!--配置-->
        <service android:name=".QQLoginService"
            android:enabled="true"
            android:exported="true"
            >
        </service>

    </application>

</manifest>
MainActivity.java

package com.zking.android24_myqq;

import android.app.Service;
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;
import android.widget.EditText;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity {

    private EditText et_main_number;
    private EditText et_main_pass;
    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);//qq号
        et_main_pass = (EditText) findViewById(R.id.et_main_pass);//密码

        intent = new Intent(this,QQLoginService.class);

    }

    //检测有没有连接成功
    ServiceConnection connection= new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {//连接成功  IBinder强转为自己写的MyIBinder
                Log.i("test","绑定成功");
                myIBinder = (QQLoginService.MyIBinder) service;
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {//没有连接成功
                Log.i("test","绑定失败");
        }
    };

    //应用程序一启动就和服务绑定到一起去了
    @Override
    protected void onResume() {
        super.onResume();
        //绑定服务
        bindService(intent,connection, Service.BIND_AUTO_CREATE);//Ctrl+P   ServiceConnection服务连接   BIND_AUTO_CREATE在你绑定的时候自动创建(启动)服务
    }

    //点击登录
    public void login(View view){
         String number=et_main_number.getText().toString();
         String pass=et_main_pass.getText().toString();
         boolean flag=myIBinder.login(number,pass);//把账号和密码传给这个服务
         if(flag){
             Toast.makeText(this, "登录成功", Toast.LENGTH_SHORT).show();
         }else{
             Toast.makeText(this, "登录失败", Toast.LENGTH_SHORT).show();
         }
    }

}
QQLoginService.java

package com.zking.android24_myqq;

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;

/**
 * 利用服务来进行登录
 *
 * QQ登录的服务
 * 本地服务:启动服务的
 * 远程服务:绑定服务 (应用程序一启动就和服务绑定到一起去了)
 *
 * Activity与服务进行通信
 * 业务逻辑全部交给服务来写
 */

public class QQLoginService extends Service {

    /**
     * 自己写一个内部类
     * MyIBinder把他想像成jspServlet里面的(业务逻辑类)Dao层,Dao方法
     */
    class MyIBinder extends Binder{
           //登录的方法
           public boolean login(String number,String pass){
               if("766437357".equals(number) && "123456".equals(pass)){
                     return true;
               }else{
                     return false;
               }
           }
    }

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {//远程服务一个onBind就够了   IBinder
        Log.i("test","onBind");
        return new MyIBinder();
    }


}
效果图



MyQQ3.0版本(使用接口)

把2.0版本进行优化
3.0版本只是比2.0版本多了个接口的概念(实现类改为接口)
其他的类同2.0版本一样

接口和实现类里面的方法必须一模一样


MainActivity.java

package com.zking.android24_myqq;

import android.app.Service;
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;
import android.widget.EditText;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity {

    private EditText et_main_number;
    private EditText et_main_pass;
    private Intent intent;
    //private QQLoginService.MyIBinder myIBinder;  不给自己的实现类了,给接口
    private QQLogin qqlogin;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        et_main_number = (EditText) findViewById(R.id.et_main_number);//qq号
        et_main_pass = (EditText) findViewById(R.id.et_main_pass);//密码

        intent = new Intent(this,QQLoginService.class);

    }

    //检测有没有连接成功
    ServiceConnection connection= new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {//连接成功  IBinder强转为自己写的MyIBinder
                Log.i("test","绑定成功");
                //myIBinder = (QQLoginService.MyIBinder) service;
                qqlogin = (QQLogin) service;
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {//没有连接成功
                Log.i("test","绑定失败");
        }
    };

    //应用程序一启动就和服务绑定到一起去了
    @Override
    protected void onResume() {
        super.onResume();
        //绑定服务
        bindService(intent,connection, Service.BIND_AUTO_CREATE);//Ctrl+P   ServiceConnection服务连接   BIND_AUTO_CREATE在你绑定的时候自动创建(启动)服务
    }

    //点击登录
    public void login(View view){
         String number=et_main_number.getText().toString();
         String pass=et_main_pass.getText().toString();
         //boolean flag=myIBinder.login(number,pass);//把账号和密码传给这个服务
        boolean flag=qqlogin.login(number,pass);
         if(flag){
             Toast.makeText(this, "登录成功", Toast.LENGTH_SHORT).show();
         }else{
             Toast.makeText(this, "登录失败", Toast.LENGTH_SHORT).show();
         }
    }
}
QQLogin.java

package com.zking.android24_myqq;

/**
 * QQ登录的接口
 */

public interface QQLogin {
    public boolean login(String number, String pass);
}
QQLoginService.java

package com.zking.android24_myqq;

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;

/**
 * 利用服务来进行登录
 *
 * QQ登录的服务
 * 本地服务:启动服务的
 * 远程服务:绑定服务 (应用程序一启动就和服务绑定到一起去了)
 *
 * Activity与服务进行通信
 * 业务逻辑全部交给服务来写
 */

public class QQLoginService extends Service {

    /**
     * 自己写一个内部类
     * MyIBinder把他想像成jspServlet里面的(业务逻辑类)Dao层,Dao方法
     */
    class MyIBinder extends Binder implements QQLogin{//接口就要实现
           //登录的方法
           public boolean login(String number,String pass){
               if("766437357".equals(number) && "123456".equals(pass)){
                     return true;
               }else{
                     return false;
               }
           }
    }

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {//远程服务一个onBind就够了   IBinder
        Log.i("test","onBind");
        return new MyIBinder();
    }


}


MyQQ4.0版本(使用aidl)

AIDL:安卓接口定义语言

写aidl文件的目的是自动生成了一个接口,我们用这个自动生成的接口
为什么要用4.0版本,因为微信要用所以要用自动生成的那个aidl



MainActivity.java

package com.zking.android24_myqq;

import android.app.Service;
import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.os.RemoteException;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.EditText;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity {

    private EditText et_main_number;
    private EditText et_main_pass;
    private Intent intent;
    //private QQLoginService.MyIBinder myIBinder;  不给自己的实现类了,给接口
    private QQLogin qqlogin;
    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);//qq号
        et_main_pass = (EditText) findViewById(R.id.et_main_pass);//密码

        intent = new Intent(this,QQLoginService.class);

    }

    //检测有没有连接成功
    ServiceConnection connection= new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {//连接成功  IBinder强转为自己写的MyIBinder
                Log.i("test","绑定成功");
                //myIBinder = (QQLoginService.MyIBinder) service;
                //qqlogin = (QQLogin) service;
                qqLoginInterface = QQLoginInterface.Stub.asInterface(service);//给自动生成的.java文件(因为写了一个aidl文件,所以自动生成了一个.java文件)
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {//没有连接成功
                Log.i("test","绑定失败");
        }
    };

    //应用程序一启动就和服务绑定到一起去了
    @Override
    protected void onResume() {
        super.onResume();
        //绑定服务
        bindService(intent,connection, Service.BIND_AUTO_CREATE);//Ctrl+P   ServiceConnection服务连接   BIND_AUTO_CREATE在你绑定的时候自动创建(启动)服务
    }

    //点击登录
    public void login(View view){
         String number=et_main_number.getText().toString();
         String pass=et_main_pass.getText().toString();
         //boolean flag=myIBinder.login(number,pass);//把账号和密码传给这个服务
         //boolean flag=qqlogin.login(number,pass);
         boolean flag= false;
         try {
             flag = qqLoginInterface.login(number,pass);
         } catch (RemoteException e) {
             e.printStackTrace();
         }
         if(flag){
             Toast.makeText(this, "登录成功", Toast.LENGTH_SHORT).show();
         }else{
             Toast.makeText(this, "登录失败", Toast.LENGTH_SHORT).show();
         }
    }

}
QQLogin.java文件同上面一样

QQLoginService.java

package com.zking.android24_myqq;

import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.os.RemoteException;
import android.support.annotation.Nullable;
import android.util.Log;

/**
 * 利用服务来进行登录
 *
 * QQ登录的服务
 * 本地服务:启动服务的
 * 远程服务:绑定服务 (应用程序一启动就和服务绑定到一起去了)
 *
 * Activity与服务进行通信
 * 业务逻辑全部交给服务来写
 */

public class QQLoginService extends Service {

    /**
     * 自己写一个内部类
     * MyIBinder把他想像成jspServlet里面的(业务逻辑类)Dao层,Dao方法
     */
    class MyIBinder extends  QQLoginInterface.Stub{
        @Override
        public boolean login(String number, String pass) throws RemoteException {
            if("766437357".equals(number) && "123456".equals(pass)){
                   return true;
            }
            return false;
        }
    }

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {//远程服务一个onBind就够了   IBinder
        Log.i("test","onBind");
        return new MyIBinder();
    }


}

QQLoginInterface.aidl

// QQLoginInterface.aidl
package com.zking.android24_myqq;

// Declare any non-default types here with import statements

interface QQLoginInterface {
     boolean login(String number, String pass);//把接口QQLogin的方法copy过来,但是不要修饰符
}

效果图



最后,MyWeChat(微信客户端)



activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    android:orientation="vertical"
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent" tools:context="com.zking.android24_mywechat.MainActivity">

    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="MyWeChat"
        android:textSize="30sp"
        />

    <EditText
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="请输入用户名:"
        android:id="@+id/et_main_number"
        />
    <EditText
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="请输入密码:"
        android:id="@+id/et_main_pass"
        />
    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="登录"
        android:onClick="login"
        />

</LinearLayout>
MainActivity.java

package com.zking.android24_mywechat;

import android.app.Service;
import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.IBinder;
import android.os.RemoteException;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.EditText;
import android.widget.Toast;

import com.zking.android24_myqq.QQLoginInterface;

/**
 * 服务是写在QQ里面的,要启动QQ的服务
 * 通过微信里面怎么启动qq的服务
 * Android 5.0 之后,启动其他应用程序的服务,不允许使用隐式
 *
 *
 * 把QQ自动生成的那个类copy到微信里面去
 */
public class MainActivity extends AppCompatActivity {

    private EditText et_main_number;
    private EditText et_main_pass;
    private Intent intent;
    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_pass = (EditText) findViewById(R.id.et_main_pass);

        intent = new Intent();
        ComponentName componentName=new ComponentName("com.zking.android24_myqq","com.zking.android24_myqq.QQLoginService");//你要启动的服务(QQ)所在的包名,QQ里面的服务类(1.应用程序的包名)
        intent.setComponent(componentName);
    }

    //连接对象
    ServiceConnection connection=new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
                qqLoginInterface = QQLoginInterface.Stub.asInterface(service);
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {

        }
    };

    @Override
    protected void onResume() {
        super.onResume();
        //绑定服务
        bindService(intent,connection, Service.BIND_AUTO_CREATE);//2连接对象
    }

    public void login(View view){
            String number=et_main_number.getText().toString();
            String pass=et_main_pass.getText().toString();

            try {
                boolean b=qqLoginInterface.login(number,pass);
                if(b){
                    Toast.makeText(this, "登录成功", Toast.LENGTH_SHORT).show();
                }else{
                    Toast.makeText(this, "登录失败", Toast.LENGTH_SHORT).show();
                }
            } catch (RemoteException e) {
                e.printStackTrace();
            }
    }



}







  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值