halnp java分词,Android native进程间通信实例-binder篇之——HAL层访问JAVA层的服务

favicon.ico摘要:

rvicesManager.javacaseTRANSACTION_isSpellCheckerEnabled:{data.enforceInterface(DESCRIPTOR);boolean_result=this.isSpellCheckerEnabled();reply.writeNoException();reply.writeInt(((_result)?(1):(0)));retu

有一天在群里聊天的时候,有人提出一个问题,怎样才能做到HAL层访问JAVA层的接口?刚好我不会,所以做了一点研究。

gt;#include#defineLOG_TAG"binderclient"usingnamespaceandroid;intmain(intargc,char**ar

inder.FIRST_CALL_TRANSACTION*/1+7);spITextServicesBinder=defaultServiceManager()->

e.java中有一行 publicclassTextServicesManagerServiceextendsITextServicesManager.Stub,所以我从 ITex

e.java中有一行 publicclassTextServicesManagerServiceextendsITextServicesManager.Stub,所以我从 ITex

e.java中有一行 publicclassTextServicesManagerServiceextendsITextServicesManager.Stub,所以我从 ITex

t;List>(){})cityIds.stream().map{cityId->valcityListenableFuture=asyncHttpClient.p

.javacaseTRANSACTION_isSpellCheckerEnabled:{data.enforceInterface(DESCRIPTOR);boolean_result=this.is

码:valcityIdsFlux:Flux=getCityIds()valcitiesFlux:Flux=cityIdsFlux.flatMap{thi

ence>(){})l}}复制代码在这里,我使用thenApply运算符将CompletableFuture转换为Comp

码很容易理解;但是,涉及八个阻塞调用:获取7个城市ID的列表,然后获取每个城市的详细信息获取7个城市的详细信息每一个调用都将在不同的线程上。3.非阻塞IO回调我将使用AsyncHttpClient库来

码很容易理解;但是,涉及八个阻塞调用:获取7个城市ID的列表,然后获取每个城市的详细信息获取7个城市的详细信息每一个调用都将在不同的线程上。3.非阻塞IO回调我将使用AsyncHttpClient库来

gt;#include#defineLOG_TAG"binderclient"usingnamespaceandroid;intmain(intargc,char**ar

gt;#include#defineLOG_TAG"binderclient"usingnamespaceandroid;intmain(intargc,char**ar

之前的文章末尾部分说过了service call 可以用来调试系统的binder服务。 传送门: Android native进程间通信实例-binder篇之——简单的单工通信

gt;#include#defineLOG_TAG"binderclient"usingnamespaceandroid;intmain(intargc,char**ar

这次可以用到这个命令了!

gt;#include#defineLOG_TAG"binderclient"usingnamespaceandroid;intmain(intargc,char**ar

inder.FIRST_CALL_TRANSACTION*/1+7);spITextServicesBinder=defaultServiceManager()->

e.java中有一行 publicclassTextServicesManagerServiceextendsITextServicesManager.Stub,所以我从 ITex

e.java中有一行 publicclassTextServicesManagerServiceextendsITextServicesManager.Stub,所以我从 ITex

e.java中有一行 publicclassTextServicesManagerServiceextendsITextServicesManager.Stub,所以我从 ITex

t;List>(){})cityIds.stream().map{cityId->valcityListenableFuture=asyncHttpClient.p

.javacaseTRANSACTION_isSpellCheckerEnabled:{data.enforceInterface(DESCRIPTOR);boolean_result=this.is

码:valcityIdsFlux:Flux=getCityIds()valcitiesFlux:Flux=cityIdsFlux.flatMap{thi

ence>(){})l}}复制代码在这里,我使用thenApply运算符将CompletableFuture转换为Comp

码很容易理解;但是,涉及八个阻塞调用:获取7个城市ID的列表,然后获取每个城市的详细信息获取7个城市的详细信息每一个调用都将在不同的线程上。3.非阻塞IO回调我将使用AsyncHttpClient库来

