You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

README.md 7.4 KiB

3 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243
  1. [![Build Status](https://travis-ci.org/codezjx/AndLinker.svg?branch=master)](https://travis-ci.org/codezjx/AndLinker)
  2. [![JCenter](https://api.bintray.com/packages/codezjx/maven/and-linker/images/download.svg)](https://bintray.com/codezjx/maven/and-linker/_latestVersion)
  3. [![License](https://img.shields.io/badge/License-Apache%20License%202.0-blue.svg)](http://www.apache.org/licenses/LICENSE-2.0)
  4. # AndLinker
  5. [中文文档](README_CN.md)
  6. ## Introduction
  7. AndLinker is a IPC(Inter-Process Communication) library for Android, which combines the features of [AIDL][aidl] and [Retrofit][retrofit]. Allows IPC call seamlessly compose with [RxJava][rxjava] and [RxJava2][rxjava2] call adapters. Project design and partial code refer to the great project [Retrofit][retrofit].
  8. ## Setup
  9. Add the `jcenter()` repository in your root `build.gradle`.
  10. ```groovy
  11. allprojects {
  12. repositories {
  13. jcenter()
  14. }
  15. }
  16. ```
  17. Add the dependencies in your app level `build.gradle`.
  18. ```groovy
  19. dependencies {
  20. implementation 'com.codezjx.library:andlinker:0.7.1'
  21. }
  22. ```
  23. ## Features
  24. - Define normal Java Interface instead of AIDL Interface
  25. - Generates the IPC implementation of the remote service interface like [Retrofit][retrofit]
  26. - Support call adapter: `Call`, [RxJava][rxjava] `Observable`, [RxJava2][rxjava2] `Observable` & `Flowable`
  27. - Support remote service callback
  28. - Support all AIDL data types
  29. - Support all AIDL directional tag, either `in`, `out`, or `inout`
  30. - Support the AIDL `oneway` keyword
  31. ## Getting Started
  32. Define a normal java Interface with `@RemoteInterface` annotation, and implements the interface.
  33. ```java
  34. @RemoteInterface
  35. public interface IRemoteService {
  36. int getPid();
  37. void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat,
  38. double aDouble, String aString);
  39. }
  40. private final IRemoteService mRemoteService = new IRemoteService() {
  41. @Override
  42. public int getPid() {
  43. return android.os.Process.myPid();
  44. }
  45. @Override
  46. public void basicTypes(int anInt, long aLong, boolean aBoolean,
  47. float aFloat, double aDouble, String aString) {
  48. // Does something
  49. }
  50. };
  51. ```
  52. In your server app, create the `AndLinkerBinder` object and register interface implementation above, then expose the linker binder to clients.
  53. ```java
  54. private AndLinkerBinder mLinkerBinder;
  55. public class RemoteService extends Service {
  56. @Override
  57. public void onCreate() {
  58. super.onCreate();
  59. mLinkerBinder = AndLinkerBinder.Factory.newBinder();
  60. mLinkerBinder.registerObject(mRemoteService);
  61. }
  62. @Override
  63. public IBinder onBind(Intent intent) {
  64. return mLinkerBinder;
  65. }
  66. }
  67. ```
  68. In your client app, create the `AndLinker` object and generates an implementation of the `IRemoteService` interface.
  69. ```java
  70. public class BindingActivity extends Activity {
  71. private AndLinker mLinker;
  72. private IRemoteService mRemoteService;
  73. @Override
  74. protected void onCreate(@Nullable Bundle savedInstanceState) {
  75. super.onCreate(savedInstanceState);
  76. mLinker = new AndLinker.Builder(this)
  77. .packageName("com.example.andlinker")
  78. .action("com.example.andlinker.REMOTE_SERVICE_ACTION")
  79. .build();
  80. mLinker.bind();
  81. mRemoteService = mLinker.create(IRemoteService.class);
  82. }
  83. @Override
  84. protected void onDestroy() {
  85. super.onDestroy();
  86. mLinker.unbind();
  87. }
  88. }
  89. ```
  90. Now your client app is ready, all methods from the created `IRemoteService` are IPC methods, call it directly!
  91. ```java
  92. int pid = mRemoteService.getPid();
  93. mRemoteService.basicTypes(1, 2L, true, 3.0f, 4.0d, "str");
  94. ```
  95. ## Supported data types
  96. AndLinker supports all AIDL data types:
  97. - All primitive types in the Java programming language (such as `int`, `long`, `char`, `boolean`, and so on)
  98. - `String`
  99. - `CharSequence`
  100. - `Parcelable`
  101. - `List` (All elements in the List must be one of the supported data types in this list)
  102. - `Map` (All elements in the Map must be one of the supported data types in this list)
  103. ## Advanced
  104. ### Call Adapters
  105. You can modify the client side app's remote service interface, wrap the return type of the method.
  106. ```java
  107. @RemoteInterface
  108. public interface IRemoteService {
  109. Observable<Integer> getPid();
  110. Call<Void> basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat,
  111. double aDouble, String aString);
  112. }
  113. ```
  114. Register the call adapter factory in `AndLinker.Builder`, the remaining steps are consistent with [Retrofit][retrofit].
  115. ```java
  116. new AndLinker.Builder(this)
  117. ...
  118. .addCallAdapterFactory(OriginalCallAdapterFactory.create()) // Basic
  119. .addCallAdapterFactory(RxJava2CallAdapterFactory.create()) // RxJava2
  120. .build();
  121. ```
  122. ### Deal with callbacks
  123. Define callback interface to receive callbacks from the remote service with `@RemoteInterface` annotation.
  124. ```java
  125. @RemoteInterface
  126. public interface IRemoteCallback {
  127. void onValueChange(int value);
  128. }
  129. ```
  130. Use `@Callback` annotation for callback parameter.
  131. ```java
  132. void registerCallback(@Callback IRemoteCallback callback);
  133. ```
  134. In your client app, implements the remote callback and register to `AndLinker`, and that's it!
  135. ```java
  136. private final IRemoteCallback mRemoteCallback = new IRemoteCallback() {
  137. @Override
  138. public void onValueChange(int value) {
  139. // Invoke when server side callback
  140. }
  141. };
  142. mLinker.registerObject(mRemoteCallback);
  143. ```
  144. ### Specify directional tag
  145. You can specify `@In`, `@Out`, or `@Inout` annotation for parameter, indicating which way the data goes, same as AIDL.
  146. ```java
  147. void directionalParamMethod(@In KeyEvent event, @Out int[] arr, @Inout Rect rect);
  148. ```
  149. >**Caution**:
  150. >- All non-primitive parameters require a directional annotation indicating which way the data goes. Either `@In`, `@Out`, or `@Inout`. Primitives are `@In` by default, and cannot be otherwise.
  151. >- Parcelable parameter with `@Out` or `@Inout` annotation must implements from `SuperParcelable`, or you must add method `public void readFromParcel(Parcel in)` by yourself.
  152. ### Use `@OneWay` annotation
  153. You can use `@OneWay` for a method which modifies the behavior of remote calls. When used, a remote call does not block, it simply sends the transaction data and immediately returns, same as AIDL.
  154. ```java
  155. @OneWay
  156. void onewayMethod(String msg);
  157. ```
  158. ## Proguard Configuration
  159. Add following rules to `proguard-rules.pro` file, keep classes that will be serialized/deserialized over AndLinker.
  160. ```
  161. -keep class com.example.andlinker.model.** {
  162. public void readFromParcel(android.os.Parcel);
  163. }
  164. ```
  165. ## Feedback
  166. Any issues or PRs are welcome!
  167. ## License
  168. Copyright 2018 codezjx <code.zjx@gmail.com>
  169. Licensed under the Apache License, Version 2.0 (the "License");
  170. you may not use this file except in compliance with the License.
  171. You may obtain a copy of the License at
  172. http://www.apache.org/licenses/LICENSE-2.0
  173. Unless required by applicable law or agreed to in writing, software
  174. distributed under the License is distributed on an "AS IS" BASIS,
  175. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  176. See the License for the specific language governing permissions and
  177. limitations under the License.
  178. [retrofit]: https://github.com/square/retrofit
  179. [rxjava]: https://github.com/ReactiveX/RxJava/tree/1.x
  180. [rxjava2]: https://github.com/ReactiveX/RxJava/tree/2.x
  181. [aidl]: https://developer.android.com/guide/components/aidl.html