├── .gitignore ├── .idea ├── .name ├── compiler.xml ├── copyright │ └── profiles_settings.xml ├── encodings.xml ├── gradle.xml ├── misc.xml ├── modules.xml └── runConfigurations.xml ├── README.md ├── app ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── org │ │ └── wangchenlong │ │ └── binderpooldemo │ │ └── ApplicationTest.java │ ├── main │ ├── AndroidManifest.xml │ ├── aidl │ │ └── org │ │ │ └── wangchenlong │ │ │ └── binderpooldemo │ │ │ ├── IBinderPool.aidl │ │ │ ├── ICompute.aidl │ │ │ └── ISecurityCenter.aidl │ ├── java │ │ └── org │ │ │ └── wangchenlong │ │ │ └── binderpooldemo │ │ │ ├── BinderPool.java │ │ │ ├── BinderPoolService.java │ │ │ ├── ComputeImpl.java │ │ │ ├── MainActivity.java │ │ │ └── SecurityCenterImpl.java │ └── res │ │ ├── layout │ │ └── activity_main.xml │ │ ├── mipmap-hdpi │ │ └── ic_launcher.png │ │ ├── mipmap-mdpi │ │ └── ic_launcher.png │ │ ├── mipmap-xhdpi │ │ └── ic_launcher.png │ │ ├── mipmap-xxhdpi │ │ └── ic_launcher.png │ │ ├── mipmap-xxxhdpi │ │ └── ic_launcher.png │ │ ├── values-w820dp │ │ └── dimens.xml │ │ └── values │ │ ├── colors.xml │ │ ├── dimens.xml │ │ ├── strings.xml │ │ └── styles.xml │ └── test │ └── java │ └── org │ └── wangchenlong │ └── binderpooldemo │ └── ExampleUnitTest.java ├── articles └── demo-anim.gif ├── build.gradle ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat └── settings.gradle /.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .gradle 3 | /local.properties 4 | /.idea/workspace.xml 5 | /.idea/libraries 6 | .DS_Store 7 | /build 8 | /captures 9 | -------------------------------------------------------------------------------- /.idea/.name: -------------------------------------------------------------------------------- 1 | BinderPoolDemo -------------------------------------------------------------------------------- /.idea/compiler.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /.idea/copyright/profiles_settings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /.idea/encodings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /.idea/gradle.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 22 | 23 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 12 | 13 | 14 | 26 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | Android 46 | 47 | 48 | Android Lint 49 | 50 | 51 | Java 52 | 53 | 54 | Java language level migration aidsJava 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 76 | 77 | $USER_HOME$/.subversion 78 | 79 | 80 | 81 | 82 | 83 | 1.8 84 | 85 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 101 | 102 | 103 | 104 | 105 | 106 | -------------------------------------------------------------------------------- /.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /.idea/runConfigurations.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 11 | 12 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 实现AIDL接口的Binder连接池 2 | 3 | > 欢迎Follow我的GitHub: https://github.com/SpikeKing 4 | 5 | Binder作为AIDL通信的核心, 在使用中经常需要重复利用, 动态管理AIDL接口. Binder连接池的主要作用是把Binder请求统一发送至Service执行, 即动态管理Binder操作, 避免重复创建Service. 本文使用两种简单的AIDL服务, 使用Binder连接池动态切换, 含有演示Demo. 6 | 7 | 本文源码的GitHub[下载地址](https://github.com/SpikeKing/BinderPoolDemo) 8 | 9 | --- 10 | 11 | ## AIDL 12 | 13 | 模拟Binder连接池, 使用两个简单的AIDL接口与实现, 一个是加解密, 一个是加法. 14 | 15 | 加解密, AIDL提供两个方法, 即加密字符串和解密字符串. 16 | 17 | ``` java 18 | package org.wangchenlong.binderpooldemo; 19 | 20 | interface ISecurityCenter { 21 | String encrypt(String content); 22 | String decrypt(String password); 23 | } 24 | ``` 25 | 26 | 加密和解密的实现, 使用简单的异或运算处理. 27 | 28 | ``` java 29 | public class SecurityCenterImpl extends ISecurityCenter.Stub { 30 | private static final char SECRET_CODE = 'w'; 31 | 32 | @Override public String encrypt(String content) throws RemoteException { 33 | char[] chars = content.toCharArray(); 34 | for (int i = 0; i < chars.length; i++) { 35 | chars[i] ^= SECRET_CODE; 36 | } 37 | return new String(chars); 38 | } 39 | 40 | @Override public String decrypt(String password) throws RemoteException { 41 | return encrypt(password); 42 | } 43 | } 44 | ``` 45 | 46 | > AIDL的实现方法都需要设置``RemoteException``的异常抛出, 防止连接异常. 47 | 48 | 求和的AIDL接口 49 | 50 | ``` java 51 | package org.wangchenlong.binderpooldemo; 52 | 53 | interface ICompute { 54 | int add(int a, int b); 55 | } 56 | ``` 57 | 58 | 求和的实现, 非常简单. 59 | 60 | ``` java 61 | public class ComputeImpl extends ICompute.Stub { 62 | @Override public int add(int a, int b) throws RemoteException { 63 | return a + b; 64 | } 65 | } 66 | ``` 67 | 68 | **Binder连接池**通过ID查找Bidner, 查询并返回匹配的Binder. 69 | 70 | ``` java 71 | package org.wangchenlong.binderpooldemo; 72 | 73 | interface IBinderPool { 74 | IBinder queryBinder(int binderCode); 75 | } 76 | ``` 77 | 78 | --- 79 | 80 | ## Binder 连接池 81 | 82 | Service服务通过``Binder``连接池动态选择``Binder``请求. 83 | 84 | ``` java 85 | private Binder mBinderPool = new BinderPool.BinderPoolImpl(); // 动态选择Binder 86 | 87 | @Nullable @Override public IBinder onBind(Intent intent) { 88 | Log.e(TAG, "onBind"); 89 | return mBinderPool; 90 | } 91 | ``` 92 | 93 | Binder连接池的具体实现, 创建``BinderPool``单例, 连接服务. 94 | 95 | ``` java 96 | private BinderPool(Context context) { 97 | mContext = context.getApplicationContext(); 98 | connectBinderPoolService(); // 连接服务 99 | } 100 | 101 | public static BinderPool getInstance(Context context) { 102 | if (sInstance == null) { 103 | synchronized (BinderPool.class) { 104 | if (sInstance == null) { 105 | sInstance = new BinderPool(context); 106 | } 107 | } 108 | } 109 | return sInstance; 110 | } 111 | ``` 112 | 113 | 绑定服务, 通过``CountDownLatch``类, 把异步操作转换为同步操作, 防止绑定冲突. 114 | 115 | ``` 116 | private synchronized void connectBinderPoolService() { 117 | mCountDownLatch = new CountDownLatch(1); // 只保持一个绑定服务 118 | Intent service = new Intent(mContext, BinderPoolService.class); 119 | mContext.bindService(service, mBinderPoolConnection, Context.BIND_AUTO_CREATE); 120 | try { 121 | mCountDownLatch.await(); 122 | } catch (InterruptedException e) { 123 | e.printStackTrace(); 124 | } 125 | } 126 | ``` 127 | 128 | 通过``DeathRecipient``处理Binder连接池死亡重联机制. 129 | 130 | ``` java 131 | // 失效重联机制, 当Binder死亡时, 重新连接 132 | private IBinder.DeathRecipient mDeathRecipient = new IBinder.DeathRecipient() { 133 | @Override public void binderDied() { 134 | Log.e(TAG, "Binder失效"); 135 | mBinderPool.asBinder().unlinkToDeath(mDeathRecipient, 0); 136 | mBinderPool = null; 137 | connectBinderPoolService(); 138 | } 139 | }; 140 | 141 | // Binder的服务连接 142 | private ServiceConnection mBinderPoolConnection = new ServiceConnection() { 143 | @Override public void onServiceConnected(ComponentName name, IBinder service) { 144 | mBinderPool = IBinderPool.Stub.asInterface(service); 145 | try { 146 | mBinderPool.asBinder().linkToDeath(mDeathRecipient, 0); 147 | } catch (RemoteException e) { 148 | e.printStackTrace(); 149 | } 150 | mCountDownLatch.countDown(); 151 | } 152 | 153 | @Override public void onServiceDisconnected(ComponentName name) { 154 | 155 | } 156 | }; 157 | ``` 158 | 159 | 通过ID连接不同的``Binder``请求. 160 | 161 | ``` java 162 | public IBinder queryBinder(int binderCode) { 163 | IBinder binder = null; 164 | try { 165 | if (mBinderPool != null) { 166 | binder = mBinderPool.queryBinder(binderCode); 167 | } 168 | } catch (RemoteException e) { 169 | e.printStackTrace(); 170 | } 171 | 172 | return binder; 173 | } 174 | ``` 175 | 176 | Binder连接池AIDL的具体实现, 通过ID选择Binder. 177 | 178 | ``` java 179 | public static class BinderPoolImpl extends IBinderPool.Stub { 180 | public BinderPoolImpl() { 181 | super(); 182 | } 183 | 184 | @Override public IBinder queryBinder(int binderCode) throws RemoteException { 185 | IBinder binder = null; 186 | switch (binderCode) { 187 | case BINDER_COMPUTE: 188 | binder = new ComputeImpl(); 189 | break; 190 | case BINDER_SECURITY_CENTER: 191 | binder = new SecurityCenterImpl(); 192 | break; 193 | default: 194 | break; 195 | } 196 | return binder; 197 | } 198 | } 199 | ``` 200 | 201 | > AIDL并不会直接生成, 使用AS的``Build -> Make Project``即可. 202 | 203 | --- 204 | 205 | ## 客户端 206 | 207 | 通过AIDL接口, 把耗时任务移到Service进行. 操作Binder需要在其他线程中执行, 使用Handler回调至主线程, 并更新页面. 208 | 209 | ``` java 210 | public void encryptMsg(View view) { 211 | new Thread(new Runnable() { 212 | @Override public void run() { 213 | doEncrypt(); 214 | } 215 | }).start(); 216 | } 217 | 218 | private void doEncrypt() { 219 | BinderPool binderPool = BinderPool.getInstance(getApplicationContext()); 220 | IBinder securityBinder = binderPool.queryBinder(BinderPool.BINDER_SECURITY_CENTER); 221 | mISecurityCenter = SecurityCenterImpl.asInterface(securityBinder); 222 | String msg = "Hello, I am Spike!"; 223 | try { 224 | String encryptMsg = mISecurityCenter.encrypt(msg); 225 | Log.e(TAG, "加密信息: " + encryptMsg); 226 | String decryptMsg = mISecurityCenter.decrypt(encryptMsg); 227 | Log.e(TAG, "解密信息: " + decryptMsg); 228 | Message hm = new Message(); 229 | hm.what = 0; 230 | hm.obj = encryptMsg + "\n" + decryptMsg; 231 | mHandler.sendMessage(hm); 232 | 233 | } catch (RemoteException e) { 234 | e.printStackTrace(); 235 | } 236 | } 237 | ``` 238 | 239 | > 其他线程使用``Handler``向主线程传递数据, 在界面中显示效果. 240 | 241 | 加法操作类似. 242 | 243 | ``` java 244 | public void addNumbers(View view) { 245 | new Thread(new Runnable() { 246 | @Override public void run() { 247 | doAddition(); 248 | } 249 | }).start(); 250 | } 251 | 252 | private void doAddition() { 253 | BinderPool binderPool = BinderPool.getInstance(getApplicationContext()); 254 | IBinder computeBinder = binderPool.queryBinder(BinderPool.BINDER_COMPUTE); 255 | mICompute = ComputeImpl.asInterface(computeBinder); 256 | try { 257 | int result = mICompute.add(12, 12); 258 | Log.e(TAG, "12 + 12 = " + result); 259 | 260 | Message hm = new Message(); 261 | hm.what = 1; 262 | hm.obj = result + ""; 263 | mHandler.sendMessage(hm); 264 | } catch (RemoteException e) { 265 | e.printStackTrace(); 266 | } 267 | } 268 | ``` 269 | 270 | > 注意AIDL需要捕获``RemoteException``的异常. 271 | 272 | --- 273 | 274 | 效果 275 | 276 | ![效果](https://raw.githubusercontent.com/SpikeKing/BinderPoolDemo/master/articles/demo-anim.gif) 277 | 278 | AIDL是较为高效的跨进程通信方式, 也是其他方式的低层实现; Binder连接池可以在同一服务中处理多个Binder请求, 节省资源, 因此需要熟练掌握. 279 | 280 | OK, that's all! Enjoy it! 281 | -------------------------------------------------------------------------------- /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | 3 | android { 4 | compileSdkVersion 23 5 | buildToolsVersion "23.0.2" 6 | 7 | defaultConfig { 8 | applicationId "org.wangchenlong.binderpooldemo" 9 | minSdkVersion 16 10 | targetSdkVersion 23 11 | versionCode 1 12 | versionName "1.0" 13 | } 14 | buildTypes { 15 | release { 16 | minifyEnabled false 17 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 18 | } 19 | } 20 | } 21 | 22 | dependencies { 23 | compile fileTree(dir: 'libs', include: ['*.jar']) 24 | testCompile 'junit:junit:4.12' 25 | compile 'com.android.support:appcompat-v7:23.3.0' 26 | } 27 | -------------------------------------------------------------------------------- /app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in /Users/wangchenlong/Installations/android-sdk/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | 12 | # If your project uses WebView with JS, uncomment the following 13 | # and specify the fully qualified class name to the JavaScript interface 14 | # class: 15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 16 | # public *; 17 | #} 18 | -------------------------------------------------------------------------------- /app/src/androidTest/java/org/wangchenlong/binderpooldemo/ApplicationTest.java: -------------------------------------------------------------------------------- 1 | package org.wangchenlong.binderpooldemo; 2 | 3 | import android.app.Application; 4 | import android.test.ApplicationTestCase; 5 | 6 | /** 7 | * Testing Fundamentals 8 | */ 9 | public class ApplicationTest extends ApplicationTestCase { 10 | public ApplicationTest() { 11 | super(Application.class); 12 | } 13 | } -------------------------------------------------------------------------------- /app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /app/src/main/aidl/org/wangchenlong/binderpooldemo/IBinderPool.aidl: -------------------------------------------------------------------------------- 1 | // IBinderPool.aidl 2 | package org.wangchenlong.binderpooldemo; 3 | 4 | // Declare any non-default types here with import statements 5 | 6 | interface IBinderPool { 7 | /** 8 | * Demonstrates some basic types that you can use as parameters 9 | * and return values in AIDL. 10 | */ 11 | IBinder queryBinder(int binderCode); 12 | } 13 | -------------------------------------------------------------------------------- /app/src/main/aidl/org/wangchenlong/binderpooldemo/ICompute.aidl: -------------------------------------------------------------------------------- 1 | // ICompute.aidl 2 | package org.wangchenlong.binderpooldemo; 3 | 4 | // Declare any non-default types here with import statements 5 | 6 | interface ICompute { 7 | /** 8 | * Demonstrates some basic types that you can use as parameters 9 | * and return values in AIDL. 10 | */ 11 | int add(int a, int b); 12 | } 13 | -------------------------------------------------------------------------------- /app/src/main/aidl/org/wangchenlong/binderpooldemo/ISecurityCenter.aidl: -------------------------------------------------------------------------------- 1 | // ISecurityCenter.aidl 2 | package org.wangchenlong.binderpooldemo; 3 | 4 | // Declare any non-default types here with import statements 5 | 6 | interface ISecurityCenter { 7 | /** 8 | * Demonstrates some basic types that you can use as parameters 9 | * and return values in AIDL. 10 | */ 11 | String encrypt(String content); 12 | String decrypt(String password); 13 | } 14 | -------------------------------------------------------------------------------- /app/src/main/java/org/wangchenlong/binderpooldemo/BinderPool.java: -------------------------------------------------------------------------------- 1 | package org.wangchenlong.binderpooldemo; 2 | 3 | import android.content.ComponentName; 4 | import android.content.Context; 5 | import android.content.Intent; 6 | import android.content.ServiceConnection; 7 | import android.os.IBinder; 8 | import android.os.RemoteException; 9 | import android.util.Log; 10 | 11 | import java.util.concurrent.CountDownLatch; 12 | 13 | /** 14 | * 连接池实现 15 | *