码很容易理解;但是,涉及八个阻塞调用:获取7个城市ID的列表,然后获取每个城市的详细信息获取7个城市的详细信息每一个调用都将在不同的线程上。3.非阻塞IO回调我将使用AsyncHttpClient库来

gt;#include#defineLOG_TAG"binderclient"usingnamespaceandroid;intmain(intargc,char**ar

gt;#include#defineLOG_TAG"binderclient"usingnamespaceandroid;intmain(intargc,char**ar

1. 随机选取一个java层的服务。

gt;#include#defineLOG_TAG"binderclient"usingnamespaceandroid;intmain(intargc,char**ar

adb shell 中输入命令 service list,选取一个服务来做研究,这次看中的是 textservices, 注意第一个服务 bysysui 后面的 "[ ]" 里面没有内容,不能选取这样的服务来做这次的研究。

gt;#include#defineLOG_TAG"binderclient"usingnamespaceandroid;intmain(intargc,char**ar

1608da91-27c2-41d6-b0f1-9deb6619b7ae.jpg

码很容易理解;但是,涉及八个阻塞调用:获取7个城市ID的列表,然后获取每个城市的详细信息获取7个城市的详细信息每一个调用都将在不同的线程上。3.非阻塞IO回调我将使用AsyncHttpClient库来

inder.FIRST_CALL_TRANSACTION*/1+7);spITextServicesBinder=defaultServiceManager()->

e.java中有一行 publicclassTextServicesManagerServiceextendsITextServicesManager.Stub,所以我从 ITex

e.java中有一行 publicclassTextServicesManagerServiceextendsITextServicesManager.Stub,所以我从 ITex

e.java中有一行 publicclassTextServicesManagerServiceextendsITextServicesManager.Stub,所以我从 ITex

t;List>(){})cityIds.stream().map{cityId->valcityListenableFuture=asyncHttpClient.p

.javacaseTRANSACTION_isSpellCheckerEnabled:{data.enforceInterface(DESCRIPTOR);boolean_result=this.is

码:valcityIdsFlux:Flux=getCityIds()valcitiesFlux:Flux=cityIdsFlux.flatMap{thi

ence>(){})l}}复制代码在这里,我使用thenApply运算符将CompletableFuture转换为Comp

码很容易理解;但是,涉及八个阻塞调用:获取7个城市ID的列表,然后获取每个城市的详细信息获取7个城市的详细信息每一个调用都将在不同的线程上。3.非阻塞IO回调我将使用AsyncHttpClient库来

码很容易理解;但是,涉及八个阻塞调用:获取7个城市ID的列表,然后获取每个城市的详细信息获取7个城市的详细信息每一个调用都将在不同的线程上。3.非阻塞IO回调我将使用AsyncHttpClient库来

gt;#include#defineLOG_TAG"binderclient"usingnamespaceandroid;intmain(intargc,char**ar

gt;#include#defineLOG_TAG"binderclient"usingnamespaceandroid;intmain(intargc,char**ar

2. 搜寻这个服务相关的源码。

码很容易理解;但是,涉及八个阻塞调用:获取7个城市ID的列表,然后获取每个城市的详细信息获取7个城市的详细信息每一个调用都将在不同的线程上。3.非阻塞IO回调我将使用AsyncHttpClient库来

frameworks/base/services/core/java/com/android/server/TextServicesManagerService.java

码很容易理解;但是,涉及八个阻塞调用:获取7个城市ID的列表,然后获取每个城市的详细信息获取7个城市的详细信息每一个调用都将在不同的线程上。3.非阻塞IO回调我将使用AsyncHttpClient库来

frameworks/base/core/java/com/android/internal/textservice/ITextServicesManager.aidl

