day16 Service AIDL进程间通信 与 Messager

AIDL

简介

AIDL,全称是Android Interface Define Language,即安卓接口定义语言,可以实现安卓设备中进程之间的通信(Inter Process Communication, IPC)。安卓中的服务分为2类:本地服务(网络下载大文件,音乐播放器,后台初始化数据库的操作);远程服务(远程调用支付宝进程的服务…)

使用:

进程之间的通信

步骤

(1).main里创建文件夹名:aidl,之后右击new—>AIDL(默认名:IMyAidlInterface.aidl)
(2).在接口里写方法

// IMyAidlInterface.aidl
package com.example.day16_practice_service;

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

interface IMyAidlInterface {
    /**
     * Demonstrates some basic types that you can use as parameters
     * and go_back values in AIDL.
     */
//    void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat,
//            double aDouble, String aString);
    int plus(int id,int add);
    int reduce(int id,int reduce);
    int show(int id);
}

(3).Rebuild Project---->自动生成一个Java文件:E:\AndroidStudioProjects\Month02\day16_practice_service\build\generated\aidl_source_output_dir\debug\compileDebugAidl\out\com\example\day16_practice_service\IMyAidlInterface.java
(4).数据提供

public class MySQLite extends SQLiteOpenHelper {
    public MySQLite(Context context) {
        super(context, "practice", null, 1);
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        db.execSQL("create table users (id Integer primary key autoincrement,name varchar(30),balance Double)");
        db.execSQL("insert into users values (null,?,?)",new String[]{"小明","3500000"});
        db.execSQL("insert into users values (null,?,?)",new String[]{"小张","3000000"});
        db.execSQL("insert into users values (null,?,?)",new String[]{"小李","3800000"});
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {

    }
}

服务

public class MyService extends Service {

    MySQLite mySQLite;
    SQLiteDatabase database;
    //重写方法中要执行的具体操作
    IBinder binder = new IMyAidlInterface.Stub() {
        @Override
        public int plus(int id, int add) throws RemoteException {
            Cursor cursor = database.query("users", null, "id = ?", new String[]{id+""}, null, null, null, null);
            double balance = 0;
            if (cursor.moveToNext()){
                balance = cursor.getDouble(cursor.getColumnIndex("balance"));
            }else{
                return -1;
            }
            ContentValues values = new ContentValues();
            values.put("balance",add+balance);
            int users = database.update("users", values, "id = ?", new String[]{id + ""});
            return users;
        }

        @Override
        public int reduce(int id, int reduce) throws RemoteException {
            Cursor cursor = database.query("users", null, "id = ?", new String[]{id+""}, null, null, null, null);
            double balance = 0;
            if (cursor.moveToNext()){
                balance = cursor.getDouble(cursor.getColumnIndex("balance"));
            }else{
                return -1;
            }
            ContentValues values = new ContentValues();
            if (balance > reduce){
                values.put("balance",balance-reduce);
            }else {
                return -2;
            }
            int users = database.update("users", values, "id = ?", new String[]{id + ""});
            return users;
        }

        @Override
        public int show(int id) throws RemoteException {
            Cursor cursor = database.query("users", null, "id = ?", new String[]{id+""}, null, null, null, null);
            double balance;
            if (cursor.moveToNext()){
                balance = cursor.getDouble(cursor.getColumnIndex("balance"));
            }else {
                return -1;
            }
            return (int)balance;
        }
    };

    @Override
    public void onCreate() {
        super.onCreate();
        mySQLite = new MySQLite(this);
        database = mySQLite.getWritableDatabase();
    }

    @Override
    public IBinder onBind(Intent intent) {
        return binder;
    }
}

清单文件注册:

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

    <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=".MyService"
            android:exported="true">
            <intent-filter>
                <action android:name="com.bw.practice"></action>
            </intent-filter>
        </service>


    </application>

</manifest>

(5).另一个App中:
创建一个与上一个App中一模一样的aidl,步骤同上,注意 包名必须相同

public class MainActivity extends AppCompatActivity {

