Android AIDL 實現過程

Android系統中的進程之間不能共享內存,所以,須要提供一些機制在不一樣進程之間進行數據通訊。爲了使其餘的應用程序也能夠訪問本應用程序提供的服務,Android系統採用了遠程過程調用(Remote Procedure CallRPC)方式來實現。與不少其餘的基於RPC的解決方案同樣,Android使用一種接口定義語言(Interface Definition LanguageIDL)來公開服務的接口。咱們知道4Android應用程序組件中的3個(ActivityBroadcastReceiverContentProvider)均可以進行跨進程訪問,另一個Android應用程序組件Service一樣能夠。所以,能夠將這種能夠跨進程訪問的服務稱爲AIDLAndroid Interface Definition Language)服務。java

 

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

 

 

應爲用到了parcelable接口,這裏先說說它: app

Parcelable接口ide

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:this

package com.harlan.demo.aidl;spa

 

import android.os.Parcel;server

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:本人也是參考別人的例子寫的,中間有解釋不對的地方,望輕噴。。。。

相關文章
相關標籤/搜索