转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/38461079 ,本文出自【张鸿洋的博客】

1、概述

Binder能干什么?Binder可以提供系统中任何程序都可以访问的全局服务。这个功能当然是任何系统都应该提供的,下面我们简单看一下Android的Binder的框架

Android Binder框架分为服务器接口、Binder驱动、以及客户端接口;简单想一下,需要提供一个全局服务,那么全局服务那端即是服务器接口,任何程序即客户端接口,它们之间通过一个Binder驱动访问。

服务器端接口:实际上是Binder类的对象,该对象一旦创建,内部则会启动一个隐藏线程,会接收Binder驱动发送的消息,收到消息后,会执行Binder对象中的onTransact()函数,并按照该函数的参数执行不同的服务器端代码。

Binder驱动:该对象也为Binder类的实例,客户端通过该对象访问远程服务。

客户端接口:获得Binder驱动,调用其transact()发送消息至服务器

如果大家对上述不了解,没关系,下面会通过例子来更好的说明,实践是检验真理的唯一标准嘛

2、AIDL的使用

如果对Android比较熟悉,那么一定使用过AIDL,如果你还不了解,那么也没关系,下面会使用一个例子展示AIDL的用法。

我们使用AIDL实现一个跨进程的加减法调用

1、服务端

新建一个项目,创建一个包名:com.zhy.calc.aidl,在包内创建一个ICalcAIDL文件:

  1. package com.zhy.calc.aidl;
  2. interface ICalcAIDL
  3. {
  4. int add(int x , int y);
  5. int min(int x , int y );
  6. }

注意,文件名为ICalcAIDL.aidl

然后在项目的gen目录下会生成一个ICalcAIDL.java文件,暂时不贴这个文件的代码了,后面会详细说明

然后我们在项目中新建一个Service,代码如下:

  1. package com.example.zhy_binder;
  2.  
  3. import com.zhy.calc.aidl.ICalcAIDL;
  4.  
  5. import android.app.Service;
  6. import android.content.Intent;
  7. import android.os.IBinder;
  8. import android.os.RemoteException;
  9. import android.util.Log;
  10.  
  11. public class CalcService extends Service
  12. {
  13. private static final String TAG = "server";
  14.  
  15. public void onCreate()
  16. {
  17. Log.e(TAG, "onCreate");
  18. }
  19.  
  20. public IBinder onBind(Intent t)
  21. {
  22. Log.e(TAG, "onBind");
  23. return mBinder;
  24. }
  25.  
  26. public void onDestroy()
  27. {
  28. Log.e(TAG, "onDestroy");
  29. super.onDestroy();
  30. }
  31.  
  32. public boolean onUnbind(Intent intent)
  33. {
  34. Log.e(TAG, "onUnbind");
  35. return super.onUnbind(intent);
  36. }
  37.  
  38. public void onRebind(Intent intent)
  39. {
  40. Log.e(TAG, "onRebind");
  41. super.onRebind(intent);
  42. }
  43.  
  44. private final ICalcAIDL.Stub mBinder = new ICalcAIDL.Stub()
  45. {
  46.  
  47. @Override
  48. public int add(int x, int y) throws RemoteException
  49. {
  50. return x + y;
  51. }
  52.  
  53. @Override
  54. public int min(int x, int y) throws RemoteException
  55. {
  56. return x - y;
  57. }
  58.  
  59. };
  60.  
  61. }

在此Service中,使用生成的ICalcAIDL创建了一个mBinder的对象,并在Service的onBind方法中返回

最后记得在AndroidManifest中注册

  1. <service android:name="com.example.zhy_binder.CalcService" >
  2. <intent-filter>
  3. <action android:name="com.zhy.aidl.calc" />
  4.  
  5. <category android:name="android.intent.category.DEFAULT" />
  6. </intent-filter>
  7. </service>

这里我们指定了一个name,因为我们一会会在别的应用程序中通过Intent来查找此Service;这个不需要Activity,所以我也就没写Activity,安装完成也看不到安装图标,悄悄在后台运行着。

到此,服务端编写完毕。下面开始编写客户端

2、客户端

客户端的代码比较简单,创建一个布局,里面包含4个按钮,分别为绑定服务,解除绑定,调用加法,调用减法

