美文网首页
Android Studio 创建AIDL Demo

Android Studio 创建AIDL Demo

作者: EdwardWinner | 来源:发表于2017-10-03 23:07 被阅读510次

    由于一直在做上层App,与AIDL接触的真心很少,上层应用之间的交互使用AIDL不多,可以使用Broadcast、ContentProvider等等。但是最近确实被AIDL摆了一道,决定认真调试一下。
    AIDL其实是一个IPC通信机制, 即进程之间也可以相互通信,传递有效数据,那么怎么创建或者说需要什么呢?首先交互需要服务端和客户端,其次主要的方式创建aidl文件,其实质还是通过service进行交互。

    1.AIDLServer

    1.1 Person的创建

    package com.example.edwardadmin.aidlmodel;
    
    import android.os.Parcel;
    import android.os.Parcelable;
    
    /**
     * Created by EdwardAdmin on 2017/9/24.
     */
    
    public class Person implements Parcelable {
    
        private String mUserName;
        private String mUserAge;
    
        public Person(String username, String userage) {
            mUserName = username;
            mUserAge = userage;
        }
    
        public String getmUserName() {
            return mUserName;
        }
    
        public String getmUserAge() {
            return mUserAge;
        }
    
        @Override
        public String toString() {
            return super.toString();
        }
    
        protected Person(Parcel in) {
            mUserName = in.readString();
            mUserAge = in.readString();
        }
    
        @Override
        public void writeToParcel(Parcel dest, int flags) {
            dest.writeString(mUserName);
            dest.writeString(mUserAge);
        }
    
        @Override
        public int describeContents() {
            return 0;
        }
    
        public static final Creator<Person> CREATOR = new Creator<Person>() {
            @Override
            public Person createFromParcel(Parcel in) {
                return new Person(in);
            }
    
            @Override
            public Person[] newArray(int size) {
                return new Person[size];
            }
        };
    }
    

    注意点:

    Model类需要实现 Parcelable,重写重要方法

    1.2 IPersonAidlInterface.aidl创建

    // IPersonAidlInterface.aidl
    package com.example.edwardadmin.aidl;
    
    parcelable Person;
    

    注意点:

    parcelable 是小写

    1.3 IRomteAidlInterface.aidl创建

    // IRomteAidlInterface.aidl
    package com.example.edwardadmin.aidl;
    
    // Declare any non-default types here with import statements
    
    interface IRomteAidlInterface {
        /**
         * Demonstrates some basic types that you can use as parameters
         * and return values in AIDL.
         */
        void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat,
                double aDouble, String aString);
    
        String getPersonUserName();
        String getPersonUserAge();
    
    }
    

    1.4 RmoteService的创建

    package com.example.edwardadmin.service;
    
    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;
    
    import com.example.edwardadmin.aidl.IRomteAidlInterface;
    import com.example.edwardadmin.aidlmodel.Person;
    
    /**
     * Created by EdwardAdmin on 2017/9/24.
     */
    
    public class RmoteService extends Service {
    
        private static final String TAG = "RmoteService";
    
        private Person mPerson;
        private String mUserName;
        private String mUserAge;
    
        @Override
        public void onCreate() {
            super.onCreate();
        }
    
        @Nullable
        @Override
        public IBinder onBind(Intent intent) {
            Log.d(TAG, "onBind Service success!");
            mPerson = new Person("Edward", "24");
            return new RomteBinder();
        }
    
        class RomteBinder extends IRomteAidlInterface.Stub {
    
            @Override
            public void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat, double aDouble, String aString) throws RemoteException {
    
            }
    
            @Override
            public String getPersonUserName() throws RemoteException {
                mUserName = mPerson.getmUserName();
                Log.d(TAG, "Person mUserName = " + mUserName);
                return mUserName;
            }
    
            @Override
            public String getPersonUserAge() throws RemoteException {
                mUserAge = mPerson.getmUserAge();
                Log.d(TAG, "Person mUserAge = " + mUserAge);
                return mUserAge;
            }
        }
    
        @Override
        public boolean onUnbind(Intent intent) {
            return super.onUnbind(intent);
        }
    }
    

    1.5 AndroidManifest.xml创建

    <?xml version="1.0" encoding="utf-8"?>
    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
              package="com.example.edwardadmin.aidlserver">
    
        <application
            android:allowBackup="true"
            android:icon="@mipmap/ic_launcher"
            android:label="@string/app_name"
            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="com.example.edwardadmin.service.RmoteService">
                <intent-filter>
                    <action android:name="android.intent.action.RESPOND_AIDL_MESSAGE"></action>
                </intent-filter>
            </service>
        </application>
    
    </manifest>
    

    1.6 AIDLServer项目结构

    AIDLServer项目结构图

    2.AIDLClient创建

    2.1 copy aidl to client.

    2.2 Connect & Acquire

    package com.example.edwardadmin.aidl;
    
    import android.content.ComponentName;
    import android.content.Context;
    import android.content.Intent;
    import android.content.ServiceConnection;
    import android.content.pm.PackageManager;
    import android.content.pm.ResolveInfo;
    import android.os.IBinder;
    import android.os.RemoteException;
    import android.support.v7.app.AppCompatActivity;
    import android.os.Bundle;
    import android.util.Log;
    import android.view.View;
    import android.widget.Button;
    import android.widget.Toast;
    
    import java.util.List;
    
    public class MainActivity extends AppCompatActivity {
    
        private static final String TAG = "MainActivity";
        private static final String BIND_SERVICE_ACTION = "android.intent.action.RESPOND_AIDL_MESSAGE";
    
        private IRomteAidlInterface iRomteAidlInterface;
    
        private Button mConnectButton;
        private Button mAcquireButton;
    
        private String mUsername;
        private String mUserage;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            initView();
        }
    
        private void initView() {
            mConnectButton = (Button) this.findViewById(R.id.connect);
            mAcquireButton = (Button) this.findViewById(R.id.acquire_info);
    
            mConnectButton.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    bindService();
                }
            });
    
            mAcquireButton.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    if (null != iRomteAidlInterface) {
                        try {
                            mUsername = iRomteAidlInterface.getPersonUserName();
                            mUserage = iRomteAidlInterface.getPersonUserAge();
                            Toast.makeText(getApplicationContext(), "mUsername = " + mUsername + ",mUserage = " + mUserage, Toast.LENGTH_SHORT).show();
                        } catch (RemoteException e) {
                            e.printStackTrace();
                        }
                    }
                }
            });
        }
    
        ServiceConnection serviceConnection = new ServiceConnection() {
            @Override
            public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
                iRomteAidlInterface = IRomteAidlInterface.Stub.asInterface(iBinder);
            }
    
            @Override
            public void onServiceDisconnected(ComponentName componentName) {
                iRomteAidlInterface = null;
            }
        };
    
        private void bindService() {
            Intent serviceIntent = new Intent();
            serviceIntent.setAction(BIND_SERVICE_ACTION);
            //serviceIntent.setComponent(new ComponentName("com.example.edwardadmin.aidlserver", "com.example.edwardadmin.service.RmoteService"));
            final Intent eintent = new Intent(achieveExplicitFromImplicitIntent(this, serviceIntent));
            bindService(serviceIntent, serviceConnection, Context.BIND_AUTO_CREATE);
            Log.d(TAG, "bindService");
        }
    
        private void unBindSevice() {
            unbindService(serviceConnection);
            Log.d(TAG, "unbindService");
        }
    
        @Override
        protected void onDestroy() {
            super.onDestroy();
            unBindSevice();
        }
    
        public Intent achieveExplicitFromImplicitIntent(Context context, Intent implicitIntent) {
            // Retrieve all services that can match the given intent
            PackageManager pm = context.getPackageManager();
            List<ResolveInfo> resolveInfo = pm.queryIntentServices(implicitIntent, 0);
    
            // Make sure only one match was found
            if (resolveInfo == null || resolveInfo.size() != 1) {
                return null;
            }
    
            // Get component info and create ComponentName
            ResolveInfo serviceInfo = resolveInfo.get(0);
            String packageName = serviceInfo.serviceInfo.packageName;
            String className = serviceInfo.serviceInfo.name;
            Log.d(TAG,"packageName = " + packageName);
            Log.d(TAG,"className = " + className);
            ComponentName component = new ComponentName(packageName, className);
            
            Intent explicitIntent = new Intent(implicitIntent);
    
            explicitIntent.setComponent(component);
            return explicitIntent;
        }
    }
    

    2.3 AIDLClient项目结构

    AIDLClient项目结构图

    Question1.当AIDLClient创建成功之后,Service连接不上?

    Answer:

    1).Intent 除了必要的Action,还需要ComponentName,参数packageName:"AIDLServer->AndroidMainfest.xml->package",参数className:"AIDLServer->Service完整的包名+ServiceName"
    2).如果第一点不清楚的,调用achieveExplicitFromImplicitIntent方法,获取正确的Intent。

    Github地址:
    AIDLServer:https://github.com/EricWinner/AIDLServer
    AIDLClient:https://github.com/EricWinner/AIDLClient

    有任何问题,欢迎指出.

    相关文章

      网友评论

          本文标题:Android Studio 创建AIDL Demo

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