码很容易理解;但是,涉及八个阻塞调用:获取7个城市ID的列表,然后获取每个城市的详细信息获取7个城市的详细信息每一个调用都将在不同的线程上。3.非阻塞IO回调我将使用AsyncHttpClient库来

out/target/common/obj/JAVA_LIBRARIES/framework_intermediates/src/core/java/com/android/internal/textservice/ITextServicesManager.java

码很容易理解;但是,涉及八个阻塞调用:获取7个城市ID的列表,然后获取每个城市的详细信息获取7个城市的详细信息每一个调用都将在不同的线程上。3.非阻塞IO回调我将使用AsyncHttpClient库来

inder.FIRST_CALL_TRANSACTION*/1+7);spITextServicesBinder=defaultServiceManager()->

e.java中有一行 publicclassTextServicesManagerServiceextendsITextServicesManager.Stub,所以我从 ITex

e.java中有一行 publicclassTextServicesManagerServiceextendsITextServicesManager.Stub,所以我从 ITex

e.java中有一行 publicclassTextServicesManagerServiceextendsITextServicesManager.Stub,所以我从 ITex

t;List>(){})cityIds.stream().map{cityId->valcityListenableFuture=asyncHttpClient.p

.javacaseTRANSACTION_isSpellCheckerEnabled:{data.enforceInterface(DESCRIPTOR);boolean_result=this.is

码:valcityIdsFlux:Flux=getCityIds()valcitiesFlux:Flux=cityIdsFlux.flatMap{thi

ence>(){})l}}复制代码在这里,我使用thenApply运算符将CompletableFuture转换为Comp

码很容易理解;但是,涉及八个阻塞调用:获取7个城市ID的列表,然后获取每个城市的详细信息获取7个城市的详细信息每一个调用都将在不同的线程上。3.非阻塞IO回调我将使用AsyncHttpClient库来

码很容易理解;但是,涉及八个阻塞调用:获取7个城市ID的列表,然后获取每个城市的详细信息获取7个城市的详细信息每一个调用都将在不同的线程上。3.非阻塞IO回调我将使用AsyncHttpClient库来

gt;#include#defineLOG_TAG"binderclient"usingnamespaceandroid;intmain(intargc,char**ar

gt;#include#defineLOG_TAG"binderclient"usingnamespaceandroid;intmain(intargc,char**ar

3. 选择一个接口用于被 HAL 层的代码访问

ence>(){})l}}复制代码在这里,我使用thenApply运算符将CompletableFuture转换为Comp

可以知道TextServicesManagerService.java 中 有一行 public class TextServicesManagerService extends ITextServicesManager.Stub,

ence>(){})l}}复制代码在这里,我使用thenApply运算符将CompletableFuture转换为Comp

所以我从 ITextServicesManager.aidl 来选择要访问的接口, 这次选的就是 boolean isSpellCheckerEnabled(); 这个函数应该就是返回一个bool变量而已,越简单越好。

ence>(){})l}}复制代码在这里,我使用thenApply运算符将CompletableFuture转换为Comp

inder.FIRST_CALL_TRANSACTION*/1+7);spITextServicesBinder=defaultServiceManager()->

e.java中有一行 publicclassTextServicesManagerServiceextendsITextServicesManager.Stub,所以我从 ITex

e.java中有一行 publicclassTextServicesManagerServiceextendsITextServicesManager.Stub,所以我从 ITex

e.java中有一行 publicclassTextServicesManagerServiceextendsITextServicesManager.Stub,所以我从 ITex

t;List>(){})cityIds.stream().map{cityId->valcityListenableFuture=asyncHttpClient.p

.javacaseTRANSACTION_isSpellCheckerEnabled:{data.enforceInterface(DESCRIPTOR);boolean_result=this.is

码:valcityIdsFlux:Flux=getCityIds()valcitiesFlux:Flux=cityIdsFlux.flatMap{thi

ence>(){})l}}复制代码在这里,我使用thenApply运算符将CompletableFuture转换为Comp

