zoukankan      html  css  js  c++  java
  • Android AIDL 实现过程

    Android系统中的进程之间不能共享内存,因此,需要提供一些机制在不同进程之间进行数据通信。为了使其他的应用程序也可以访问本应用程序提供的服务,Android系统采用了远程过程调用(Remote Procedure CallRPC)方式来实现。与很多其他的基于RPC的解决方案一样,Android使用一种接口定义语言(Interface Definition LanguageIDL)来公开服务的接口。我们知道4Android应用程序组件中的3个(ActivityBroadcastReceiverContentProvider)都可以进行跨进程访问,另外一个Android应用程序组件Service同样可以。因此,可以将这种可以跨进程访问的服务称为AIDLAndroid Interface Definition Language)服务。

    Aidl文件所在的包名和文件名要相同:

     

    应为用到了parcelable接口,这里先说说它: 

    Parcelable接口

    Android中实现序列化有两个选择:一是实现Serializable接口(是JavaSE本身就支持的),一是实现Parcelable接口(是Android特有功能,效率比实现Serializable接口高效,可用于Intent数据传递,也可以用于进程间通信(IPC))。实现Serializable接口非常简单,声明一下就可以了,而实现Parcelable接口稍微复杂一些,但效率更高,推荐用这种方法提高性能。

    注:Android中Intent传递对象有两种方法:一是Bundle.putSerializable(Key,Object),另一种是Bundle.putParcelable(Key,Object)。当然这些Object是有一定的条件的,前者是实现了Serializable接口,而后者是实现了Parcelable接口。

    HarlaInfo.Java:

    package com.harlan.demo.aidl;

    import android.os.Parcel;

    import android.os.Parcelable;

    public class HarlanInfo implements Parcelable {

    private String name;

    private int age;

    private String place;

    public String getName() {

    return name;

    }

    public void setName(String name) {

    this.name = name;

    }

    public int getAge() {

    return age;

    }

    public void setAge(int age) {

    this.age = age;

    }

    public String getPlace() {

    return place;

    }

    public void setPlace(String place) {

    this.place = place;

    }

    public HarlanInfo() {

    }

    public HarlanInfo(Parcel parcel) {

    this.name = parcel.readString();

    this.age = parcel.readInt();

    this.place = parcel.readString();

    }

    public int describeContents() {

    return 0;

    }

    /**

     * 将对象序列化为一个Parcel对象 可以将Parcel看成是一个流,通过writeToParcel把对象写到流里面,

     * 再通过createFromParcel从流里读取对象 注意:写的顺序和读的顺序必须一致。

     */

    public void writeToParcel(Parcel parcel, int arg1) {

    parcel.writeString(name);

    parcel.writeInt(age);

    parcel.writeString(place);

    }

    public static final Parcelable.Creator<HarlanInfo> CREATOR = new Creator<HarlanInfo>() {

    public HarlanInfo createFromParcel(Parcel parcel) {

    HarlanInfo harlan=new HarlanInfo(parcel);

    return harlan;

    }

    @Override

    public HarlanInfo[] newArray(int size) {

    // TODO Auto-generated method stub

    return new HarlanInfo [size];

    }

    };

    HarlanInfo.aidl

    package com.harlan.demo.aidl;

    parcelable HarlanInfo;

    定义一个aidl文件,使client端利用回调拿到serviceparam参数;然后设置到toast上显示出来。

    ICallBack.aidl:

    package com.harlan.demo.aidl;

    interface ICallBack{

    void handleByServer(String param);

    }

    定义这个aidl文件,使clientharlanInfoclient)传数据和到serviceservice用harlanInfoservice)取得数据;

    ExecuteServiceAIDL.aidl

    package com.harlan.demo.aidl;

    import com.harlan.demo.aidl.HarlanInfo;

    import com.harlan.demo.aidl.ICallBack;

    interface ExecuteServiceAIDL

    {

    /**

     *get info from server and 

     *Transfer a callback methods handle;

     *if occur error ,will be return null

     *对于非基本数据类型和StringCharSequence类型,要加上方向指示

     *包括inoutinout,in表示由客户端设置,out表示由服务端设置,inout是两者均可设置。

         */

    HarlanInfo getServerHarlanInfo(in HarlanInfo info,ICallBack icallback);

    }

    ClientActivity.java:

    package com.harlan.demo.activity;

    import android.app.Activity;

    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.util.Log;

    import android.view.View;

    import android.widget.Button;

    import android.widget.EditText;

    import android.widget.Toast;

    import com.harlan.demo.aidl.ExecuteServiceAIDL;

    import com.harlan.demo.aidl.HarlanInfo;

    import com.harlan.demo.aidl.ICallBack;

    public class ClientActivity extends Activity

    {

        public static final String TAG = "ClientActivity";

        

        private static final String BIND_ACTION = "com.harlan.demo.aidl.service";

        

        private EditText mEditTextName;

        

        private EditText mEditTextAge;

        

        private EditText mEditTextPlace;

        

        private Button mButtonCommit;

        

        private ExecuteServiceAIDL executeService;

        

        @Override

        protected void onCreate(Bundle savedInstanceState)

        {

            super.onCreate(savedInstanceState);

            setContentView(R.layout.activity_client);

            getView();

            mButtonCommit.setOnClickListener(new View.OnClickListener()

            {

                

                @Override

                public void onClick(View v)

                {

                    getServiceConnect();

                    

                }

            });

        }

            

        private void getView()

        {

            mEditTextName = (EditText)findViewById(R.id.editText_name);

            mEditTextAge = (EditText)findViewById(R.id.editText_age);

            mEditTextPlace = (EditText)findViewById(R.id.editText_place);

            mButtonCommit = (Button)findViewById(R.id.button_commit);

        }

        

        private void getServiceConnect()

        {

            Intent it = new Intent();

            it.setAction(BIND_ACTION);

            startService(it);

            bindService(it, mserviceConnection, BIND_AUTO_CREATE);

        }

        

        ServiceConnection mserviceConnection = new ServiceConnection()

        {

            

            @Override

            public void onServiceDisconnected(ComponentName name)

            {

                Log.d(TAG, "onServiceDisconnected");

                

            }

            

            @Override

            public void onServiceConnected(ComponentName name, IBinder service)

            {

                Log.d(TAG, "onServiceConnected");

                executeService = ExecuteServiceAIDL.Stub.asInterface(service);

                if (executeService != null)

                {

                    handlerInfo();

                }

            }

        };

        

        private void handlerInfo()

        {

            String mName;

            int mAge;

            String mPlace;

            if (mEditTextName.getText().toString().equals(""))

            {

                mName = "孤独";

            }

            else

            {

                mName = mEditTextName.getText().toString();

            }

            if (mEditTextAge.getText().toString().equals(""))

            {

                mAge = 23;

            }

            else

            {

                mAge = Integer.parseInt(mEditTextAge.getText().toString());

            }

            if (mEditTextPlace.getText().toString().equals(""))

            {

                mPlace = "世界";

            }

            else

            {

                mPlace = mEditTextPlace.getText().toString();

            }

            //将数据传到harlanInfo中  

            HarlanInfo mInfo = new HarlanInfo();

            mInfo.setName(mName);

            mInfo.setAge(mAge);

            mInfo.setPlace(mPlace);

            try

            {

                HarlanInfo serverInfo = new HarlanInfo();

                serverInfo = executeService.getServerHarlanInfo(mInfo, mCallBack);

                //拿到service传回的数据

                mEditTextName.setText(serverInfo.getName());

                mEditTextAge.setText(String.valueOf(serverInfo.getAge()));

                mEditTextPlace.setText(serverInfo.getPlace());

                unbindService(mserviceConnection);

            }

            catch (RemoteException e)

            {

                e.printStackTrace();

            }

        }

        

        ICallBack.Stub mCallBack = new ICallBack.Stub()

        {

            

            @Override

            public void handleByServer(String param)

                throws RemoteException

            {

                Toast.makeText(getApplicationContext(), param, Toast.LENGTH_LONG).show();

                

            }

        };

        

    }

    AIDLService.Java:

    package com.harlan.demo.service;

    import android.app.Service;

    import android.content.Intent;

    import android.os.IBinder;

    import android.os.RemoteException;

    import android.util.Log;

    import com.harlan.demo.aidl.ExecuteServiceAIDL;

    import com.harlan.demo.aidl.HarlanInfo;

    import com.harlan.demo.aidl.ICallBack;

    public class AIDLService extends Service

    {

        public static final String TAG = "AIDLService";

        

        private ICallBack mCallBack;

        

        /**

         * 绑定服务

         */

        @Override

        public IBinder onBind(Intent intent)

        {

            // TODO Auto-generated method stub

            return mBinder;

        }

        

        /**

         * 创建服务

         */

        @Override

        public void onCreate()

        {

            super.onCreate();

        }

        /**

         * 销毁服务

         */

        @Override

        public void onDestroy()

        {

            super.onDestroy();

        }

        /**

         * 启动服务

         */

        @Override

        public void onStart(Intent intent, int startId)

        {

            super.onStart(intent, startId);

        }

        /**

         * 解绑服务

         */

        @Override

        public boolean onUnbind(Intent intent)

        {

            mCallBack = null;

            return super.onUnbind(intent);

        }

        

        ExecuteServiceAIDL.Stub mBinder = new ExecuteServiceAIDL.Stub()

        {

            @Override

            public HarlanInfo getServerHarlanInfo(HarlanInfo info, ICallBack icallback)

                throws RemoteException

            {

                Log.d(TAG,"getServerHarlanInfo");

                mCallBack = icallback;

    //传参数给client

                mCallBack.handleByServer("The msg is from server");

                HarlanInfo newInfo = new HarlanInfo();

    //通过HarlanInfo序列化数据 再传给client

                newInfo.setName(info.getName()+"幸福");

                newInfo.setAge(info.getAge() + 10);

                newInfo.setPlace(info.getPlace()+"Home");

                return newInfo;

            }

        };

        

    }

    效果图,布局文件自己写

     

     ps:本人也是参考别人的例子写的,中间有解释不对的地方,望轻喷。。。。

  • 相关阅读:
    Javascript函数式编程要掌握的知识点讲解
    任务
    怎么添加项目到SVN上面
    随便写一点最近开发遇到的问题和解决方法 大部分关于laravel和php
    laravel 将数组转化成字符串 再把字符串转化成数组
    laravel 配置了自己的域名以后, localhost 无法访问 404 not found 的解决方法
    实习日记15
    php接收post过来的 json数据 例子
    数据库如何让自增id重置
    C#连接MySQL数据库
  • 原文地址:https://www.cnblogs.com/mydomainlistentome/p/4687173.html
Copyright © 2011-2022 走看看