美文网首页
Aandroid 进程间通讯 AIDL

Aandroid 进程间通讯 AIDL

作者: 程序员阿兵 | 来源:发表于2019-06-27 18:31 被阅读0次

下面是服务端和客户端互相通讯:

一 :客户端

  • 1.创建服务端工程


    image.png

在指定包名:com.custom.binder 下 创建Interface.aidl

    1. 定义接口类型,回调方法:
interface ILoginInterface {

    // 登录
    void login();

    // 登录返回
    void loginCallback(boolean loginStatus, String loginUser);
}

    1. 定义客户端service用于接收服务端回调通讯
public class MyService extends Service {

    @Override
    public IBinder onBind(Intent intent) {

        return new ILoginInterface.Stub() {
            @Override
            public void login() throws RemoteException {
            }

            @Override
            public void loginCallback(boolean loginStatus, String loginUser) throws RemoteException {
                Log.e("netease >>> ", "loginStatus: " + loginStatus + " / loginUser: " + loginUser);
            }
        };
    }
}
  • 注册服务,点击按钮调用服务端,打开服务端界面
public class MainActivity extends Activity {

    // 模拟用户名和密码 的值
    private final static String NAME = "netease";
    private final static String PWD = "163";

    private EditText nameEt;
    private EditText pwdEt;
    private boolean isStartRemote; // 是否开启跨进程通信
    private ILoginInterface iLogin; // AIDL定义接口

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        requestWindowFeature(Window.FEATURE_NO_TITLE);  // 隐藏标题
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
                WindowManager.LayoutParams.FLAG_FULLSCREEN);    // 设置全屏

        setContentView(R.layout.activity_main);

        nameEt = findViewById(R.id.nameEt);
        pwdEt = findViewById(R.id.pwdEt);

        initBindService();
    }

    public void initBindService() {
        Intent intent = new Intent();
        // 设置Server应用Action
        intent.setAction("BinderA_Action");
        // 设置Server应用包名(5.1+要求)
        intent.setPackage("com.netease.binder.a");
        // 开始绑定服务
        bindService(intent, conn, BIND_AUTO_CREATE);
        // 标识跨进程绑定
        isStartRemote = true;
    }

    // 服务连接
    private ServiceConnection conn = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            iLogin = ILoginInterface.Stub.asInterface(service);
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {

        }
    };

    // 点击事件
    public void startLogin(View view) {

        final String name = nameEt.getText().toString();
        final String pwd = pwdEt.getText().toString();

        if (TextUtils.isEmpty(name) || TextUtils.isEmpty(pwd)) {
            showToast("请输入用户名或密码...");
            return;
        }

        // 模拟登录状态加载...
        final ProgressDialog progressDialog = new ProgressDialog(this);
        progressDialog.setTitle("登录");
        progressDialog.setMessage("正在登录中...");
        progressDialog.show();

        new Thread(new Runnable() {
            @Override
            public void run() {

                SystemClock.sleep(2000);

                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        try {
                            boolean isLoginSuccess = false;
                            if (NAME.equals(name) && PWD.equals(pwd)) {
                                showToast("QQ登录成功!");
                                isLoginSuccess = true;
                                finish();
                            } else {
                                showToast("QQ登录失败!");
                            }
                            progressDialog.dismiss();
                            iLogin.loginCallback(isLoginSuccess, NAME);
                        } catch (RemoteException e) {
                            e.printStackTrace();
                        }
                    }
                });
            }
        }).start();

    }

    private void showToast(String text) {
        Toast.makeText(this, text, Toast.LENGTH_SHORT).show();
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();

        if (isStartRemote) {
            // 解绑服务,一定要记得解绑服务,否则可能会报异常(服务连接资源异常)
            unbindService(conn);
        }
    }
}

二 :服务端

  • 1.创建服务端AIDL 目录(注意次包名和服务端包名保证一致)


    image.png
  • 2.新建Interface.aidl
interface ILoginInterface {

    // 登录
    void login();

    // 登录返回
    void loginCallback(boolean loginStatus, String loginUser);
}

  • 3.新建服务端service 监听回调:下面客户端调服务端后打开对应服务端界面
public class MyService extends Service {

    @Override
    public IBinder onBind(Intent intent) {

        return new ILoginInterface.Stub() {
            @Override
            public void login() throws RemoteException {
                Log.e("netease >>> ", "BinderB_MyService");
                // 单项通信有问题,真实项目双向通信,双服务绑定
                serviceStartActivity();
            }

            @Override
            public void loginCallback(boolean loginStatus, String loginUser) throws RemoteException {
            }
        };
    }

    /**
     * 在Service启动Activity,需要配置:.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
     */
    private void serviceStartActivity() {
        Intent intent = new Intent(this, MainActivity.class);
        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        startActivity(intent);
    }

}

  • 4.服务端初始化服务,调用客户端代码
public class MainActivity extends Activity {

    private boolean isStartRemote; // 是否开启跨进程通信
    private ILoginInterface iLogin; // AIDL定义接口

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        requestWindowFeature(Window.FEATURE_NO_TITLE); // 隐藏标题
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
                WindowManager.LayoutParams.FLAG_FULLSCREEN); // 设置全屏

        setContentView(R.layout.activity_main);
        initBindService();
    }

    // 点击事件
    public void startQQLoginAction(View view) {
        if (iLogin != null) {
            try {
                // 调用Server方法
                iLogin.login();
            } catch (RemoteException e) {
                e.printStackTrace();
            }
        } else {
            Toast.makeText(this, "请安装QQ应用...", Toast.LENGTH_SHORT).show();
        }
    }

    public void initBindService() {
        Intent intent = new Intent();
        // 设置Server应用Action
        intent.setAction("BinderB_Action");
        // 设置Server应用包名(5.1+要求)
        intent.setPackage("com.netease.binder.b");
        // 开始绑定服务
        bindService(intent, conn, BIND_AUTO_CREATE);
        // 标识跨进程绑定
        isStartRemote = true;
    }

    // 服务连接
    private ServiceConnection conn = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            iLogin = ILoginInterface.Stub.asInterface(service);
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {

        }
    };

    @Override
    protected void onDestroy() {
        super.onDestroy();

        if (isStartRemote) {
            // 解绑服务,一定要记得解绑服务,否则可能会报异常(服务连接资源异常)
            unbindService(conn);
        }
    }
}
    1. 服务端注册服务
  <service
            android:name="com.netease.binder.client.service.MyService"
            android:enabled="true"
            android:exported="true"
            android:process=":remote">
            <intent-filter>
                <!-- 激活 MyService 唯一name,不能重名-->
                <action android:name="BinderA_Action" />
            </intent-filter>
        </service>

相关文章

网友评论

      本文标题:Aandroid 进程间通讯 AIDL

      本文链接:https://www.haomeiwen.com/subject/gihlcctx.html