布局文件:

  1. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  2. xmlns:tools="http://schemas.android.com/tools"
  3. android:layout_width="match_parent"
  4. android:layout_height="match_parent"
  5. android:orientation="vertical" >
  6.  
  7. <Button
  8. android:layout_width="fill_parent"
  9. android:layout_height="wrap_content"
  10. android:onClick="bindService"
  11. android:text="BindService" />
  12.  
  13. <Button
  14. android:layout_width="fill_parent"
  15. android:layout_height="wrap_content"
  16. android:onClick="unbindService"
  17. android:text="UnbindService" />
  18.  
  19. <Button
  20. android:layout_width="fill_parent"
  21. android:layout_height="wrap_content"
  22. android:onClick="addInvoked"
  23. android:text="12+12" />
  24.  
  25. <Button
  26. android:layout_width="fill_parent"
  27. android:layout_height="wrap_content"
  28. android:onClick="minInvoked"
  29. android:text="50-12" />
  30.  
  31. </LinearLayout>

主Activity

  1. package com.example.zhy_binder_client;
  2.  
  3. import android.app.Activity;
  4. import android.content.ComponentName;
  5. import android.content.Context;
  6. import android.content.Intent;
  7. import android.content.ServiceConnection;
  8. import android.os.Bundle;
  9. import android.os.IBinder;
  10. import android.util.Log;
  11. import android.view.View;
  12. import android.widget.Toast;
  13.  
  14. import com.zhy.calc.aidl.ICalcAIDL;
  15.  
  16. public class MainActivity extends Activity
  17. {
  18. private ICalcAIDL mCalcAidl;
  19.  
  20. private ServiceConnection mServiceConn = new ServiceConnection()
  21. {
  22. @Override
  23. public void onServiceDisconnected(ComponentName name)
  24. {
  25. Log.e("client", "onServiceDisconnected");
  26. mCalcAidl = null;
  27. }
  28.  
  29. @Override
  30. public void onServiceConnected(ComponentName name, IBinder service)
  31. {
  32. Log.e("client", "onServiceConnected");
  33. mCalcAidl = ICalcAIDL.Stub.asInterface(service);
  34. }
  35. };
  36.  
  37. @Override
  38. protected void onCreate(Bundle savedInstanceState)
  39. {
  40. super.onCreate(savedInstanceState);
  41. setContentView(R.layout.activity_main);
  42.  
  43. }
  44.  
  45. /**
  46. * 点击BindService按钮时调用
  47. * @param view
  48. */
  49. public void bindService(View view)
  50. {
  51. Intent intent = new Intent();
  52. intent.setAction("com.zhy.aidl.calc");
  53. bindService(intent, mServiceConn, Context.BIND_AUTO_CREATE);
  54. }
  55. /**
  56. * 点击unBindService按钮时调用
  57. * @param view
  58. */
  59. public void unbindService(View view)
  60. {
  61. unbindService(mServiceConn);
  62. }
  63. /**
  64. * 点击12+12按钮时调用
  65. * @param view
  66. */
  67. public void addInvoked(View view) throws Exception
  68. {
  69.  
  70. if (mCalcAidl != null)
  71. {
  72. int addRes = mCalcAidl.add(12, 12);
  73. Toast.makeText(this, addRes + "", Toast.LENGTH_SHORT).show();
  74. } else
  75. {
  76. Toast.makeText(this, "服务器被异常杀死,请重新绑定服务端", Toast.LENGTH_SHORT)
  77. .show();
  78.  
  79. }
  80.  
  81. }
  82. /**
  83. * 点击50-12按钮时调用
  84. * @param view
  85. */
  86. public void minInvoked(View view) throws Exception
  87. {
  88.  
  89. if (mCalcAidl != null)
  90. {
  91. int addRes = mCalcAidl.min(58, 12);
  92. Toast.makeText(this, addRes + "", Toast.LENGTH_SHORT).show();
  93. } else
  94. {
  95. Toast.makeText(this, "服务端未绑定或被异常杀死,请重新绑定服务端", Toast.LENGTH_SHORT)
  96. .show();
  97.  
  98. }
  99.  
  100. }
  101.  
  102. }

很标准的绑定服务的代码。

直接看运行结果:

我们首先点击BindService按钮,查看log

  1. 08-09 22:56:38.959: E/server(29692): onCreate
  2. 08-09 22:56:38.959: E/server(29692): onBind
  3. 08-09 22:56:38.959: E/client(29477): onServiceConnected

可以看到,点击BindService之后,服务端执行了onCreate和onBind的方法,并且客户端执行了onServiceConnected方法,标明服务器与客户端已经联通

然后点击12+12,50-12可以成功的调用服务端的代码并返回正确的结果

下面我们再点击unBindService

  1. 08-09 22:59:25.567: E/server(29692): onUnbind
  2. 08-09 22:59:25.567: E/server(29692): onDestroy

由于我们当前只有一个客户端绑定了此Service,所以Service调用了onUnbind和onDestory

然后我们继续点击12+12,50-12,通过上图可以看到,依然可以正确执行,也就是说即使onUnbind被调用,连接也是不会断开的,那么什么时候会端口呢?

即当服务端被异常终止的时候,比如我们现在在手机的正在执行的程序中找到该服务:

点击停止,此时查看log

  1. 08-09 23:04:21.433: E/client(30146): onServiceDisconnected

可以看到调用了onServiceDisconnected方法,此时连接被断开,现在点击12+12,50-12的按钮,则会弹出Toast服务端断开的提示。

说了这么多,似乎和Binder框架没什么关系,下面我们来具体看一看AIDL为什么做了些什么。

3、分析AIDL生成的代码

 

1、服务端

先看服务端的代码,可以看到我们服务端提供的服务是由

  1. private final ICalcAIDL.Stub mBinder = new ICalcAIDL.Stub()
  2. {
  3.  
  4. @Override
  5. public int add(int x, int y) throws RemoteException
  6. {
  7. return x + y;
  8. }
  9.  
  10. @Override
  11. public int min(int x, int y) throws RemoteException
  12. {
  13. return x - y;
  14. }
  15.  
  16. };

ICalcAILD.Stub来执行的,让我们来看看Stub这个类的声明:

  1. public static abstract class Stub extends android.os.Binder implements com.zhy.calc.aidl.ICalcAIDL

清楚的看到这个类是Binder的子类,是不是符合我们文章开通所说的服务端其实是一个Binder类的实例

接下来看它的onTransact()方法:

  1. @Override public boolean onTransact(int code, android.os.Parcel data, android.os.Parcel reply, int flags) throws android.os.RemoteException
  2. {
  3. switch (code)
  4. {
  5. case INTERFACE_TRANSACTION:
  6. {
  7. reply.writeString(DESCRIPTOR);
  8. return true;
  9. }
  10. case TRANSACTION_add:
  11. {
  12. data.enforceInterface(DESCRIPTOR);
  13. int _arg0;
  14. _arg0 = data.readInt();
  15. int _arg1;
  16. _arg1 = data.readInt();
  17. int _result = this.add(_arg0, _arg1);
  18. reply.writeNoException();
  19. reply.writeInt(_result);
  20. return true;
  21. }
  22. case TRANSACTION_min:
  23. {
  24. data.enforceInterface(DESCRIPTOR);
  25. int _arg0;
  26. _arg0 = data.readInt();
  27. int _arg1;
  28. _arg1 = data.readInt();
  29. int _result = this.min(_arg0, _arg1);
  30. reply.writeNoException();
  31. reply.writeInt(_result);
  32. return true;
  33. }
  34. }
  35. return super.onTransact(code, data, reply, flags);
  36. }

文章开头也说到服务端的Binder实例会根据客户端依靠Binder驱动发来的消息,执行onTransact方法,然后由其参数决定执行服务端的代码。

可以看到onTransact有四个参数

code , data ,replay , flags

code 是一个整形的唯一标识,用于区分执行哪个方法,客户端会传递此参数,告诉服务端执行哪个方法

data客户端传递过来的参数

replay服务器返回回去的值

flags标明是否有返回值,0为有(双向),1为没有(单向)

我们仔细看case TRANSACTION_min中的代码

data.enforceInterface(DESCRIPTOR);与客户端的writeInterfaceToken对用,标识远程服务的名称

int _arg0;
_arg0 = data.readInt();
int _arg1;
_arg1 = data.readInt();

