当前位置:网站首页>Service ability of Hongmeng harmonyos learning notes to realize cross end communication

Service ability of Hongmeng harmonyos learning notes to realize cross end communication

2022-07-06 13:28:00 Intoxication, thousand layer dream

One 、 Basic concepts

be based on Service Template Ability( hereinafter referred to as “Service”) Mainly used for background running tasks ( Such as performing music playback 、 File download, etc ), But it doesn't provide a user interface .Service It can be used by other applications or Ability start-up , Even if users switch to other applications ,Service Will continue to run in the background .

Service It's a single instance . On a device , same Service There will only be one instance . If more than one Ability Share this example , Only when and Service All of the binding Ability When they all quit ,Service To quit . because Service Is executed in the main thread , therefore , If in Service The operation time inside is too long , The developer must be in Service Create a new thread to handle , Prevent the main thread from blocking , The application is not responding . For more information, please refer to Official documents

Two 、 Use

1. establish Service

newly build ServiceAbility Inherit Ability

public class ServiceAbility extends Ability {
    
    private static final HiLogLabel LABEL_LOG = new HiLogLabel(3, 0xD001100, "Demo");

    @Override
    public void onStart(Intent intent) {
    
        HiLog.info(LABEL_LOG, "ServiceAbility::onStart");
        super.onStart(intent);
    }

    @Override
    public void onBackground() {
    
        super.onBackground();
        HiLog.info(LABEL_LOG, "ServiceAbility::onBackground");
    }

    @Override
    public void onStop() {
    
        super.onStop();
        HiLog.info(LABEL_LOG, "ServiceAbility::onStop");
    }

    @Override
    public void onCommand(Intent intent, boolean restart, int startId) {
    
    }

    @Override
    public IRemoteObject onConnect(Intent intent) {
    
        HiLog.info(LABEL_LOG,"ServiceAbility::onConnect");
        return new GameRemoteObject("GameRemoteObject").asObject();
    }

    @Override
    public void onDisconnect(Intent intent) {
    
    }


    /** *  Used to accept cross end information  * */
    private static class GameRemoteObject extends RemoteObject implements IRemoteBroker{
    

        public GameRemoteObject(String descriptor) {
    
            super(descriptor);
        }

        @Override
        public IRemoteObject asObject() {
    
            return this;
        }

        public boolean onRemoteRequest(int code, MessageParcel data, MessageParcel reply, MessageOption option){
    
            // Accept cross end information 
            String message =data.readString();

            // adopt  ConnectionHelper  Call back the message to  PageAbility
            ConnectionHelper.getInstance().sendMessage(message);

            // Send back the result to the message sender 
            reply.writeInt(Constants.ERR_OK);
            return true;
        }
    }

}

At the same time config.json Registration is required in the file
 Insert picture description here

2. establish ConnectionHelper

public class ConnectionHelper {
    

    /** *  Private constructor , Avoid extra instantiation of singletons  */
    private ConnectionHelper(){
    }


    /** *  Static inner class , Hold only  ConnectionHelper  example  */
    private static class ConnectionHelperHolder{
    
        private static final ConnectionHelper INSTANCE =new ConnectionHelper();
    }


    ![/** *  Provide external methods for obtaining instances  *](https://img-blog.csdnimg.cn/c13fc3bfef3c4c1ba23a60ed3308f532.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA6YaJ5oSP5Li25Y2D5bGC5qKm,size_20,color_FFFFFF,t_70,g_se,x_16) * @return ConnectionHelper  example  */
    public static ConnectionHelper getInstance(){
    
        return ConnectionHelperHolder.INSTANCE;
    }

    /** *  Communication callback  */
    private IConnectionCallback mConnectionCallback;

    /** *  Set communication callback  * * @param connectionCallback  Communication callback  */
    public void setCallback(IConnectionCallback connectionCallback){
    
        this.mConnectionCallback=connectionCallback;
    }


    /** *  Send a message  * * @param message  news  */
    public void sendMessage(String message){
    
        if(mConnectionCallback!=null){
    
            mConnectionCallback.onCallback(message);
        }
    }

    public interface IConnectionCallback {
    

        /** *  Communication callback  * * @param message  news  */
        void onCallback(String message);
    }
}

3. establish RemoteProxy

public class RemoteProxy implements IRemoteBroker {
    

    private static final HiLogLabel LABEL_LOG = new HiLogLabel(0,0x01008,"RemoteProxy");

    private final IRemoteObject remote;