16 | * Created by wangchenlong on 16/6/17. 17 | */ 18 | public class BinderPool { 19 | 20 | private static final String TAG = "DEBUG-WCL: " + BinderPool.class.getSimpleName(); 21 | 22 | public static final int BINDER_COMPUTE = 0; 23 | public static final int BINDER_SECURITY_CENTER = 1; 24 | 25 | // 编译器每次都需要从主存中读取 26 | private IBinderPool mBinderPool; 27 | private static volatile BinderPool sInstance; 28 | private Context mContext; 29 | 30 | private CountDownLatch mCountDownLatch; // 同步机制 31 | 32 | private BinderPool(Context context) { 33 | mContext = context.getApplicationContext(); 34 | connectBinderPoolService(); 35 | } 36 | 37 | // 单例 38 | public static BinderPool getInstance(Context context) { 39 | if (sInstance == null) { 40 | synchronized (BinderPool.class) { 41 | if (sInstance == null) { 42 | sInstance = new BinderPool(context); 43 | } 44 | } 45 | } 46 | return sInstance; 47 | } 48 | 49 | // 连接服务池 50 | private synchronized void connectBinderPoolService() { 51 | mCountDownLatch = new CountDownLatch(1); // 只保持一个绑定服务 52 | Intent service = new Intent(mContext, BinderPoolService.class); 53 | mContext.bindService(service, mBinderPoolConnection, Context.BIND_AUTO_CREATE); 54 | try { 55 | mCountDownLatch.await(); 56 | } catch (InterruptedException e) { 57 | e.printStackTrace(); 58 | } 59 | } 60 | 61 | // 失效重联机制, 当Binder死亡时, 重新连接 62 | private IBinder.DeathRecipient mDeathRecipient = new IBinder.DeathRecipient() { 63 | @Override public void binderDied() { 64 | Log.e(TAG, "Binder失效"); 65 | mBinderPool.asBinder().unlinkToDeath(mDeathRecipient, 0); 66 | mBinderPool = null; 67 | connectBinderPoolService(); 68 | } 69 | }; 70 | 71 | // Binder的服务连接 72 | private ServiceConnection mBinderPoolConnection = new ServiceConnection() { 73 | @Override public void onServiceConnected(ComponentName name, IBinder service) { 74 | mBinderPool = IBinderPool.Stub.asInterface(service); 75 | try { 76 | mBinderPool.asBinder().linkToDeath(mDeathRecipient, 0); 77 | } catch (RemoteException e) { 78 | e.printStackTrace(); 79 | } 80 | mCountDownLatch.countDown(); 81 | } 82 | 83 | @Override public void onServiceDisconnected(ComponentName name) { 84 | 85 | } 86 | }; 87 | 88 | /** 89 | * 查询Binder 90 | * 91 | * @param binderCode binder代码 92 | * @return Binder 93 | */ 94 | public IBinder queryBinder(int binderCode) { 95 | IBinder binder = null; 96 | try { 97 | if (mBinderPool != null) { 98 | binder = mBinderPool.queryBinder(binderCode); 99 | } 100 | } catch (RemoteException e) { 101 | e.printStackTrace(); 102 | } 103 | 104 | return binder; 105 | } 106 | 107 | /** 108 | * Binder池实现 109 | */ 110 | public static class BinderPoolImpl extends IBinderPool.Stub { 111 | public BinderPoolImpl() { 112 | super(); 113 | } 114 | 115 | @Override public IBinder queryBinder(int binderCode) throws RemoteException { 116 | IBinder binder = null; 117 | switch (binderCode) { 118 | case BINDER_COMPUTE: 119 | binder = new ComputeImpl(); 120 | break; 121 | case BINDER_SECURITY_CENTER: 122 | binder = new SecurityCenterImpl(); 123 | break; 124 | default: 125 | break; 126 | } 127 | return binder; 128 | } 129 | } 130 | } 131 | -------------------------------------------------------------------------------- /app/src/main/java/org/wangchenlong/binderpooldemo/BinderPoolService.java: -------------------------------------------------------------------------------- 1 | package org.wangchenlong.binderpooldemo; 2 | 3 | import android.app.Service; 4 | import android.content.Intent; 5 | import android.os.Binder; 6 | import android.os.IBinder; 7 | import android.support.annotation.Nullable; 8 | import android.util.Log; 9 | 10 | /** 11 | * 连接池 12 | *

13 | * Created by wangchenlong on 16/6/17. 14 | */ 15 | public class BinderPoolService extends Service { 16 | 17 | private static final String TAG = "DEBUG-WCL: " + BinderPoolService.class.getSimpleName(); 18 | 19 | private Binder mBinderPool = new BinderPool.BinderPoolImpl(); // 动态选择Binder 20 | 21 | @Nullable @Override public IBinder onBind(Intent intent) { 22 | Log.e(TAG, "onBind"); 23 | return mBinderPool; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /app/src/main/java/org/wangchenlong/binderpooldemo/ComputeImpl.java: -------------------------------------------------------------------------------- 1 | package org.wangchenlong.binderpooldemo; 2 | 3 | import android.os.RemoteException; 4 | 5 | /** 6 | * 计算实现 7 | *

8 | * Created by wangchenlong on 16/6/17. 9 | */ 10 | public class ComputeImpl extends ICompute.Stub { 11 | @Override public int add(int a, int b) throws RemoteException { 12 | return a + b; 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /app/src/main/java/org/wangchenlong/binderpooldemo/MainActivity.java: -------------------------------------------------------------------------------- 1 | package org.wangchenlong.binderpooldemo; 2 | 3 | import android.os.Bundle; 4 | import android.os.Handler; 5 | import android.os.IBinder; 6 | import android.os.Message; 7 | import android.os.RemoteException; 8 | import android.support.v7.app.AppCompatActivity; 9 | import android.util.Log; 10 | import android.view.View; 11 | import android.widget.TextView; 12 | 13 | public class MainActivity extends AppCompatActivity { 14 | 15 | private static final String TAG = "DEBUG-WCL: " + MainActivity.class.getSimpleName(); 16 | 17 | private ISecurityCenter mISecurityCenter; 18 | private ICompute mICompute; 19 | 20 | private TextView mTvEncryptMsg; // 加密数据的显示 21 | private TextView mTvAddMsg; // 累计数据的显示 22 | 23 | private Handler mHandler = new Handler() { 24 | @Override public void handleMessage(Message msg) { 25 | switch (msg.what) { 26 | case 0: 27 | mTvEncryptMsg.setText((String) msg.obj); 28 | break; 29 | case 1: 30 | mTvAddMsg.setText((String) msg.obj); 31 | break; 32 | default: 33 | break; 34 | } 35 | } 36 | }; 37 | 38 | @Override 39 | protected void onCreate(Bundle savedInstanceState) { 40 | super.onCreate(savedInstanceState); 41 | setContentView(R.layout.activity_main); 42 | mTvEncryptMsg = (TextView) findViewById(R.id.main_tv_encrypt_msg); 43 | mTvAddMsg = (TextView) findViewById(R.id.main_tv_add_msg); 44 | } 45 | 46 | /** 47 | * 加密解密的点击回调 48 | * 49 | * @param view 界面 50 | */ 51 | public void encryptMsg(View view) { 52 | new Thread(new Runnable() { 53 | @Override public void run() { 54 | doEncrypt(); 55 | } 56 | }).start(); 57 | } 58 | 59 | /** 60 | * 调用加密服务 61 | */ 62 | private void doEncrypt() { 63 | BinderPool binderPool = BinderPool.getInstance(getApplicationContext()); 64 | IBinder securityBinder = binderPool.queryBinder(BinderPool.BINDER_SECURITY_CENTER); 65 | mISecurityCenter = SecurityCenterImpl.asInterface(securityBinder); 66 | String msg = "Hello, I am Spike!"; 67 | try { 68 | String encryptMsg = mISecurityCenter.encrypt(msg); 69 | Log.e(TAG, "加密信息: " + encryptMsg); 70 | String decryptMsg = mISecurityCenter.decrypt(encryptMsg); 71 | Log.e(TAG, "解密信息: " + decryptMsg); 72 | Message hm = new Message(); 73 | hm.what = 0; 74 | hm.obj = encryptMsg + "\n" + decryptMsg; 75 | mHandler.sendMessage(hm); 76 | 77 | } catch (RemoteException e) { 78 | e.printStackTrace(); 79 | } 80 | } 81 | 82 | /** 83 | * 加法的点击回调 84 | * 85 | * @param view 视图 86 | */ 87 | public void addNumbers(View view) { 88 | new Thread(new Runnable() { 89 | @Override public void run() { 90 | doAddition(); 91 | } 92 | }).start(); 93 | } 94 | 95 | /** 96 | * 调用加法服务 97 | */ 98 | private void doAddition() { 99 | BinderPool binderPool = BinderPool.getInstance(getApplicationContext()); 100 | IBinder computeBinder = binderPool.queryBinder(BinderPool.BINDER_COMPUTE); 101 | mICompute = ComputeImpl.asInterface(computeBinder); 102 | try { 103 | int result = mICompute.add(12, 12); 104 | Log.e(TAG, "12 + 12 = " + result); 105 | 106 | Message hm = new Message(); 107 | hm.what = 1; 108 | hm.obj = result + ""; 109 | mHandler.sendMessage(hm); 110 | } catch (RemoteException e) { 111 | e.printStackTrace(); 112 | } 113 | } 114 | } 115 | -------------------------------------------------------------------------------- /app/src/main/java/org/wangchenlong/binderpooldemo/SecurityCenterImpl.java: -------------------------------------------------------------------------------- 1 | package org.wangchenlong.binderpooldemo; 2 | 3 | import android.os.RemoteException; 4 | 5 | /** 6 | * 加密算法的实现 7 | *

8 | * Created by wangchenlong on 16/6/17. 9 | */ 10 | public class SecurityCenterImpl extends ISecurityCenter.Stub { 11 | 12 | private static final char SECRET_CODE = 'w'; 13 | 14 | @Override public String encrypt(String content) throws RemoteException { 15 | char[] chars = content.toCharArray(); 16 | for (int i = 0; i < chars.length; i++) { 17 | chars[i] ^= SECRET_CODE; 18 | } 19 | return new String(chars); 20 | } 21 | 22 | @Override public String decrypt(String password) throws RemoteException { 23 | return encrypt(password); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 13 | 14 |