码很容易理解;但是,涉及八个阻塞调用:获取7个城市ID的列表,然后获取每个城市的详细信息获取7个城市的详细信息每一个调用都将在不同的线程上。3.非阻塞IO回调我将使用AsyncHttpClient库来

码很容易理解;但是,涉及八个阻塞调用:获取7个城市ID的列表,然后获取每个城市的详细信息获取7个城市的详细信息每一个调用都将在不同的线程上。3.非阻塞IO回调我将使用AsyncHttpClient库来

gt;#include#defineLOG_TAG"binderclient"usingnamespaceandroid;intmain(intargc,char**ar

gt;#include#defineLOG_TAG"binderclient"usingnamespaceandroid;intmain(intargc,char**ar

4. 搜寻 binder 中 transact 需要输入的 code

ence>(){})l}}复制代码在这里,我使用thenApply运算符将CompletableFuture转换为Comp

因为吧啦吧啦的原因(可以自行去别的博文搜索原理,本系列博文侧重实际操作),所以在out目录下可以获取到每个服务中各个接口访问锁需要传入的code。

ence>(){})l}}复制代码在这里,我使用thenApply运算符将CompletableFuture转换为Comp

在out/target/common/obj/JAVA_LIBRARIES/framework_intermediates/src/core/java/com/android/internal/textservice/ITextServicesManager.java中可以发现熟悉的onTransact接口,

ence>(){})l}}复制代码在这里,我使用thenApply运算符将CompletableFuture转换为Comp

同时发现调用 sSpellCheckerEnabled 的code为TRANSACTION_isSpellCheckerEnabled,