接下来分别读取了客户端传入的两个参数

int _result = this.min(_arg0, _arg1);
reply.writeNoException();
reply.writeInt(_result);

然后执行this.min,即我们实现的min方法;返回result由reply写回。

add同理,可以看到服务端通过AIDL生成Stub的类,封装了服务端本来需要写的代码。

2、客户端

客户端主要通过ServiceConnected与服务端连接

  1. private ServiceConnection mServiceConn = new ServiceConnection()
  2. {
  3. @Override
  4. public void onServiceDisconnected(ComponentName name)
  5. {
  6. Log.e("client", "onServiceDisconnected");
  7. mCalcAidl = null;
  8. }
  9.  
  10. @Override
  11. public void onServiceConnected(ComponentName name, IBinder service)
  12. {
  13. Log.e("client", "onServiceConnected");
  14. mCalcAidl = ICalcAIDL.Stub.asInterface(service);
  15. }
  16. };

如果你比较敏锐,应该会猜到这个onServiceConnected中的IBinder实例,其实就是我们文章开通所说的Binder驱动,也是一个Binder实例

在ICalcAIDL.Stub.asInterface中最终调用了:

  1. return new com.zhy.calc.aidl.ICalcAIDL.Stub.Proxy(obj);

这个Proxy实例传入了我们的Binder驱动,并且封装了我们调用服务端的代码,文章开头说,客户端会通过Binder驱动的transact()方法调用服务端代码

直接看Proxy中的add方法

  1. @Override public int add(int x, int y) throws android.os.RemoteException
  2. {
  3. android.os.Parcel _data = android.os.Parcel.obtain();
  4. android.os.Parcel _reply = android.os.Parcel.obtain();
  5. int _result;
  6. try {
  7. _data.writeInterfaceToken(DESCRIPTOR);
  8. _data.writeInt(x);
  9. _data.writeInt(y);
  10. mRemote.transact(Stub.TRANSACTION_add, _data, _reply, 0);
  11. _reply.readException();
  12. _result = _reply.readInt();
  13. }
  14. finally {
  15. _reply.recycle();
  16. _data.recycle();
  17. }
  18. return _result;
  19. }

首先声明两个Parcel对象,一个用于传递数据,一个用户接收返回的数据

_data.writeInterfaceToken(DESCRIPTOR);与服务器端的enforceInterfac对应

_data.writeInt(x);
_data.writeInt(y);写入需要传递的参数

mRemote.transact(Stub.TRANSACTION_add, _data, _reply, 0);

终于看到了我们的transact方法,第一个对应服务端的code,_data,_repay分别对应服务端的data,reply,0表示是双向的

_reply.readException();
_result = _reply.readInt();

最后读出我们服务端返回的数据,然后return。可以看到和服务端的onTransact基本是一行一行对应的。

到此,我们已经通过AIDL生成的代码解释了Android Binder框架的工作原理。Service的作用其实就是为我们创建Binder驱动,即服务端与客户端连接的桥梁。

AIDL其实通过我们写的aidl文件,帮助我们生成了一个接口,一个Stub类用于服务端,一个Proxy类用于客户端调用。那么我们是否可以不通过写AIDL来实现远程的通信呢?下面向大家展示如何完全不依赖AIDL来实现客户端与服务端的通信。

4、不依赖AIDL实现程序间通讯

 

1、服务端代码