    /** *  Construction method  * * @param remote IRemoteObject example  */
    public RemoteProxy(IRemoteObject remote) {
    
        this.remote = remote;
    }

    @Override
    public IRemoteObject asObject() {
    
        return remote;
    }


    public void sendMessage(String message){
    
        // Encapsulate messages into MessageParcel
        MessageParcel data= MessageParcel.obtain();
        data.writeString(message);

        MessageParcel reply =MessageParcel.obtain();
        MessageOption option =new MessageOption(MessageOption.TF_SYNC);
        try {
    
            // adopt RemoteObject Instance send message 
            remote.sendRequest(IRemoteObject.MIN_TRANSACTION_ID,data,reply,option);

            // Get the message delivery results 
            int ec=reply.readInt();
            if(ec!= Constants.ERR_OK){
    
                throw new RemoteException();
            }
        } catch (RemoteException e) {
    
            HiLog.error(LABEL_LOG,"RemoteException: %{public}s",e.getMessage());
        }
    }
}

4. start-up service

There's no need to start setvice, Connect directly
Start local device Service The code example of is as follows :


Intent intent = new Intent();
Operation operation = new Intent.OperationBuilder()
        .withDeviceId("")
        .withBundleName("com.domainname.hiworld.himusic")
        .withAbilityName("com.domainname.hiworld.himusic.ServiceAbility")
        .build();
intent.setOperation(operation);
startAbility(intent);

Start the remote device Service The code example of is as follows :

Intent intent = new Intent();
Operation operation = new Intent.OperationBuilder()
        .withDeviceId("deviceId")
        .withBundleName("com.domainname.hiworld.himusic")
        .withAbilityName("com.domainname.hiworld.himusic.ServiceAbility")
        .withFlags(Intent.FLAG_ABILITYSLICE_MULTI_DEVICE) //  Set the identification to support multi device startup of distributed dispatching system 
        .build();
intent.setOperation(operation);
startAbility(intent);

5. Connect Service

Define related variables

private Text countdownText;

private static RemoteProxy mRemoteProxy=null;

private final IAbilityConnection connection=new IAbilityConnection() {
    
        @Override
        public void onAbilityConnectDone(ElementName elementName, IRemoteObject iRemoteObject, int i) {
    
            // Successful connection , Instantiate agent 
            mRemoteProxy=new RemoteProxy(iRemoteObject);
            getUITaskDispatcher().asyncDispatch(()->{
    
                countdownText.setText(" Connected ");

            });
        }

        @Override
        public void onAbilityDisconnectDone(ElementName elementName, int i) {
    

        }
    };

Join function

private void connectService(String deviceId){
    
        Intent intent=new Intent();
        Operation operation=new Intent.OperationBuilder()
                .withDeviceId(deviceId)
                .withBundleName(getBundleName())
                .withAbilityName(ServiceAbility.class.getName())
                .withFlags(Intent.FLAG_ABILITYSLICE_MULTI_DEVICE)
                .build();
        intent.setOperation(operation);

        connectAbility(intent,connection);
    }

Send message function

private void sendMessage(String message){
    
        if(mRemoteProxy==null){
    
            ToastUtils.show(getContext()," No cross end connection broker ");
        }
        else{
    
            mRemoteProxy.sendMessage(message);
        }
    }

Message handler

private void handleMessage(String message){
    
        // Process the received message 
    }

Final effect , When the connection is normal, the words "connected" will appear
 Insert picture description here

3、 ... and 、 Be careful

In order to correctly connect the host end and the remote end , The host side actively connects to the remote side , The remote side actively connects to the host side . stay onStart In the function, you should get the devices on the host side and the remote side ID


isMainDevice=intent.getBooleanParam(Constants.PARAM_KEY_IS_MAIN_DEVICE,true);  
mRemoteDeviceId=intent.getStringParam(Constants.PARAM_KEY_REMOTE_DEVICE_ID);
mMainDeviceId=intent.getStringParam(Constants.PARAM_KEY_MAIN_DEVICE_ID);

At the same time, judge whether the current page is created in the form of host or remote end , And in onActive The function uses different connection parameters according to whether it is the host

if(isMainDevice){
    
    connectService(mRemoteDeviceId);
}
else {
    
    connectService(mMainDeviceId);
}

Four 、 Reference resources

Official development documents of Hongmeng
Hongmeng official example code

原网站

版权声明
本文为[Intoxication, thousand layer dream]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/02/202202131441022181.html