    Button btn1,btn2,btn3;
    IMyAidlInterface iMyAidlInterface;
    ServiceConnection connection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            iMyAidlInterface = IMyAidlInterface.Stub.asInterface(service);
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {
            iMyAidlInterface = null;
        }
    };
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        btn1 = findViewById(R.id.add1);
        btn2 = findViewById(R.id.reduce);
        btn3 = findViewById(R.id.show);
        btn3.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                try {
                    int show = iMyAidlInterface.show(1);
                    Toast.makeText(MainActivity.this, ""+show, Toast.LENGTH_SHORT).show();
                } catch (RemoteException e) {
                    e.printStackTrace();
                }
            }
        });
        btn2.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                try {
                    int reduce = iMyAidlInterface.reduce(1, 2000);
                    if (reduce == -1){
                        Toast.makeText(MainActivity.this, "无此id", Toast.LENGTH_SHORT).show();
                        return;
                    }
                    if (reduce == -2){
                        Toast.makeText(MainActivity.this, "余额不足", Toast.LENGTH_SHORT).show();
                        return;
                    }
                    Toast.makeText(MainActivity.this, "成功", Toast.LENGTH_SHORT).show();
                } catch (RemoteException e) {
                    e.printStackTrace();
                }
            }
        });
        btn1.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                try {
                    int plus = iMyAidlInterface.plus(1, 30000);
                    if (plus == -1){
                        Toast.makeText(MainActivity.this, "无此id", Toast.LENGTH_SHORT).show();
                        return;
                    }
                    Toast.makeText(MainActivity.this, "成功", Toast.LENGTH_SHORT).show();
                } catch (RemoteException e) {
                    e.printStackTrace();
                }
            }
        });


        Intent intent = new Intent();
        intent.setAction("com.bw.practice");
        intent.setPackage("com.example.day16_practice_service");
        bindService(intent,connection,BIND_AUTO_CREATE);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        unbindService(connection);
    }
}

先启动数据提供端,再启动数据修改端

Messager

Messager 信使,能够完成跨进程通信。

Messager的原理

Messager的2个构造方法:分别以handler和Ibinder为参数
public Messenger(Handler target) {
mTarget = target.getIMessenger();
}
public Messenger(IBinder target) {
mTarget = IMessenger.Stub.asInterface(target);
}
我们可以在客户端发送一个Message给服务端,在服务端的handler中会接收到客户端的消息,然后进行对应的处理,处理完成后,再将结果等数据封装成Message,发送给客户端,客户端的handler中会接收到处理的结果。

特点

·客户端和服务端发送的都是message
·使用handler接受消息(客户端和服务端都是)
·不需要编写aidl文件

服务端:

public class MyService extends Service {
    //服务端信使对象,可以接受客户端发来的消息
    Messenger messenger=new Messenger(new Handler(){
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            //接受客户端发来的消息
            Bundle data = msg.getData();
            String data1 = data.getString("data");
            Toast.makeText(MyService.this, "接收到信息"+data1, Toast.LENGTH_SHORT).show();

        }
    });

    @Override
    public IBinder onBind(Intent intent) {
        return messenger.getBinder();
    }
}

清单文件注册

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

<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=".MyService" android:exported="true">
        <intent-filter>
            <action android:name="com.bawei.1704.aa"></action>
        </intent-filter>
    </service>
</application>

</manifest>

客户端:

public class MainActivity extends AppCompatActivity {
    ServiceConnection connection=new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            //获得服务端的信使对象
            Messenger messenger = new Messenger(service);
            //客户端向服务端发送消息
            Message message = new Message();
            //打包发送(注意)
            Bundle bundle = new Bundle();
            bundle.putString("data","服务器你好");
            message.setData(bundle);
            try {
                messenger.send(message);
                Toast.makeText(MainActivity.this, "客户端发送成功", Toast.LENGTH_SHORT).show();
            } catch (RemoteException e) {
                e.printStackTrace();
            }
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {

        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Intent intent = new Intent();
        intent.setAction("com.bawei.1704.aa");
        intent.setPackage("com.example.day16_messager_server");
        bindService(intent,connection,BIND_AUTO_CREATE);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        unbindService(connection);
    }
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值