我们新建一个CalcPlusService.java用于实现两个数的乘和除

  1. package com.example.zhy_binder;
  2.  
  3. import android.app.Service;
  4. import android.content.Intent;
  5. import android.os.Binder;
  6. import android.os.IBinder;
  7. import android.os.Parcel;
  8. import android.os.RemoteException;
  9. import android.util.Log;
  10.  
  11. public class CalcPlusService extends Service
  12. {
  13. private static final String DESCRIPTOR = "CalcPlusService";
  14. private static final String TAG = "CalcPlusService";
  15.  
  16. public void onCreate()
  17. {
  18. Log.e(TAG, "onCreate");
  19. }
  20.  
  21. @Override
  22. public int onStartCommand(Intent intent, int flags, int startId)
  23. {
  24. Log.e(TAG, "onStartCommand");
  25. return super.onStartCommand(intent, flags, startId);
  26. }
  27.  
  28. public IBinder onBind(Intent t)
  29. {
  30. Log.e(TAG, "onBind");
  31. return mBinder;
  32. }
  33.  
  34. public void onDestroy()
  35. {
  36. Log.e(TAG, "onDestroy");
  37. super.onDestroy();
  38. }
  39.  
  40. public boolean onUnbind(Intent intent)
  41. {
  42. Log.e(TAG, "onUnbind");
  43. return super.onUnbind(intent);
  44. }
  45.  
  46. public void onRebind(Intent intent)
  47. {
  48. Log.e(TAG, "onRebind");
  49. super.onRebind(intent);
  50. }
  51.  
  52. private MyBinder mBinder = new MyBinder();
  53.  
  54. private class MyBinder extends Binder
  55. {
  56. @Override
  57. protected boolean onTransact(int code, Parcel data, Parcel reply,
  58. int flags) throws RemoteException
  59. {
  60. switch (code)
  61. {
  62. case 0x110:
  63. {
  64. data.enforceInterface(DESCRIPTOR);
  65. int _arg0;
  66. _arg0 = data.readInt();
  67. int _arg1;
  68. _arg1 = data.readInt();
  69. int _result = _arg0 * _arg1;
  70. reply.writeNoException();
  71. reply.writeInt(_result);
  72. return true;
  73. }
  74. case 0x111:
  75. {
  76. data.enforceInterface(DESCRIPTOR);
  77. int _arg0;
  78. _arg0 = data.readInt();
  79. int _arg1;
  80. _arg1 = data.readInt();
  81. int _result = _arg0 / _arg1;
  82. reply.writeNoException();
  83. reply.writeInt(_result);
  84. return true;
  85. }
  86. }
  87. return super.onTransact(code, data, reply, flags);
  88. }
  89.  
  90. };
  91.  
  92. }

我们自己实现服务端,所以我们自定义了一个Binder子类,然后复写了其onTransact方法,我们指定服务的标识为CalcPlusService,然后0x110为乘,0x111为除;

记得在AndroidMenifest中注册

  1. <service android:name="com.example.zhy_binder.CalcPlusService" >
  2. <intent-filter>
  3. <action android:name="com.zhy.aidl.calcplus" />
  4. <category android:name="android.intent.category.DEFAULT" />
  5. </intent-filter>
  6. </service>

服务端代码结束。

2、客户端代码

单独新建了一个项目,代码和上例很类似

首先布局文件:

  1. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  2. xmlns:tools="http://schemas.android.com/tools"
  3. android:layout_width="match_parent"
  4. android:layout_height="match_parent"
  5. android:orientation="vertical" >
  6.  
  7. <Button
  8. android:layout_width="fill_parent"
  9. android:layout_height="wrap_content"
  10. android:onClick="bindService"
  11. android:text="BindService" />
  12.  
  13. <Button
  14. android:layout_width="fill_parent"
  15. android:layout_height="wrap_content"
  16. android:onClick="unbindService"
  17. android:text="UnbindService" />
  18.  
  19. <Button
  20. android:layout_width="fill_parent"
  21. android:layout_height="wrap_content"
  22. android:onClick="mulInvoked"
  23. android:text="50*12" />
  24.  
  25. <Button
  26. android:layout_width="fill_parent"
  27. android:layout_height="wrap_content"
  28. android:onClick="divInvoked"
  29. android:text="36/12" />
  30.  
  31. </LinearLayout>

可以看到加入了乘和除

