From 9a7a2fa90f17dea167d69a236d822751a7713bca Mon Sep 17 00:00:00 2001 From: HuangXW Date: Tue, 9 Aug 2022 16:57:15 +0800 Subject: [PATCH] =?UTF-8?q?Call=E8=B0=83=E7=94=A8=E5=BC=80=E5=8F=91?= =?UTF-8?q?=E6=96=87=E6=A1=A3=E6=95=B4=E6=94=B9=E4=BB=A5=E5=8F=8A=E6=96=B0?= =?UTF-8?q?=E5=A2=9ECall=E5=89=8D=E5=8F=B0=E7=9A=84=E8=AF=B4=E6=98=8E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: HuangXW --- .../ability/figures/stage-call.png | Bin 3003 -> 10066 bytes zh-cn/application-dev/ability/stage-call.md | 182 +++++++++++------- .../reference/apis/js-apis-ability-context.md | 52 +++-- .../apis/js-apis-service-extension-context.md | 42 +++- 4 files changed, 176 insertions(+), 100 deletions(-) diff --git a/zh-cn/application-dev/ability/figures/stage-call.png b/zh-cn/application-dev/ability/figures/stage-call.png index 28f2a0f7ea9d86fc81e0c1a37d556384b14a9bdd..511632f7b7ce2c4c4d6582792311184f46fbf703 100644 GIT binary patch literal 10066 zcmeHtc~nws+czpDmLgdv%MnwLm1U#zgxX+}R%TkJR@Skc6VV)yD9SnwSXSnM!)eeo zMJ*>3u}tw~IplzfNN9?Rf~kOjz`M2cob|2mdH?#JwZ669cb&Z!?tL%!ec#u8jlb)< z_MM|{`_)!xtpI^QY6o2R90!4vAi%Q(vK;u^%6V%K+!T<<_dA1%TXn{P0XWdVhhfe%%m;;AfwY^omZV2D7`RPGQ9`O^cqEI)BxM1V< zOh41^O4#>1@LhHBLzCnlKg7rTx3$xRHNwfyU|9x018}J#;7j*-Reiu#SFA zJo@ZL1&}zC5`I5hc~xmlqTpjaLiXVsqL*wYgYTIvqKB_vcMx>VA&{#3V-~(a&{|2< zU)SuP55;M^YxddwvMPSWls%c@sHgxs_+A|xqj!&>zv{|7I&`S6?+_GsBxSDydL8hR z&s)J4eSq4R-;_W2>>6h8-=mXQIam@dfPg=yAB2MtcVLj)78;P->s|jD{6Fx3%y%4& zN4RMry*-5SF?69Vt@-gClNNn-YgdO@)a90dHv==h=hvGDJ>HVF!ypcGX%c;cT!}iA zXP!-$7F3?oRsn-Hu2MWl`7F{J7Ux?@x;>5Oaj*syZy5Uq(p?By=ddIas zPPtp^v+EusZgZfIqLoW*&mz^py4TWD+Cu6m1&vjE;bT++0%8OMFxcot__BxnbCx;G9|N{mcE_yN}6GoFB0fWy`dCOc;ggTy|%?!@mz@nd2Q_d zq_$o!1AHC&Sc~4OZxoYFZ<1Qu_02b=iAh=zmSiQ5YSK5)(z$jS#Pzlmvob_JJ&PsTQs@3ExYFi@w3d-Z)#q3Xh8 zlxyC6o7bGe-cS~@kQ+@VPRu@+^l{OFo3Pt^bD_PP`Jg-F`X>m>ox7blbL#uh(wDQ_ zE<418Wb|^zh8NH$7y%5l>>7?lM@hPzqHYljF;Em*-9esT9_Y0%Q#~ap>UHxR_O36VUXJ;6*4`Tu5eY0Xi!Y> zWX{AK2%6-MYWN;bluYRj>uHDa!dIKs6|NnL`{p%u!yy|QT_aotJ=smI4)PxeU?6ck zA~C6RNmd3ho1L{4(UEFU+Ann^vR{U6U(ajFs$!G#!5ciY^CkkGbC#jiOWD7ZF9n~w?0>3DbS;(dyYr>mD1z|B0NJ(~HZz$S$QA5@?dQM<^&UiVQz$&*JpteWc*N}KemzljL`J#x!%sh#v4{`1$_`_L-$)GOC zQ`z;fy({Wr0i1cO2=ri z4%#-e4y*`z>}r5HU>$A$<~Z>t3)Q{e&&PxKzO?+n6G8~5Yl^`s--RL^MPWiHHm6cg zFp9;&dJGGGK=Mnlb0NtUm7Nd+`&jX#`^N4w`4jIa^g~`NM@*JZg;=_l(p0;Zn3%Rw zdIEp=1#x}6ekncEQ$ja`Ws0l3XszK6;Wff8uO;52^&oEKo>zW6hDDf93|W6?^De6v~M23vh@?{ zxb-OI-)+y%!FwE&+E|N3mDKH3^#HP3e(bCCbh$6{z+&)R0|V$2SO?I8Vx~If2Tl=h0Gz@=$rgaZ3Wy>W zi7M^$SAG#zNYtmddS$m^)EN5%=XZ1nCx|bP)4WRQ3v~KaA-6L&Prq|!zAgoEyHGh@ zFLMVU5v_dN_UH!*!_jH29u6QA6F*;D;JCf?oOi1vKl##cwxDNum@iAV%}5weu859P3#(LT@vScU z2-CUcQgipizS<(mYsos9+%0H63!u$Ye|6w|)1&2wa1?2Y>o0EXL;EVdI=9y@`XDVsy_DY zCf&#QPfESehZiJssPmE{-X=jQ$5aLU`G~Gt%=zCL%+w`yxw%ZShwhD=D*`Kyz9>X{ zN%yMeZChl6GyLp*RZ2?-O#|}muB=ifmiffzF6uZ0d(He91+iYz@d5~Z^`t_V@elRm z8{RiMhtTVuECve$Si85h7<>A&=0+9pN7W?{2?6f`qWC|9|Ck3z6`U^J|H+7U^oDfN z_op!)_3=*`0r~WUX(fVfOr&t+aAfi zr5}>iwPeFxMvJcy&HWc&S!pSSw8lVp1HMM z!4MW_3OJjyVC?n{x0vR)(UtW@Y7nq3pcjV#MDAT9t?&Z|fA7AhvNeK+spLj*@Vyp{ zgMV!dcCNgO(zOwKn_FB1pygzsM#IzxY>cpGYTpnpU=hVHZZLU^#_hH6oInlIii{UR zNh-MMSbCA6O`k>J&+Y8LH8=(5K{FjU23g?piu=yvmzOV_m#0V}e9@74;@vc=s<3mvD+%4JgKgBLDNjcYC8*=^wl*Y13mD=+m+@ zfJqs_Zk<&AO4EPQTi+ChqzJPOUqM+BlQB@hP(k}(kcMJEc8waCERb*%F}lfG5HTYu zdO|=5DI})V0D_h3LBzwh1lh9(&@&-NGhG@%*yLaTCjY#xAVqO1q|#xUrU3ph?Fu*Q z2WZ*GgMQuN!hn% zo^!1W(LQya^Q;}0s4pha?K!`DcZ612*~W zChWI4&3VrW*jT-obdEr}5IZZBMKmq9h|a*oAC~WNhR+>c^r$$*x*gJGiBCul`KL9j z&dy9D|m13Wl0y@_-Q_!+b%MDod?u%28nlty%DblUrlW1AZ;6HM6LP6 zl%Gy=-Ic<+?d#2|P+xLL)W#kKKw)b5&LLlhF+0lWp~yuOeut=!1Kc!dofG_QE})e= zUtIdj2Cm&a2sdg@{^R9O#Zg?l8Ji4u`5iFGB}MSg2k21UbQ-|Y|Klc;^}os=D?82~ zeHxDOIT?ac4jz*7C?@zRvCWJ~>y!$3>?uXYZ2L|i4nB#IqfL97LoswSrgTnPAE**^ zuoK0Q)o5vrZxr zJ6qYo=co^W%X;+q<;~^F*!BrDoq1aieu;PQK60cKFEjktOa?PS%l=lWUMsx}Q70$r zFaNihWm6eKy)}0SPj4x7JYyOhQ{-akHF@1} z()QrPCka9_C4tAj(A0El;n^|hnl+F&_7fL>1gir89^>kjIGq!+z|3fGrwK!n$F&2W z+P-j8G_YMjR0VK+I|8)h3vE-+)UZgSY#gE)=d6S+Pa-!G?IF06QUjDf|E{i8FW`M| z0kL8p8^Nxqc}}$u^!x@7F@lx-(GK8u(Q+%wiAay03{g3 z+`YHn`DsAZRB)4U*n|l-*#NAlbpQ^7Y~A^S{|Ir(6@CFI);Ox*Q~|u`s)$8gdT3CT z3U+n@D1_j|2jCX~q`6N60(QQudYNnl)6#(SIl;T!6%AY<;N6c9fTS+Ca*VO<$%tmC zVs4@aWW6&y=OI`T+rGi&^tPXL!yx<=L^DiL;l2?Jf?K=(D_|MB0rGDk^0UFtw_uP< zM*rWB@J=|BmU40K%JY#v^(^fuNlT6Y!#iGnaE?Whev~8v;LG0!H&%UJ1Ib3QPDM`Z zL-nEz{36<%fil^NSuafdp`Rz5bAjLMI?vdPy{n|D!a~P|MUt3FLLLy2|2~~7!1Ow> z^ZMH94=W>oG-|eZxZ4{u6D3piMT}jU*l)jeeF>_{>507`%k&Vc^;?{1Q(z4*^wDnC zQoLi@v>jd%N+Ip+{C;XKmv<6ie~=c$)KBW&lxgEvENKaf9h)L9XV8kk&VZBvCIhm6 zpNiP1qzNJA+fUakT^#y&XQtT@-)zZD*j2JO&|CTXt_rId5x$D_h?f|ygGl5 z#mQnaDra7LeqlrXF&k4IYTu1mdjR_Mq6wQr9ad1*f$zVsYvPf*CAB+4sM=q=S_KD4 z6VN9>N3L(f9$lUYpO=Ygl&8oxdoR7XF$0m9LsYKNOZQvuJpUwGx+39fHsxwe)93(s z-z4e-@}`HTSWAKA=y~p27w@2VW&i}I`X?ObjJFe9s1E92ltnh=-O$_h`2RZBjRM59 zw40b{9GDgR$__Z+%t)#~)Nbd4i*PG*jRoq9E#Cr2d!@a*sGq(j@pPi-V#^-OY=1|G zQc9H0guq~}HW|>^WL2g2!jk6?QvaL{OC2FjYR%0*``1PsyBFeaOF4Lr*(hoU3#j`* zAh;+M+)h^&T)T&x^l?xBj=gkDhr zp;VX-ICz6J+bjiqgQFt7i z7vf*uw|Ctw(pRxo{_x_|-S1_6mCYl_u#^_|;IAoc+1^*5YkXgQrnnS)m%L*UB1b;d zq%()e6Sv~O2eF6ZN7A)&>CfP$28YKYUfG8GZrT;*V@#8dydU+q z$%vI`rJ<;&)5_-z(jr? z%L<(zP5k)!)c1CkP^-z%3P*>0lg2K9@yV&5Z<;xR+f{4jnb#ogf{qb8;$FFSEF zM#}LYdE4fY(&i|yeeE;A?R%SdmGsD@YP!>wj# z{RSG0VWP`I`gWeGOQ?S1UFyuG$Yrlgy^0@u7M?WsCC8yWVswgpYbr#BmpMH}DSQsC zr9s_sU_r74?;y^%6Z8hm0MxgvcDFNdcMx6Z1jr|i?`pF%Y;%yju@ep;XBKALET8im zHT@r_`o$gaOB7v<9eLvQz1z$G3C%D5h#y9Z>MJ>SBV?fJm_=xRSJdq2mm`%SeH+5- zM6YW3Jw7u6dU%U1uhx)PCn>HK4#pqh4|H%Bj-j{_g1LboGm3q0hcMEiPOs)HOYT&f z&`xyyp0D6a=Qy7C)KlA$&e_VboFquY?7p`fUi^Ab`+ITVV4<|%@EyaZVVr25X(OaD zqtUZ<5faiqAaKCnc~cGe$~$Z8nY9y7$(lYu=`c`5%9^7L<*ig9Uro}S&{1@9-+UW| z`uuFi&iEf8Y41kAj$R2~1z~Nep`HxY?sQ~Z@yh`aj2^fXcrVnNH+RqxHitGi9S`{3 zCo7B7OprbHM{COW=TovEF7=Lq^T7~%O=~G~PqzT|a4{6U34mAS_GcS>Rp_R!hTJyH zL&3+UWC6Nd9tNb%*5qzDrh;AKg`KP|f!Cz>WnZ|6l zv`uWcI=9y9gj@G038Z_J5K<<3e7Cja(dEdVMh|U2!$3FE=_a?T<4}jtgPk3LhaZ`m zS?zsw*zVM??pCkIN7(o$Ev?$7saY|9oQdS#iTq)0(){8FwPml`Ham$`_4J$J@7H(X zpWF%5FVr_3cZ-TiCY-8|snv-YxDq*8O103; zqv{|JcRt5EoPJ<4u~9UeE#LBdKmMs9-tPDVt09Q>!gRxkJ4Wo$*#NaY47HzYAF`kS zHn%tEGgBt0EW7&Se2V^#g0KFEYpAy>UwZ!nk=2cfUQAdBcm?i)PuD1k3QO&jeeq z(a&jyZv)$&a)=ba-@c?9?+R=Uu?c8WO>;oUbzbg#Wlpd`6`VnSF^}YTd$o9a`5Jrq z#lAdqrSX@Y7eB2@vx_Y|lPDUA?7Nt1PX7MrP&!GD5BU1xKxD^W%|CBy`fb!a6X7(Q z%^++)cRdp$6GaZjvd!fex3cGd3}QO zyF4;5{-fVh+`|gk52D%l0%Q_KHuh)ruu$#-wI8F%hj_9BP-%mc{cH|X>X(RYr|gza z@njq23C#|2_WPuFpM6YZVoT*uf3p2D8TfT-D7}u^8x+6GmBsBj(`~wc*#$khX?gLd z+&Zm1rF0~GjpYkB*`t};DYO2^q4x=BC zJ2`mB6FxQ|Vdq4%vkH(tx=Zi^=&&)&qJO9tzXB}Oe@Q^LTAz~czq~^_>uRDo421q{m+bg_p!$y8-eql)aK;jVosZ7J zbvmf>W9b<#LOn)E&3gB03WM|qgVcC>5!RMIa4B%n)ZQuex);^{;cmWm?R06}4`^km zW%J1;e7uUPj#E;%D-rEtaWT6Wzdn`-}SCc2w^OKt;JeD=r*t`kwO z5ZTpx7#rjKF@AMUMR+XwZX-h!AW3*es=u?*@7cb}Uij0XSlRmlX^EdvzlD zsNI~v>jsz8qoerVy35)qb0nIx0&ONwIIg*f_#181FNbWG=B_k+?|YT8%u45|qJb}v zwB#0Jb0z{@r0khClQ^><+0TJe@YwD2yE~MWvgE<(9*x*->fAIgw^+whjD znK`NJD)Z5Ep)57WVl!RnLcqrvzAMTMotL{1XW{D1)k`OO1$Q{`jIs-?8z-jZE$_a0OM zMYYGb&%sLs^`uK>f@T9)rfmgfbBneUxtw+mC)p7bL7 zNT4P3$5Myyo{~bT_kY|V`i~c=S%Fha*%Q5W|3|;-k$&{-exPl;X&zf5N}m_4T9w3% z8J)}^e@7tp*e>#DnIjC=(Nuw*ZhZSg+2DLQqx}5OueR`B)V3S9du=NjcH5IF+pS>V z10NPy{$6VZT~(A2SlogzqvrMkZU9J^oteJ6%L1Er0M1{OU#${(swq2J@ql?>6 zmgJf!$(U#}n@fmX!cZ=g40>ILG3b4U&+fasf4%R2?;p?kJ?HtIbAIQX-#O>`UM1k{ zWo5pW0RTW2<8aIc03<=^-DA5nL{p=C-JwMy+{NA&D1W6i1u;?qHcmDG@E{GoMuI^+ z80z2|4gfo!iysM2$i34504HFM*|z8463WRT@ABL*Q=<8|V7+;pJb7yt4Eh!P~ z`!To?vxtw;qoj)^xHqz~J9)7o!>@+=AtwM60s^AXXml~7!;pe#Xg(6632>AIw4Brs zM>VQXMBwoFFqkC3ZyGeNv`WfDmYxI>PDP2N1-#uPOw`7j>7~GGJt$1i&d1L31cZCg z|0kzaha75%jR_xXPSLcataK_rZM9F^f4<_)I=`P4vn*&BK_tsd0||i^@YK}Q^3w^F z`SGjfmu_-%*#R@2gGb!!vt|8*vx__;l6~&OiE(x{xf9lsT#~ zAPm(gL;beLoSi1lDO3L8Ga0Jj!rYpr3xXo=fiNItn#>I~xIoFLc(qCnRs_cp7z`=q z@eHY~U(qwp*Gqz37G4tT&nhsYK>%V&`5{XyDxw}?fhs|MU13ei-b)p3jNC#!eL zy0E<4)Z2mkkKpz|l64zr_A|Km03Yw@Nw|ybk7JGme24jMd9}xYd8H+>db#V?+K`f+ zXXkpK?4^{V6h&7Ae@O=oPB+27Ip^BX?5(nnDG@}>4PBeE%*o_(1|KibD>d;28B)W~ z&6!wCt#sLol=XLSql#gE9K&=o|B50;;-NVw3~`$jL8NCtQGEj@+)zF{*1bNM>%jL$ z@Yk-nBfMS#hg+yn`gPkPO{;GS(4f(j*#+{I0%YkIlJ{b7-M#45N=1uGJfyFrrlCQy z)jeGM{jE&fq~;)t^;Nsck4y@b_qiepe0a+Xf6{BC=I=^)@@RxdDr0$aif$yL-&qOf zOrS2&Dn~kGnS|UiIArwFC%^Klqk70WOeI+;`dIU7VoU>!Jqpz93U|Ymc;;F34hEDd z5G#44oH#?`uE35_$4X+CCD0(AaKPVO| zV4KWT6W%779xR&Bs#L|j*~m?6}PF|=wGd;dIbnlnY^b| zl^1eX3+nWqKvF4<*|7Auoo%`DY5tAD_B;V8RY${ z5NwmhYp>Y2INjs4NRap^g;H;7YWjpyGjJqEz;B7n_BZ?1{`>6IHx?YakGjf{sL*JC zB}SqU{Wlk;CQT#u*m_eb0=?`~G2tmG^voDX!Ty zrD}97hZ3Z{18Zv$d{Zjqhd`(E7kowBx$<^=?1IOvX!f;HR~lQu@yAk?ABG8CY3L6P zb(ehkmo*i`A^Dx&4<{lvCb~o1UP=lNj9OAu91DocV&wLVSR zBppyDP9!2AZdCLN1AK*zlbS^pwW8nL&|n6n5->xr3?{X;kBo>qCWo!q@iTFg-s~`A zj#|yxI39m$vf^`8gKVCAE^<6s@$j(?q~BhFW#LcOaTdPDJ02!R_-MkBsC+s@YVo8i z#zc8fBB8owPt)jH@$h(mWu@_yU!$jO~ps)4Ik;#JV6p-j_u$ z&8|P4tyM#V>-yEvvu_PjdL5~i_@!u7&Dt688R2$kv~pj++;A&*uqE*;$)_HdlYhVd zEhi$XLp|;laZVr#GV$BN71+e1KG{V0^f2{J0o%1GMhEbab;S>_9+i$GZHTvz9Tc`i664; zIrbi}ToJ1i3l*%x(cS;)znUuRM=preG|Rf-=iTJA5ehkm|7tHgbRz1y3!;`1T`_9me0F^1l<^ zZ!|Yn46>nW=IMZ|W@-l|4t}Yw8$16ZcwY!!Wt@-SrvaY1!AQ)~9i}|k z%~wE49NC-?EyWqIi?j5+%04b@I&#;!WL7Wpmt6f15qmZ@aKc}X!&usq#eGLG35RxD z&pcPkaMgs551|_4JiE*Tyuiu>`Bpsq&cy;!ZxP5y)Yo45YLY8-Tc_X2-Cw}b0QID| zCUel4?@tC{IwPi_L1$Vc->ihPdD|z=ed3nl3_7Gu^tt>k2B8O-%k7i(!8pW+yc>lo z<6e=J&n?Zx8K(VP1@i#k6Jq0|He0h7DxdJ1iLvov>GV+oRP&yQ(_gRpZx|lCjH9XQ z!WdGYDuE^eZG9_P)f1A1YkM46g-DYgF9k?3w*Xm9+iTZfSZO7`D*|Gi@%c6aMN063 z|3D|;v66sNCX`ukH0aV;A$jfNdbb0%38;~mM&;*1$ic)wtmTG~*G5TLpg|xs5DK;c z=|-m~{ITtVIEcYm|6yvYL)9Vlw$thN+V8v$;k%?lcX@Fc$7q2>{2cGdn?Mo({0JSs zsWGaG{`7pfxufs@Z$GHx%q3wVA zS^V$Zc1KBpHtL|Jr41U-+72A2B?0+{~b=Xg`gM!?1j<_LECdi ZpSStGYr~$&^v@7~#vI2TE4THd{u?zmTL=IE diff --git a/zh-cn/application-dev/ability/stage-call.md b/zh-cn/application-dev/ability/stage-call.md index e8126fa0d7..65f12149bf 100644 --- a/zh-cn/application-dev/ability/stage-call.md +++ b/zh-cn/application-dev/ability/stage-call.md @@ -1,39 +1,58 @@ # Call调用开发指导 ## 场景介绍 -Ability Call调用是Ability能力的扩展,它为Ability提供一种能够被外部调用的能力,使Ability既能被拉起到前台展示UI,也支持Ability在后台被创建并运行。应用开发者可通过Call调用,使用IPC通信实现不同Ability之间的数据共享。Call调用的场景主要包括: -- 创建Callee被调用端。 -- 访问Callee被调用端。 +Call调用是Ability能力的扩展,它为Ability提供一种能够被外部调用并与外部进行通信的能力。Call调用支持前台与后台两种启动方式,使Ability既能被拉起到前台展示UI,也可以在后台被创建并运行。Call调用在调用方与被调用方间建立了IPC通信,因此应用开发者可通过Call调用实现不同Ability之间的数据共享。 + +Call调用的核心接口是startAbilityByCall方法,与startAbility接口的不同之处在于: + - startAbilityByCall支持前台与后台两种启动方式,而startAbility仅支持前台启动。 + - 调用方可使用startAbilityByCall所返回的Caller对象与被调用方进行通信,而startAbilty不具备通信能力。 + +Call调用的使用场景主要包括: +- 需要与被启动的Ability进行通信 +- 希望被启动的Ability在后台运行 -本文中的Caller和Callee分别表示调用者和被调用者,IPC表示进程间通信,Call调用流程示意图如下。 +**表1** Call调用相关名词解释 +|名词|描述| +|:------|:------| +|CallerAbility|指代进行Call调用的Ability(调用方)| +|CalleeAbility|指代被Call调用的Ability(被调用方)| +|Caller |实际对象,由startAbilityByCall接口所返回,CallerAbility可使用Caller与CalleeAbility进行通信,具体接口见表2| +|Callee |实际对象,被Ability对象所持有,可与Caller进行通信| +|IPC |指代进程间通信| +Call调用流程示意图如下: + - CallerAbility调用startAbilityByCall接口获取Caller,并使用Caller对象的call方法向CalleeAbility发送数据 + - CalleeAbility持有一个Callee对象,通过Callee的on方法注册回调函数,当接收到Caller发送的数据时将会调用对应的回调函数 ![stage-call](figures/stage-call.png) > ![icon-note.gif](public_sys-resources/icon-note.gif) **说明:** -> Callee被调用端所在的Ability,启动模式需要为单实例。 -> 当前仅支持系统应用及ServiceExtensionAbility使用Call访问Callee。 +> CalleeAbility的启动模式需要为单实例。 +> 当前仅支持系统应用使用Call调用。 ## 接口说明 Caller及Callee功能如下:具体的API详见[接口文档](../reference/apis/js-apis-application-ability.md#caller)。 -**表1** Call API接口功能介绍 +**表2** Call API接口功能介绍 |接口名|描述| |:------|:------| -|startAbilityByCall(want: Want): Promise\|获取指定通用组件的Caller通信接口,拉起指定通用组件并将其切换到后台。| +|startAbilityByCall(want: Want): Promise\|启动指定Ability并获取其Caller通信接口,默认为后台启动,通过配置want可实现前台启动,详见[接口文档](../reference/apis/js-apis-ability-context.md#abilitycontextstartabilitybycall)。AbilityContext与ServiceExtensionContext均支持该接口。| |on(method: string, callback: CalleeCallBack): void|通用组件Callee注册method对应的callback方法。| -|off(method: string): void|通用组件Callee去注册method的callback方法。| +|off(method: string): void|通用组件Callee解注册method的callback方法。| |call(method: string, data: rpc.Sequenceable): Promise\|向通用组件Callee发送约定序列化数据。| -|callWithResult(method: string, data: rpc.Sequenceable): Promise\|向通用组件Callee发送约定序列化数据, 并将返回的约定序列化数据带回。| +|callWithResult(method: string, data: rpc.Sequenceable): Promise\|向通用组件Callee发送约定序列化数据, 并将Callee返回的约定序列化数据带回。| |release(): void|释放通用组件的Caller通信接口。| |onRelease(callback: OnReleaseCallBack): void|注册通用组件通信断开监听通知。| ## 开发步骤 +Call调用的开发步骤: +- 创建Callee被调用端。 +- 访问Callee被调用端。 > ![icon-note.gif](public_sys-resources/icon-note.gif) **说明:** > 开发步骤章节中的示例代码片段是开发过程的步骤化展示,部分代码可能无法单独运行,完整工程代码请参考[相关实例](#相关实例)。 ### 创建Callee被调用端 Callee被调用端,需要实现指定方法的数据接收回调函数、数据的序列化及反序列化方法。在需要接收数据期间,通过on接口注册监听,无需接收数据时通过off接口解除监听。 -1. 配置Ability的启动模式 +**1. 配置Ability的启动模式** - 配置module.json5,将Callee被调用端所在的Ability配置为单实例"singleton"。 + 配置module.json5,将CalleeAbility配置为单实例"singleton"。 |Json字段|字段说明| |:------|:------| @@ -51,11 +70,11 @@ Ability配置标签示例如下: "visible": true }] ``` -2. 导入Ability模块。 -``` +**2. 导入Ability模块** +```ts import Ability from '@ohos.application.Ability' ``` -3. 定义约定的序列化数据。 +**3. 定义约定的序列化数据** 调用端及被调用端发送接收的数据格式需协商一致,如下示例约定数据由number和string组成。具体示例代码如下: ```ts @@ -81,7 +100,7 @@ export default class MySequenceable { } } ``` -4. 实现Callee.on监听及Callee.off解除监听。 +**4. 实现Callee.on监听及Callee.off解除监听** 被调用端Callee的监听函数注册时机, 取决于应用开发者。注册监听之前的数据不会被处理,取消监听之后的数据不会被处理。如下示例在Ability的onCreate注册'MSG_SEND_METHOD'监听,在onDestroy取消监听,收到序列化数据后作相应处理并返回,应用开发者根据实际需要做相应处理。具体示例代码如下: ```ts @@ -89,12 +108,12 @@ const TAG: string = '[CalleeAbility]' const MSG_SEND_METHOD: string = 'CallSendMsg' function sendMsgCallback(data) { - Logger.log(TAG, 'CalleeSortFunc called') + console.log('CalleeSortFunc called') // 获取Caller发送的序列化数据 let receivedData = new MySequenceable(0, '') data.readSequenceable(receivedData) - Logger.log(TAG, `receiveData[${receivedData.num}, ${receivedData.str}]`) + console.log(`receiveData[${receivedData.num}, ${receivedData.str}]`) // 作相应处理 // 返回序列化数据result给Caller @@ -106,7 +125,7 @@ export default class CalleeAbility extends Ability { try { this.callee.on(MSG_SEND_METHOD, sendMsgCallback) } catch (error) { - Logger.error(TAG, `${MSG_SEND_METHOD} register failed with error ${JSON.stringify(error)}`) + console.log(`${MSG_SEND_METHOD} register failed with error ${JSON.stringify(error)}`) } } @@ -121,14 +140,26 @@ export default class CalleeAbility extends Ability { ``` ### 访问Callee被调用端 -1. 导入Ability模块。 -``` +**1. 导入Ability模块** +```ts import Ability from '@ohos.application.Ability' ``` -2. 获取Caller通信接口。 +**2. 获取Caller通信接口** Ability的context属性实现了startAbilityByCall方法,用于获取指定通用组件的Caller通信接口。如下示例通过`this.context`获取Ability实例的context属性,使用startAbilityByCall拉起Callee被调用端并获取Caller通信接口,注册Caller的onRelease监听。应用开发者根据实际需要做相应处理。具体示例代码如下: ```ts +// 注册caller的release监听 +private regOnRelease(caller) { + try { + caller.onRelease((msg) => { + console.log(`caller onRelease is called ${msg}`) + }) + console.log('caller register OnRelease succeed') + } catch (error) { + console.log(`caller register OnRelease failed with ${error}`) + } +} + async onButtonGetCaller() { try { this.caller = await context.startAbilityByCall({ @@ -136,41 +167,40 @@ async onButtonGetCaller() { abilityName: 'CalleeAbility' }) if (this.caller === undefined) { - Logger.error(TAG, 'get caller failed') + console.log('get caller failed') return } - Logger.log(TAG, 'get caller success') + console.log('get caller success') this.regOnRelease(this.caller) } catch (error) { - Logger.error(TAG, `get caller failed with ${error}`) + console.log(`get caller failed with ${error}`) } -}.catch((error) => { - console.error(TAG + 'get caller failed with ' + error) -}) +} ``` 在跨设备场景下,需指定对端设备deviceId。具体示例代码如下: ```ts -let TAG = '[MainAbility] ' -var caller = undefined -let context = this.context - -context.startAbilityByCall({ - deviceId: getRemoteDeviceId(), - bundleName: 'com.samples.CallApplication', - abilityName: 'CalleeAbility' -}).then((data) => { - if (data != null) { - caller = data - console.log(TAG + 'get remote caller success') - // 注册caller的release监听 - caller.onRelease((msg) => { - console.log(TAG + 'remote caller onRelease is called ' + msg) - }) - console.log(TAG + 'remote caller register OnRelease succeed') - } -}).catch((error) => { - console.error(TAG + 'get remote caller failed with ' + error) -}) +async onButtonGetRemoteCaller() { + var caller = undefined + var context = this.context + + context.startAbilityByCall({ + deviceId: getRemoteDeviceId(), + bundleName: 'com.samples.CallApplication', + abilityName: 'CalleeAbility' + }).then((data) => { + if (data != null) { + caller = data + console.log('get remote caller success') + // 注册caller的release监听 + caller.onRelease((msg) => { + console.log(`remote caller onRelease is called ${msg}`) + }) + console.log('remote caller register OnRelease succeed') + } + }).catch((error) => { + console.error(`get remote caller failed with ${error}`) + }) +} ``` 从DeviceManager获取指定设备的deviceId,getTrustedDeviceListSync接口仅对系统应用开放。具体示例代码如下: ```ts @@ -178,29 +208,31 @@ import deviceManager from '@ohos.distributedHardware.deviceManager'; var dmClass; function getRemoteDeviceId() { if (typeof dmClass === 'object' && dmClass != null) { - var list = dmClass.getTrustedDeviceListSync(); + var list = dmClass.getTrustedDeviceListSync() if (typeof (list) == 'undefined' || typeof (list.length) == 'undefined') { - console.log("MainAbility onButtonClick getRemoteDeviceId err: list is null"); - return; + console.log("MainAbility onButtonClick getRemoteDeviceId err: list is null") + return } - console.log("MainAbility onButtonClick getRemoteDeviceId success:" + list[0].deviceId); - return list[0].deviceId; + console.log("MainAbility onButtonClick getRemoteDeviceId success:" + list[0].deviceId) + return list[0].deviceId } else { - console.log("MainAbility onButtonClick getRemoteDeviceId err: dmClass is null"); + console.log("MainAbility onButtonClick getRemoteDeviceId err: dmClass is null") } } ``` 在跨设备场景下,需要向用户申请数据同步的权限。具体示例代码如下: ```ts -let context = this.context -let permissions: Array = ['ohos.permission.DISTRIBUTED_DATASYNC'] -context.requestPermissionsFromUser(permissions).then((data) => { - console.log("Succeed to request permission from user with data: "+ JSON.stringify(data)) -}).catch((error) => { - console.log("Failed to request permission from user with error: "+ JSON.stringify(error)) -}) +requestPermission() { + let context = this.context + let permissions: Array = ['ohos.permission.DISTRIBUTED_DATASYNC'] + context.requestPermissionsFromUser(permissions).then((data) => { + console.log("Succeed to request permission from user with data: "+ JSON.stringify(data)) + }).catch((error) => { + console.log("Failed to request permission from user with error: "+ JSON.stringify(error)) + }) +} ``` -3. 发送约定序列化数据 +**3. 发送约定序列化数据** 向被调用端发送Sequenceable数据有两种方式,一种是不带返回值,一种是获取被调用端返回的数据,method以及序列化数据需要与被调用端协商一致。如下示例调用Call接口,向Callee被调用端发送数据。具体示例代码如下: ```ts @@ -210,7 +242,7 @@ async onButtonCall() { let msg = new MySequenceable(1, 'origin_Msg') await this.caller.call(MSG_SEND_METHOD, msg) } catch (error) { - Logger.error(TAG, `caller call failed with ${error}`) + console.log(`caller call failed with ${error}`) } } ``` @@ -224,27 +256,29 @@ async onButtonCallWithResult(originMsg, backMsg) { try { let msg = new MySequenceable(1, originMsg) const data = await this.caller.callWithResult(MSG_SEND_METHOD, msg) - Logger.log(TAG, 'caller callWithResult succeed') + console.log('caller callWithResult succeed') let result = new MySequenceable(0, '') data.readSequenceable(result) backMsg(result.str) - Logger.log(TAG, `caller result is [${result.num}, ${result.str}]`) + console.log(`caller result is [${result.num}, ${result.str}]`) } catch (error) { - Logger.error(TAG, `caller callWithResult failed with ${error}`) + console.log(`caller callWithResult failed with ${error}`) } } ``` -4. 释放Caller通信接口 +**4. 释放Caller通信接口** Caller不再使用后,应用开发者可以通过release接口释放Caller。具体示例代码如下: ```ts -try { - this.caller.release() - this.caller = undefined - Logger.log(TAG, 'caller release succeed') -} catch (error) { - Logger.error(TAG, `caller release failed with ${error}`) +releaseCall() { + try { + this.caller.release() + this.caller = undefined + console.log('caller release succeed') + } catch (error) { + console.log(`caller release failed with ${error}`) + } } ``` diff --git a/zh-cn/application-dev/reference/apis/js-apis-ability-context.md b/zh-cn/application-dev/reference/apis/js-apis-ability-context.md index db88c9d306..a86889bb16 100644 --- a/zh-cn/application-dev/reference/apis/js-apis-ability-context.md +++ b/zh-cn/application-dev/reference/apis/js-apis-ability-context.md @@ -876,7 +876,7 @@ disconnectAbility(connection: number, callback:AsyncCallback\): void; startAbilityByCall(want: Want): Promise<Caller>; -获取指定通用组件服务端的caller通信接口, 并且将指定通用组件服务端拉起并切换到后台。 +启动指定Ability至前台或后台,同时获取其Caller通信接口,调用方可使用Caller与被启动的Ability进行通信。 **系统能力**:SystemCapability.Ability.AbilityRuntime.Core @@ -884,7 +884,7 @@ startAbilityByCall(want: Want): Promise<Caller>; | 参数名 | 类型 | 必填 | 说明 | | -------- | -------- | -------- | -------- | -| want | [Want](js-apis-application-Want.md) | 是 | 传入需要启动的ability的信息,包含ability名称、包名、设备ID,设备ID缺省或为空表示启动本地ability。 | +| want | [Want](js-apis-application-Want.md) | 是 | 传入需要启动的Ability的信息,包含abilityName、moduleName、bundleName、deviceId(可选)、parameters(可选),其中deviceId缺省或为空表示启动本地Ability,parameters缺省或为空表示后台启动Ability。 | **返回值:** @@ -895,22 +895,40 @@ startAbilityByCall(want: Want): Promise<Caller>; **示例:** ```js - import Ability from '@ohos.application.Ability'; - var caller; - export default class MainAbility extends Ability { - onWindowStageCreate(windowStage) { - this.context.startAbilityByCall({ - bundleName: "com.example.myservice", - abilityName: "MainAbility", - deviceId: "" - }).then((obj) => { - caller = obj; - console.log('Caller GetCaller Get ' + caller); - }).catch((e) => { - console.log('Caller GetCaller error ' + e); - }); + let caller = undefined; + + // 后台启动Ability,不配置parameters + var wantBackground = { + bundleName: "com.example.myservice", + moduleName: "entry", + abilityName: "MainAbility", + deviceId: "" + }; + this.context.startAbilityByCall(wantBackground) + .then((obj) => { + caller = obj; + console.log('GetCaller success'); + }).catch((error) => { + console.log(`GetCaller failed with ${error}`); + }); + + // 前台启动Ability,将parameters中的"ohos.aafwk.param.callAbilityToForeground"配置为true + var wantForeground = { + bundleName: "com.example.myservice", + moduleName: "entry", + abilityName: "MainAbility", + deviceId: "", + parameters: { + "ohos.aafwk.param.callAbilityToForeground": true } - } + }; + this.context.startAbilityByCall(wantForeground) + .then((obj) => { + caller = obj; + console.log('GetCaller success'); + }).catch((error) => { + console.log(`GetCaller failed with ${error}`); + }); ``` ## AbilityContext.startAbilityWithAccount diff --git a/zh-cn/application-dev/reference/apis/js-apis-service-extension-context.md b/zh-cn/application-dev/reference/apis/js-apis-service-extension-context.md index b142b15571..e63f93a387 100644 --- a/zh-cn/application-dev/reference/apis/js-apis-service-extension-context.md +++ b/zh-cn/application-dev/reference/apis/js-apis-service-extension-context.md @@ -694,15 +694,17 @@ disconnectAbility(connection: number): Promise<void>; startAbilityByCall(want: Want): Promise<Caller>; -将指定Ability拉起到后台并获取其Caller通信接口,拉起方可使用Caller与被拉起的Ability进行通信。 +启动指定Ability至前台或后台,同时获取其Caller通信接口,调用方可使用Caller与被启动的Ability进行通信。 **系统能力**:SystemCapability.Ability.AbilityRuntime.Core +**系统API**:此接口为系统接口,三方应用不支持调用。 + **参数:** | 参数名 | 类型 | 必填 | 说明 | | -------- | -------- | -------- | -------- | -| want | [Want](js-apis-application-Want.md) | 是 | 传入需要启动的ability的信息,包含ability名称、模块名、包名、设备ID,设备ID缺省或为空表示启动本地ability。 | +| want | [Want](js-apis-application-Want.md) | 是 | 传入需要启动的Ability的信息,包含abilityName、moduleName、bundleName、deviceId(可选)、parameters(可选),其中deviceId缺省或为空表示启动本地Ability,parameters缺省或为空表示后台启动Ability。 | **返回值:** @@ -714,16 +716,38 @@ startAbilityByCall(want: Want): Promise<Caller>; ```js let caller = undefined; - this.context.startAbilityByCall({ + + // 后台启动Ability,不配置parameters + var wantBackground = { bundleName: "com.example.myservice", moduleName: "entry", abilityName: "MainAbility", deviceId: "" - }).then((obj) => { - caller = obj; - console.log('Caller GetCaller Get ' + caller); - }).catch((e) => { - console.log('Caller GetCaller error ' + e); - }); + }; + this.context.startAbilityByCall(wantBackground) + .then((obj) => { + caller = obj; + console.log('GetCaller Success'); + }).catch((error) => { + console.log(`GetCaller failed with ${error}`); + }); + + // 前台启动Ability,将parameters中的"ohos.aafwk.param.callAbilityToForeground"配置为true + var wantForeground = { + bundleName: "com.example.myservice", + moduleName: "entry", + abilityName: "MainAbility", + deviceId: "", + parameters: { + "ohos.aafwk.param.callAbilityToForeground": true + } + }; + this.context.startAbilityByCall(wantForeground) + .then((obj) => { + caller = obj; + console.log('GetCaller success'); + }).catch((error) => { + console.log(`GetCaller failed with ${error}`); + }); ``` \ No newline at end of file -- GitLab