码:valcityIdsFlux:Flux=getCityIds()valcitiesFlux:Flux=cityIdsFlux.flatMap{thi

它的定义是:static final int TRANSACTION_isSpellCheckerEnabled = (android.os.IBinder.FIRST_CALL_TRANSACTION + 7);

码:valcityIdsFlux:Flux=getCityIds()valcitiesFlux:Flux=cityIdsFlux.flatMap{thi

因为android.os.IBinder.FIRST_CALL_TRANSACTION的值是1, 所以可知code为 8

码:valcityIdsFlux:Flux=getCityIds()valcitiesFlux:Flux=cityIdsFlux.flatMap{thi

inder.FIRST_CALL_TRANSACTION*/1+7);spITextServicesBinder=defaultServiceManager()->

e.java中有一行 publicclassTextServicesManagerServiceextendsITextServicesManager.Stub,所以我从 ITex

e.java中有一行 publicclassTextServicesManagerServiceextendsITextServicesManager.Stub,所以我从 ITex

e.java中有一行 publicclassTextServicesManagerServiceextendsITextServicesManager.Stub,所以我从 ITex

t;List>(){})cityIds.stream().map{cityId->valcityListenableFuture=asyncHttpClient.p

.javacaseTRANSACTION_isSpellCheckerEnabled:{data.enforceInterface(DESCRIPTOR);boolean_result=this.is

码:valcityIdsFlux:Flux=getCityIds()valcitiesFlux:Flux=cityIdsFlux.flatMap{thi

ence>(){})l}}复制代码在这里,我使用thenApply运算符将CompletableFuture转换为Comp

码很容易理解;但是,涉及八个阻塞调用:获取7个城市ID的列表,然后获取每个城市的详细信息获取7个城市的详细信息每一个调用都将在不同的线程上。3.非阻塞IO回调我将使用AsyncHttpClient库来

码很容易理解;但是,涉及八个阻塞调用:获取7个城市ID的列表,然后获取每个城市的详细信息获取7个城市的详细信息每一个调用都将在不同的线程上。3.非阻塞IO回调我将使用AsyncHttpClient库来

gt;#include#defineLOG_TAG"binderclient"usingnamespaceandroid;intmain(intargc,char**ar

gt;#include#defineLOG_TAG"binderclient"usingnamespaceandroid;intmain(intargc,char**ar

5. 使用service call 来撩一下 isSpellCheckerEnabled

码:valcityIdsFlux:Flux=getCityIds()valcitiesFlux:Flux=cityIdsFlux.flatMap{thi

1961bf35-ba5c-4c00-9252-2532849512bc.jpg

.javacaseTRANSACTION_isSpellCheckerEnabled:{data.enforceInterface(DESCRIPTOR);boolean_result=this.is

可以看到Parcel有两个值,第一个是00000000,第二个是00000001.

.javacaseTRANSACTION_isSpellCheckerEnabled:{data.enforceInterface(DESCRIPTOR);boolean_result=this.is

再看看ITextServicesManager.java中TRANSACTION_isSpellCheckerEnabled这个code的处理,果然write了两次,而第二次writeInt的值就是我们需要获取的bool值了!

.javacaseTRANSACTION_isSpellCheckerEnabled:{data.enforceInterface(DESCRIPTOR);boolean_result=this.is

inder.FIRST_CALL_TRANSACTION*/1+7);spITextServicesBinder=defaultServiceManager()->

e.java中有一行 publicclassTextServicesManagerServiceextendsITextServicesManager.Stub,所以我从 ITex

e.java中有一行 publicclassTextServicesManagerServiceextendsITextServicesManager.Stub,所以我从 ITex

e.java中有一行 publicclassTextServicesManagerServiceextendsITextServicesManager.Stub,所以我从 ITex

t;List>(){})cityIds.stream().map{cityId->valcityListenableFuture=asyncHttpClient.p

.javacaseTRANSACTION_isSpellCheckerEnabled:{data.enforceInterface(DESCRIPTOR);boolean_result=this.is

码:valcityIdsFlux:Flux=getCityIds()valcitiesFlux:Flux=cityIdsFlux.flatMap{thi

ence>(){})l}}复制代码在这里,我使用thenApply运算符将CompletableFuture转换为Comp

码很容易理解;但是,涉及八个阻塞调用:获取7个城市ID的列表,然后获取每个城市的详细信息获取7个城市的详细信息每一个调用都将在不同的线程上。3.非阻塞IO回调我将使用AsyncHttpClient库来

码很容易理解;但是,涉及八个阻塞调用:获取7个城市ID的列表,然后获取每个城市的详细信息获取7个城市的详细信息每一个调用都将在不同的线程上。3.非阻塞IO回调我将使用AsyncHttpClient库来

gt;#include#defineLOG_TAG"binderclient"usingnamespaceandroid;intmain(intargc,char**ar

gt;#include#defineLOG_TAG"binderclient"usingnamespaceandroid;intmain(intargc,char**ar

ITextServicesManager.java

.javacaseTRANSACTION_isSpellCheckerEnabled:{data.enforceInterface(DESCRIPTOR);boolean_result=this.is

case TRANSACTION_isSpellCheckerEnabled:

{

data.enforceInterface(DESCRIPTOR);

boolean _result = this.isSpellCheckerEnabled();

reply.writeNoException();

reply.writeInt(((_result)?(1):(0)));

return true;

}

使用了一个名为CompletableFuture.allOf的运算符,它返回一个“Void”类型,并且必须强制返回所需类型的CompletableFuture

城市的详细信息,例如,当使用ID为1——“/cities/1”调用时:{"country":"USA","id":1,"name":"Portland"

城市的详细信息,例如,当使用ID为1——“/cities/1”调用时:{"country":"USA","id":1,"name":"Portland"

1. 首先data.enforceInterface 传进去了一个组字符串 private static final java.lang.String DESCRIPTOR = "com.android.internal.textservice.ITextServicesManager";

城市的详细信息,例如,当使用ID为1——“/cities/1”调用时:{"country":"USA","id":1,"name":"Portland"

感觉这组字符串是和校验有关了,查看了Parcel.cpp 源码, 发现enforceInterface果然是对比字符串用的,在这个接口的上面有个接口名字叫做 writeInterfaceToken,

城市的详细信息,例如,当使用ID为1——“/cities/1”调用时:{"country":"USA","id":1,"name":"Portland"

所以到时候要用 writeInterfaceToken 来写这组字符串用于比对校验。

t;List>(){})cityIds.stream().map{cityId->valcityListenableFuture=asyncHttpClient.p

2. writeNoException 和 writeInt 最终调用的是 Parcel.cpp 里面writeInt32,所以reply部分要 readInt32 两次。

t;List>(){})cityIds.stream().map{cityId->valcityListenableFuture=asyncHttpClient.p

inder.FIRST_CALL_TRANSACTION*/1+7);spITextServicesBinder=defaultServiceManager()->

e.java中有一行 publicclassTextServicesManagerServiceextendsITextServicesManager.Stub,所以我从 ITex

e.java中有一行 publicclassTextServicesManagerServiceextendsITextServicesManager.Stub,所以我从 ITex

e.java中有一行 publicclassTextServicesManagerServiceextendsITextServicesManager.Stub,所以我从 ITex

t;List>(){})cityIds.stream().map{cityId->valcityListenableFuture=asyncHttpClient.p

.javacaseTRANSACTION_isSpellCheckerEnabled:{data.enforceInterface(DESCRIPTOR);boolean_result=this.is

码:valcityIdsFlux:Flux=getCityIds()valcitiesFlux:Flux=cityIdsFlux.flatMap{thi

ence>(){})l}}复制代码在这里,我使用thenApply运算符将CompletableFuture转换为Comp

码很容易理解;但是,涉及八个阻塞调用:获取7个城市ID的列表,然后获取每个城市的详细信息获取7个城市的详细信息每一个调用都将在不同的线程上。3.非阻塞IO回调我将使用AsyncHttpClient库来

码很容易理解;但是,涉及八个阻塞调用:获取7个城市ID的列表,然后获取每个城市的详细信息获取7个城市的详细信息每一个调用都将在不同的线程上。3.非阻塞IO回调我将使用AsyncHttpClient库来

gt;#include#defineLOG_TAG"binderclient"usingnamespaceandroid;intmain(intargc,char**ar

gt;#include#defineLOG_TAG"binderclient"usingnamespaceandroid;intmain(intargc,char**ar

6. HAL层代码怎么写

使用了一个名为CompletableFuture.allOf的运算符,它返回一个“Void”类型,并且必须强制返回所需类型的CompletableFuture

就直接在之前写的mybinderclient.cpp 上面贴源码吧transct 前写校验字符串,然后传入code 值为8,最后readInt32 两次,第二次就是要读取的JAVA 层服务isSpellCheckerEnabled  的值啦!

使用了一个名为CompletableFuture.allOf的运算符,它返回一个“Void”类型,并且必须强制返回所需类型的CompletableFuture

#include

#include

#include

#include

#include

#define LOG_TAG "binderclient"

using namespace android;

int main(int argc, char** argv)

{

static int TRANSACTION_isSpellCheckerEnabled = (/*android.os.IBinder.FIRST_CALL_TRANSACTION*/1 + 7);

sp ITextServicesBinder = defaultServiceManager()->getService(String16("textservices"));

Parcel ITextServicesData, ITextServicesReply;

ITextServicesData.writeInterfaceToken(String16("com.android.internal.textservice.ITextServicesManager"));

ITextServicesBinder->transact(TRANSACTION_isSpellCheckerEnabled, ITextServicesData, &ITextServicesReply);

int ret = ITextServicesReply.readInt32();

int ret2 = ITextServicesReply.readInt32();

printf("ret = %d, isSpellCheckerEnabled = %d

", ret, ret2);

return 0;

}

使用了一个名为CompletableFuture.allOf的运算符,它返回一个“Void”类型,并且必须强制返回所需类型的CompletableFuture

城市的详细信息,例如,当使用ID为1——“/cities/1”调用时:{"country":"USA","id":1,"name":"Portland"

执行结果:

使用了一个名为CompletableFuture.allOf的运算符,它返回一个“Void”类型,并且必须强制返回所需类型的CompletableFuture

57cce1bb-4629-40ae-8ba6-3c9dacdd31d7.jpg

e.java中有一行 publicclassTextServicesManagerServiceextendsITextServicesManager.Stub,所以我从 ITex

inder.FIRST_CALL_TRANSACTION*/1+7);spITextServicesBinder=defaultServiceManager()->

e.java中有一行 publicclassTextServicesManagerServiceextendsITextServicesManager.Stub,所以我从 ITex

e.java中有一行 publicclassTextServicesManagerServiceextendsITextServicesManager.Stub,所以我从 ITex

e.java中有一行 publicclassTextServicesManagerServiceextendsITextServicesManager.Stub,所以我从 ITex

t;List>(){})cityIds.stream().map{cityId->valcityListenableFuture=asyncHttpClient.p

.javacaseTRANSACTION_isSpellCheckerEnabled:{data.enforceInterface(DESCRIPTOR);boolean_result=this.is

码:valcityIdsFlux:Flux=getCityIds()valcitiesFlux:Flux=cityIdsFlux.flatMap{thi

ence>(){})l}}复制代码在这里,我使用thenApply运算符将CompletableFuture转换为Comp

码很容易理解;但是,涉及八个阻塞调用:获取7个城市ID的列表,然后获取每个城市的详细信息获取7个城市的详细信息每一个调用都将在不同的线程上。3.非阻塞IO回调我将使用AsyncHttpClient库来

码很容易理解;但是,涉及八个阻塞调用:获取7个城市ID的列表,然后获取每个城市的详细信息获取7个城市的详细信息每一个调用都将在不同的线程上。3.非阻塞IO回调我将使用AsyncHttpClient库来

gt;#include#defineLOG_TAG"binderclient"usingnamespaceandroid;intmain(intargc,char**ar

gt;#include#defineLOG_TAG"binderclient"usingnamespaceandroid;intmain(intargc,char**ar

inder.FIRST_CALL_TRANSACTION*/1+7);spITextServicesBinder=defaultServiceManager()->

e.java中有一行 publicclassTextServicesManagerServiceextendsITextServicesManager.Stub,所以我从 ITex

e.java中有一行 publicclassTextServicesManagerServiceextendsITextServicesManager.Stub,所以我从 ITex

e.java中有一行 publicclassTextServicesManagerServiceextendsITextServicesManager.Stub,所以我从 ITex

t;List>(){})cityIds.stream().map{cityId->valcityListenableFuture=asyncHttpClient.p

.javacaseTRANSACTION_isSpellCheckerEnabled:{data.enforceInterface(DESCRIPTOR);boolean_result=this.is

码:valcityIdsFlux:Flux=getCityIds()valcitiesFlux:Flux=cityIdsFlux.flatMap{thi

ence>(){})l}}复制代码在这里,我使用thenApply运算符将CompletableFuture转换为Comp

码很容易理解;但是,涉及八个阻塞调用:获取7个城市ID的列表,然后获取每个城市的详细信息获取7个城市的详细信息每一个调用都将在不同的线程上。3.非阻塞IO回调我将使用AsyncHttpClient库来

码很容易理解;但是,涉及八个阻塞调用:获取7个城市ID的列表,然后获取每个城市的详细信息获取7个城市的详细信息每一个调用都将在不同的线程上。3.非阻塞IO回调我将使用AsyncHttpClient库来

gt;#include#defineLOG_TAG"binderclient"usingnamespaceandroid;intmain(intargc,char**ar

gt;#include#defineLOG_TAG"binderclient"usingnamespaceandroid;intmain(intargc,char**ar

inder.FIRST_CALL_TRANSACTION*/1+7);spITextServicesBinder=defaultServiceManager()->

e.java中有一行 publicclassTextServicesManagerServiceextendsITextServicesManager.Stub,所以我从 ITex

e.java中有一行 publicclassTextServicesManagerServiceextendsITextServicesManager.Stub,所以我从 ITex

e.java中有一行 publicclassTextServicesManagerServiceextendsITextServicesManager.Stub,所以我从 ITex

t;List>(){})cityIds.stream().map{cityId->valcityListenableFuture=asyncHttpClient.p

.javacaseTRANSACTION_isSpellCheckerEnabled:{data.enforceInterface(DESCRIPTOR);boolean_result=this.is

码:valcityIdsFlux:Flux=getCityIds()valcitiesFlux:Flux=cityIdsFlux.flatMap{thi

ence>(){})l}}复制代码在这里,我使用thenApply运算符将CompletableFuture转换为Comp

码很容易理解;但是,涉及八个阻塞调用:获取7个城市ID的列表,然后获取每个城市的详细信息获取7个城市的详细信息每一个调用都将在不同的线程上。3.非阻塞IO回调我将使用AsyncHttpClient库来

码很容易理解;但是,涉及八个阻塞调用:获取7个城市ID的列表,然后获取每个城市的详细信息获取7个城市的详细信息每一个调用都将在不同的线程上。3.非阻塞IO回调我将使用AsyncHttpClient库来

gt;#include#defineLOG_TAG"binderclient"usingnamespaceandroid;intmain(intargc,char**ar

gt;#include#defineLOG_TAG"binderclient"usingnamespaceandroid;intmain(intargc,char**ar

这次在HAL层通过binder 访问 JAVA 层服务的简单例子就讲解到这里,希望大家看完以后能够触类旁通,在这个例子上面得到启发。

inder.FIRST_CALL_TRANSACTION*/1+7);spITextServicesBinder=defaultServiceManager()->

希望大家多多吐槽,大家一起共同进步!!

inder.FIRST_CALL_TRANSACTION*/1+7);spITextServicesBinder=defaultServiceManager()->

