For AI agents: the complete documentation index is available at /next/llms.txt, the full documentation bundle is available at /next/llms-full.txt, and this page is available as Markdown at /next/api/lynx-devtool-native-api/lynx-base-inspector-owner/subscribe-message.md.
Lynx
  • English
  • subscribeMessage

    Registers a handler for a specified debugging message type to receive and process messages of that type.

    It works with the sendMessage method to enable two-way communication with the message sender (e.g., the DevTool Desktop Application).

    Syntax

    iOS

    LynxBaseInspectorOwnerNG.h
    - (void)subscribeMessage:(nonnull NSString *)type withHandler:(nonnull id<MessageHandler>)handler;

    Android

    LynxBaseInspectorOwnerNG.java
    void subscribeMessage(String type, MessageHandler handler);

    Harmony

    LynxBaseInspectorOwner.ets
    subscribeMessage(type: string, handler: MessageHandler): void;

    Parameters

    • type: The type of message to subscribe to, such as CDP or other custom message types.
    • handler: An object that implements MessageHandler to receive debugging messages.
    Warning

    DevTool only holds a weak reference to the MessageHandler object. Developers need to manage its lifecycle.

    Usage Example

    Implementation Steps

    1. Implement MessageHandler to process incoming debugging messages.
    2. Get the LynxBaseInspectorOwner instance. On iOS and Android, it needs to be cast to the LynxBaseInspectorOwnerNG type.
    3. Call the subscribeMessage method to subscribe to debugging messages of the specified type.

    Code Example

    The following example code subscribes to CDP messages. When a Page.enable message is received, it sends a Log.entryAdded message with the content Hello, Lynx DevTool!.

    As a result, this log will be displayed in the Console panel of the DevTool Desktop Application.

    Subscribe Message

    iOS

    TestMessageHandler.h
    #import <Lynx/LynxBaseInspectorOwnerNG.h>
    
    @interface TestMessageHandler : NSObject <MessageHandler>
    
    - (instancetype)initWithInspectorOwner:(id<LynxBaseInspectorOwnerNG>)owner;
    
    @end
    TestMessageHandler.m
    #import <UIKit/UIKit.h>
    #import <Lynx/CustomizedMessage.h>
    
    #import "TestMessageHandler.h"
    
    @implementation TestMessageHandler {
      __weak id<LynxBaseInspectorOwnerNG> _owner;
    }
    
    - (instancetype)initWithInspectorOwner:(id<LynxBaseInspectorOwnerNG>)owner {
      self = [super init];
      if (self) {
        _owner = owner;
      }
      return self;
    }
    
    - (void)onMessage:(nonnull NSString *)message {
      NSData *data = [message dataUsingEncoding:NSUTF8StringEncoding];
      NSDictionary *dic = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil];
    
      if ([[dic objectForKey:@"method"] isEqualToString:@"Page.enable"]) {
        id<LynxBaseInspectorOwnerNG> strongOwner = _owner;
        if (!strongOwner) {
          return;
        }
    
        long long timestamp = (long long)([[NSDate date] timeIntervalSince1970] * 1000);
        NSDictionary *logJSON = @{
          @"method": @"Log.entryAdded",
          @"params": @{
            @"entry": @{
              @"level": @"info",
              @"source": @"javascript",
              @"text": @"Hello, Lynx DevTool!",
              @"timestamp": @(timestamp)
            }
          }
        };
    
        NSData *logData = [NSJSONSerialization dataWithJSONObject:logJSON options:0 error:nil];
        NSString *logString = [[NSString alloc] initWithData:logData encoding:NSUTF8StringEncoding];
        if (logString) {
          CustomizedMessage *customizedMessage = [[CustomizedMessage alloc] init];
          customizedMessage.type = @"CDP";
          customizedMessage.data = logString;
          [strongOwner sendMessage:customizedMessage];
        }
      }
    }
    
    @end
    ViewController.m
    #import <Lynx/LynxView.h>
    #import <Lynx/LynxBaseInspectorOwner.h>
    
    #import "TestMessageHandler.h"
    
    @implementation ViewController {
      TestMessageHandler *_handler;
    }
    
    - (void)viewDidLoad {
      [super viewDidLoad];
    
      // ...
    
      id<LynxBaseInspectorOwnerNG> owner = (id<LynxBaseInspectorOwnerNG>)lynxView.baseInspectorOwner;
      _handler = [[TestMessageHandler alloc] initWithInspectorOwner:owner];
      [owner subscribeMessage:@"CDP" withHandler:_handler];
      __weak id<LynxBaseInspectorOwnerNG> weakOwner = owner;
      dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(10 * NSEC_PER_SEC)),
                     dispatch_get_main_queue(), ^{
                       id<LynxBaseInspectorOwnerNG> strongOwner = weakOwner;
                       [strongOwner unsubscribeMessage:@"CDP"];
                     });
    }
    
    @end

    Android

    TestMessageHandler.java
    import com.lynx.devtoolwrapper.CustomizedMessage;
    import com.lynx.devtoolwrapper.LynxBaseInspectorOwnerNG;
    import com.lynx.devtoolwrapper.MessageHandler;
    
    import java.lang.ref.WeakReference;
    
    import org.json.JSONException;
    import org.json.JSONObject;
    
    public class TestMessageHandler implements MessageHandler {
      private final WeakReference<LynxBaseInspectorOwnerNG> mOwner;
    
      public TestMessageHandler(LynxBaseInspectorOwnerNG owner) {
        mOwner = new WeakReference<>(owner);
      }
    
      @Override
      public void onMessage(String message) {
        try {
          JSONObject jsonObject = new JSONObject(message);
          String method = jsonObject.getString("method");
          if ("Page.enable".equals(method)) {
            LynxBaseInspectorOwnerNG owner = mOwner.get();
            if (owner == null) {
              return;
            }
            JSONObject logJSON = new JSONObject();
            logJSON.put("method", "Log.entryAdded");
            logJSON.put("params", new JSONObject().put("entry", new JSONObject()
                .put("level", "info")
                .put("source", "javascript")
                .put("text", "Hello, Lynx DevTool!")
                .put("timestamp", System.currentTimeMillis())));
            CustomizedMessage customizedMessage = new CustomizedMessage("CDP", logJSON.toString());
            owner.sendMessage(customizedMessage);
          }
        } catch (JSONException e) {
          // ...
        }
      }
    }
    MainActivity.java
    import android.os.Handler;
    import android.os.Looper;
    
    import com.lynx.devtoolwrapper.LynxBaseInspectorOwnerNG;
    
    import java.lang.ref.WeakReference;
    
    public class MainActivity extends Activity {
      private TestMessageHandler mTestMessageHandler = null;
    
      @Override
      protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // ...
    
        subscribeCDPMessage(lynxView);
      }
    
      private void subscribeCDPMessage(LynxView lynxView) {
        LynxBaseInspectorOwnerNG owner = (LynxBaseInspectorOwnerNG) lynxView.getBaseInspectorOwner();
        if (owner == null) {
          return;
        }
        mTestMessageHandler = new TestMessageHandler(owner);
        owner.subscribeMessage("CDP", mTestMessageHandler);
        Handler mainHandler = new Handler(Looper.getMainLooper());
        WeakReference<LynxBaseInspectorOwnerNG> weakOwner = new WeakReference<>(owner);
        mainHandler.postDelayed(() -> {
          LynxBaseInspectorOwnerNG strongOwner = weakOwner.get();
          strongOwner.unsubscribeMessage("CDP");
        }, 10000);
      }
    }

    Harmony

    TestMessageHandler.ets
    import { LynxBaseInspectorOwner, MessageHandler } from '@lynx/lynx';
    
    interface LogEntry {
      level: string;
      source: string;
      text: string;
      timestamp: number;
    }
    
    interface LogParams {
      entry: LogEntry;
    }
    
    interface LogMessage {
      method: string;
      params: LogParams;
    }
    
    export class TestMessageHandler implements MessageHandler {
      private owner: WeakRef<LynxBaseInspectorOwner>;
    
      constructor(owner: LynxBaseInspectorOwner) {
        this.owner = new WeakRef(owner);
      }
    
      public onMessage(msg: string): void {
        let json: object = JSON.parse(msg);
        if (json['method'] === 'Page.enable') {
          let owner = this.owner.deref();
          if (!owner) {
            return;
          }
          let log: LogMessage = {
            method: 'Log.entryAdded',
            params: {
              entry: {
                level: 'info',
                source: 'javascript',
                text: 'Hello, Lynx DevTool!',
                timestamp: Date.now(),
              },
            },
          };
          owner.sendMessage('CDP', JSON.stringify(log));
        }
      }
    }
    Index.ets"
    import { LynxView, LynxContext } from '@lynx/lynx';
    import { TestMessageHandler } from './TestMessageHandler'
    
    @Entry
    @Component
    struct Index {
      // ...
      private handler?: TestMessageHandler;
    
      build() {
        Column() {
          LynxView({
            // ...
            onCreate: (context: LynxContext) => {
              let owner = context?.getBaseInspectorOwner();
              if (owner) {
                this.handler = new TestMessageHandler(owner);
                owner.subscribeMessage('CDP', this.handler);
                let weakOwner = new WeakRef(owner);
                setTimeout(() => {
                  let owner = weakOwner.deref();
                  owner?.unsubscribeMessage('CDP');
                }, 10000);
              }
            }
          }).width('100%').height('100%');
        }
      }
    }

    Compatibility

    LCD tables only load in the browser

    Except as otherwise noted, this work is licensed under a Creative Commons Attribution 4.0 International License, and code samples are licensed under the Apache License 2.0.