The following is the uProtocol client library that implements uTransport, RpcClient and RpcService defined in uProtocol Java Library using Android Binder. It also includes some commonly used utilities for error handling.
If you are using Gradle, add the following to your build.gradle file’s dependencies:
android {
dependencies {
implementation 'org.eclipse.uprotocol:up-client-android-java::1.5.+'
}
}
UPClient
, by default, establishes a connection to uBus service that is integrated into the system as part of "org.eclipse.uprotocol.core"
package.
If a service that implements IUBus.aidl
interface is integrated in a different package, you should configure the library by specifying that component or just that package.
<resources>
<string name="config_UBusService" translatable="false">com.example.core/.UBusService</string>
</resources>
Before using the UPClient
APIs, a uE must create an instance and connect to uBus.
First create an instance with one of static factory methods:
static UPClient create(Context context, Handler handler, ServiceLifecycleListener listener)
static UPClient create(Context context, Executor executor, ServiceLifecycleListener listener)
static UPClient create(Context context, UEntity entity, Handler handler, ServiceLifecycleListener listener)
static UPClient create(Context context, UEntity entity, Executor executor, ServiceLifecycleListener listener)
context
is an application context.
entity
is information about uE containing its name and major version (MUST match the meta data in the manifest).
handler
is a handler on which callbacks should execute, or null to execute on the application’s main thread.
executor
is an executor on which callbacks should execute, or null to execute on the application’s main thread executor.
listener
is a listener for monitoring uBus lifecycle.
Note
|
Every Android uE MUST declare its name and major version in the manifest. |
For the example below you may use any create(…)
factory method.
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="org.eclipse.uprotocol.example.client">
...
<application android:label="@string/app_name" ...>
<meta-data
android:name="uprotocol.entity.name"
android:value="example.client" />
<meta-data
android:name="uprotocol.entity.version"
android:value="1" />
<activity
android:name=".ExampleActivity">
</activity>
</application>
</manifest>
For the next example you should create a separate instance of UPClient
for each uE using create(…, UEntity entity,…)
factory method.
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="org.eclipse.uprotocol.example.service.lighting">
...
<application android:label="@string/app_name">
<service
android:name=".ExteriorLightingService"
... >
<meta-data
android:name="uprotocol.entity.name"
android:value="body.lighting.exterior" />
<meta-data
android:name="uprotocol.entity.version"
android:value="1" />
</service>
<service
android:name=".InteriorLightingService"
... >
<meta-data
android:name="uprotocol.entity.name"
android:value="body.lighting.interior" />
<meta-data
android:name="uprotocol.entity.version"
android:value="1" />
</service>
</application>
</manifest>
Then connect to uBus using a reactive API below:
CompletionStage<UStatus> connect()
When you are done with the UPClient
you should disconnect from uBus:
CompletionStage<UStatus> disconnect()
You cannot use other methods until the UPClient
is connected. When this happens the CompletionStage<UStatus>
returned by connect() will be completed and you also will receive the onLifecycleChanged(…, true)
callback on your service lifecycle listener. You may query the connected status using these methods:
boolean isDisconnected()
boolean isConnecting()
boolean isConnected()
For both, publisher/subscriber or observer (notification) design patterns, a uE should use the UPClient
to send messages to consumers using any method below:
UStatus send(UUri source, UPayload payload, UAttributes attributes)
UStatus send(UMessage message)
In order to start receiving messages, a consumer should register a listener for a topic:
UStatus registerListener(UUri topic, UListener listener)
For the publisher/subscriber design pattern, the precondition for a callback is that the uE needs to subscribe to the topic AND register the listener.
Given the precondition, the callback will be triggered in any of the following cases:
-
As soon as listener is registered if there is already a sent message for that topic that is in cache, OR
-
Whenever the producer sends a new message for that topic
For the notification design pattern, the only precondition is that uE needs to register the listener. Once the listener is registered the callback will be triggered whenever the notification message is sent by the producer.
A consumer can use the same listener for multiple topics, or register different listeners to the same topic.
To unregister a listener from receiving topic messages:
UStatus unregisterListener(UUri topic, UListener listener)
To unregister a listener from all topics:
UStatus unregisterListener(UListener listener)
A uE with a service role should register a listener for a particular method URI to be notified when request messages are sent against said method.
Note
|
Only one listener is allowed to be registered per a method URI. |
UStatus registerRpcListener(UUri methodUri, URpcListener listener)
To stop processing request messages for a specific method URI or all of the, a service uE should unregister the listener:
UStatus unregisterRpcListener(UUri methodUri, URpcListener listener)
UStatus unregisterRpcListener(URpcListener listener)
Code generators for uProtocol services defined in proto files primarily utilize the following method. However, clients also have the option to directly use it for invoking RPC methods.
CompletionStage<UPayload> invokeMethod(UUri methodUri, UPayload requestPayload, CallOptions options)
The Android Gradle Plugin provides several standard tasks that are commonly used in Android projects. To view the complete list, you can use the following command:
gradlew tasks
The following outlines some of the standard tasks employed in the development process:
-
clean: Deletes the build directory.
-
build: Assembles and tests this project.
-
lintAnalyzeRelease: Run lint analysis on the release variant.
-
jacocoTestReport: Generate Jacoco coverage reports.
-
connectedDebugAndroidTest: Installs and runs the tests for debug on connected devices.
-
publishReleasePublicationToMavenLocal: Publishes Maven publication 'release' to the local Maven repository.