然后是Activity的代码

  1. package com.example.zhy_binder_client03;
  2.  
  3. import android.app.Activity;
  4. import android.content.ComponentName;
  5. import android.content.Context;
  6. import android.content.Intent;
  7. import android.content.ServiceConnection;
  8. import android.os.Bundle;
  9. import android.os.IBinder;
  10. import android.os.RemoteException;
  11. import android.util.Log;
  12. import android.view.View;
  13. import android.widget.Toast;
  14.  
  15. public class MainActivity extends Activity
  16. {
  17.  
  18. private IBinder mPlusBinder;
  19. private ServiceConnection mServiceConnPlus = new ServiceConnection()
  20. {
  21. @Override
  22. public void onServiceDisconnected(ComponentName name)
  23. {
  24. Log.e("client", "mServiceConnPlus onServiceDisconnected");
  25. }
  26.  
  27. @Override
  28. public void onServiceConnected(ComponentName name, IBinder service)
  29. {
  30.  
  31. Log.e("client", " mServiceConnPlus onServiceConnected");
  32. mPlusBinder = service;
  33. }
  34. };
  35.  
  36. @Override
  37. protected void onCreate(Bundle savedInstanceState)
  38. {
  39. super.onCreate(savedInstanceState);
  40. setContentView(R.layout.activity_main);
  41.  
  42. }
  43.  
  44. public void bindService(View view)
  45. {
  46. Intent intentPlus = new Intent();
  47. intentPlus.setAction("com.zhy.aidl.calcplus");
  48. boolean plus = bindService(intentPlus, mServiceConnPlus,
  49. Context.BIND_AUTO_CREATE);
  50. Log.e("plus", plus + "");
  51. }
  52.  
  53. public void unbindService(View view)
  54. {
  55. unbindService(mServiceConnPlus);
  56. }
  57.  
  58. public void mulInvoked(View view)
  59. {
  60.  
  61. if (mPlusBinder == null)
  62. {
  63. Toast.makeText(this, "未连接服务端或服务端被异常杀死", Toast.LENGTH_SHORT).show();
  64. } else
  65. {
  66. android.os.Parcel _data = android.os.Parcel.obtain();
  67. android.os.Parcel _reply = android.os.Parcel.obtain();
  68. int _result;
  69. try
  70. {
  71. _data.writeInterfaceToken("CalcPlusService");
  72. _data.writeInt(50);
  73. _data.writeInt(12);
  74. mPlusBinder.transact(0x110, _data, _reply, 0);
  75. _reply.readException();
  76. _result = _reply.readInt();
  77. Toast.makeText(this, _result + "", Toast.LENGTH_SHORT).show();
  78.  
  79. } catch (RemoteException e)
  80. {
  81. e.printStackTrace();
  82. } finally
  83. {
  84. _reply.recycle();
  85. _data.recycle();
  86. }
  87. }
  88.  
  89. }
  90.  
  91. public void divInvoked(View view)
  92. {
  93.  
  94. if (mPlusBinder == null)
  95. {
  96. Toast.makeText(this, "未连接服务端或服务端被异常杀死", Toast.LENGTH_SHORT).show();
  97. } else
  98. {
  99. android.os.Parcel _data = android.os.Parcel.obtain();
  100. android.os.Parcel _reply = android.os.Parcel.obtain();
  101. int _result;
  102. try
  103. {
  104. _data.writeInterfaceToken("CalcPlusService");
  105. _data.writeInt(36);
  106. _data.writeInt(12);
  107. mPlusBinder.transact(0x111, _data, _reply, 0);
  108. _reply.readException();
  109. _result = _reply.readInt();
  110. Toast.makeText(this, _result + "", Toast.LENGTH_SHORT).show();
  111.  
  112. } catch (RemoteException e)
  113. {
  114. e.printStackTrace();
  115. } finally
  116. {
  117. _reply.recycle();
  118. _data.recycle();
  119. }
  120. }
  121.  
  122. }
  123. }

为了明了,我直接在mulInvoked里面写了代码,和服务端都没有抽象出一个接口。首先绑定服务时,通过onServiceConnected得到Binder驱动即mPlusBinder;

然后准备数据,调用transact方法,通过code指定执行服务端哪个方法,代码和上面的分析一致。

下面看运行结果:

是不是很好的实现了我们两个应用程序间的通讯,并没有使用aidl文件,也从侧面分析了我们上述分析是正确的。

好了,就到这里,相信大家看完这篇博文,对aidl和Binder的理解也会更加深刻。

测试代码点击下载

代码先安装server端的代码,然后再安装client端的。。。