inder.FIRST_CALL_TRANSACTION*/1+7);spITextServicesBinder=defaultServiceManager()->

e.java中有一行 publicclassTextServicesManagerServiceextendsITextServicesManager.Stub,所以我从 ITex

e.java中有一行 publicclassTextServicesManagerServiceextendsITextServicesManager.Stub,所以我从 ITex

e.java中有一行 publicclassTextServicesManagerServiceextendsITextServicesManager.Stub,所以我从 ITex

t;List>(){})cityIds.stream().map{cityId->valcityListenableFuture=asyncHttpClient.p

.javacaseTRANSACTION_isSpellCheckerEnabled:{data.enforceInterface(DESCRIPTOR);boolean_result=this.is

码:valcityIdsFlux:Flux=getCityIds()valcitiesFlux:Flux=cityIdsFlux.flatMap{thi

ence>(){})l}}复制代码在这里,我使用thenApply运算符将CompletableFuture转换为Comp

码很容易理解;但是,涉及八个阻塞调用:获取7个城市ID的列表,然后获取每个城市的详细信息获取7个城市的详细信息每一个调用都将在不同的线程上。3.非阻塞IO回调我将使用AsyncHttpClient库来

码很容易理解;但是,涉及八个阻塞调用:获取7个城市ID的列表,然后获取每个城市的详细信息获取7个城市的详细信息每一个调用都将在不同的线程上。3.非阻塞IO回调我将使用AsyncHttpClient库来

gt;#include#defineLOG_TAG"binderclient"usingnamespaceandroid;intmain(intargc,char**ar

gt;#include#defineLOG_TAG"binderclient"usingnamespaceandroid;intmain(intargc,char**ar

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值