Android aidl Binder框架浅析的更多相关文章

  1. Android AIDL浅析及异步使用

    AIDL:Android Interface Definition Language,即 Android 接口定义语言. AIDL 是什么 Android 系统中的进程之间不能共享内存,因此,需要提供 ...

  2. [置顶] 深入理解android之IPC机制与Binder框架

    [android之IPC机制与Binder框架] [Binder框架.Parcel.Proxy-Stub以及AIDL] Abstract [每个平台都会有自己一套跨进程的IPC机制,让不同进程里的两个 ...

  3. Android service binder aidl 关系

    /********************************************************************************** * Android servic ...

  4. Android系统--Binder系统具体框架分析(二)Binder驱动情景分析

    Android系统--Binder系统具体框架分析(二)Binder驱动情景分析 1. Binder驱动情景分析 1.1 进程间通信三要素 源 目的:handle表示"服务",即向 ...

  5. ANDROID BINDER机制浅析

    Binder是Android上一种IPC机制,重要且较难理解.由于Linux上标准IPC在灵活和可靠性存在一定不足,Google基于OpenBinder的设计和构想实现了Binder. 本文只简单介绍 ...

  6. Android Otto框架浅析

    今天要介绍的是一个Android中使用得比較多的android 事件总线 EventBus模式的一个框架Otto. Otto 官网:http://square.github.io/otto/ 一.An ...

  7. Android系统--Binder系统具体框架分析(一)补充

    Android系统--Binder系统具体框架分析(一)补充 补充:对Binder驱动分析一的代码补充,添加saygoobye和saygoodbye_to服务 test_server.h #ifnde ...

  8. android 多进程 Binder AIDL Service

    本文參考http://blog.csdn.net/saintswordsman/article/details/5130947 android的多进程是通过Binder来实现的,一个类,继承了Bind ...

  9. Android网络通信Volley框架源代码浅析(一)

    尊重原创http://blog.csdn.net/yuanzeyao/article/details/25837897 从今天開始,我打算为大家呈现关于Volley框架的源代码分析的文章,Volley ...

随机推荐

  1. intellij idea 10.5介绍

    IDEA 全称 IntelliJ IDEA,是java语言开发的集成环境,IntelliJ在业界被公认为最好的java开发工具之一,尤其在智能代码助手.代码自动提示.重构.J2EE支持.Ant.JUn ...

  2. 1029 C语言文法定义与C程序的推导过程

    1 阅读并理解提供给大家的C语言文法文件. 2 参考该文件写出一个自己好理解版的现实版的完整版的C语言文法. 3 给出一段C程序,写出用上述文法产生这段C程序的推导过程. program → exte ...

  3. poj1703 Find them, Catch them

    并查集. 这题错了不少次才过的. 分析见代码. http://poj.org/problem?id=1703 #include <cstdio> #include <cstring& ...

  4. sscanf 函数 分类: POJ 2015-08-04 09:19 4人阅读 评论(0) 收藏

    sscanf 其实很强大 分类: 纯C技术 技术笔记 2010-03-05 16:00 12133人阅读 评论(4) 收藏 举报 正则表达式stringbuffercurlgoogle 最近在做日志分 ...

  5. Windows手动添加开机启动项

    @方法1. 添加程序完整路径到注册表HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Run下 或者添加到HKEY_CURREN ...

  6. maven之一——多模块项目构建

    参考这个帖子: http://www.cnblogs.com/xdp-gacl/p/4242221.html

  7. 六、IO流——文件

    IO流1.字节流(InputStream.OutputStream)2.字符流 (Reader.Writer)3.缓冲流(BufferedInputStream.BufferedOutputStrea ...

  8. [转]NSTimer和CADisplayLink的基本用法

    简要区别:NSTimer初始化器接受调用方法逻辑之间的间隔作为它的其中一个参数,预设一秒执行30次.CADisplayLink默认每秒运行60次,通过它的frameInterval属性改变每秒运行帧数 ...

  9. :判断101-200之间有多少个素数,并输出所有素数。 程序分析:判断素数的方法:用一个数分别去除2到sqrt(这个数),如果能被整除, 则表明此数不是素数,反之是素数。

    package C; public class Sushu { public static void main(String[] args) { int sum=0; for (int i = 101 ...

  10. V-rep学习笔记:曲柄摇杆机构

    在ADAMS中创建一个曲柄摇杆机构很方便,但是V-rep中建模就比较麻烦.下面将自己在V-rep中建立曲柄摇杆机构模型的过程记录下来(由于对V-rep不是很熟,可能会有一些错误,只能等以后发现了再改进 ...