Author: Han Ru

Company: Program Ka (Beijing) Technology Co., LTD

Hong Meng Bus columnist

First, use scenarios

EventHandler development scenario

The main function of EventHandler is to post the InnerEvent or Runnable task to another thread for processing. The scenarios include:

  • The developer needs to post the InnerEvent event to a new thread, which is processed by priority and latency. During delivery, the EventHandler priority can be set to IMMEDIATE, HIGH, LOW, or IDLE, and an appropriate delayTime can be set.
  • The developer needs to post Runnable tasks to a new thread and process them according to priority and latency. During delivery, the EventHandler priority can be set to IMMEDIATE, HIGH, LOW, or IDLE, and an appropriate delayTime can be set.
  • The developer needs to post events in the newly created thread to the original thread for processing.

EventRunner Working mode

EventRunner can be divided into hosted mode and manual mode. The two modes are implemented by selecting different parameters when calling EventRunner’s Create () method, as shown in the API reference. The default mode is managed.

  • Hosted mode: No need for developers to call the run() and stop() methods to start and stop EventRunner. When EventRunner is instantiated, the system calls Run () to start EventRunner; When EventRunner is not referenced, stop() is called to stop EventRunner.
  • Manual mode: The developer calls EventRunner’s run() and stop() methods to ensure that the thread is started and stopped.

Second, the EventHandler

EventHandler, which allows sending and processing of InnerEvent and Runnable objects on asynchronous threads. Each EventHandler instance is bound to a thread that has an event queue. The thread periodically retrieves events from the event queue and dispatches them to EventHandler for processing. EventHandler passes the event or Runnable task to the thread’s event queue and executes it when the event or task comes out of the event queue.

You can use EventHandler to schedule and process events and Runnable objects between different threads and schedule events or Runnable objects for processing at specific time intervals.

You can use the methods provided in this class to send synchronous or asynchronous events, delay event processing, and set event priorities.

You need to rewrite the processEvent (ohos. Eventhandler. InnerEvent) method to handle the event.

Definition of the EventHandler class:

java.lang.Object

|---ohos.eventhandler.EventHandler
public class EventHandler extends Object
Copy the code

EventHandler attribute Priority

EventRunner will retrieve events or Runnable tasks from the event queue for processing, depending on their priority.

attribute describe
Priority.IMMEDIATE Indicates that the event is delivered immediately
Priority.HIGH Indicates that events are delivered before LOW priority
Priority.LOW The event priority is higher than IDLE. The default event priority is LOW
Priority.IDLE Indicates that the event is delivered only if no other events exist

The main methods of EventHandler:

The interface name describe
EventHandler(EventRunner runner) Create an EventHandler using an existing EventRunner
current() In the processEvent callback, get the current EventHandler
processEvent(InnerEvent event) Callbacks handle events and are implemented by the developer
sendEvent(InnerEvent event) Sends an event to the event queue with a delay of 0ms and a priority of LOW
sendEvent(InnerEvent event, long delayTime) Sends a delayed event to the event queue with a LOW priority
sendEvent(InnerEvent event, long delayTime, EventHandler.Priority priority) Sends a delayed event of the specified priority to the event queue
sendEvent(InnerEvent event, EventHandler.Priority priority) Sends an event of the specified priority to the event queue with a delay of 0ms
sendSyncEvent(InnerEvent event) Sends a synchronization event to the event queue with a delay of 0ms and a priority of LOW
sendSyncEvent(InnerEvent event, EventHandler.Priority priority) Sends a synchronization event with a specified priority to the event queue. The delay is 0ms. The priority cannot be IDLE
postSyncTask(Runnable task) Sends a Runnable synchronization task to the event queue with a delay of 0ms and a priority of LOW
postSyncTask(Runnable task, EventHandler.Priority priority) Sends a Runnable synchronization task of the specified priority to the event queue with a delay of 0ms
postTask(Runnable task) Sends a Runnable task to the event queue with a delay of 0ms and a priority of LOW
postTask(Runnable task, long delayTime) Sends a Runnable delayed task to the event queue with a LOW priority
postTask(Runnable task, long delayTime, EventHandler.Priority priority) Sends a Runnable delayed task with the specified priority to the event queue
postTask(Runnable task, EventHandler.Priority priority) Sends a Runnable task of the specified priority to the event queue with a delay of 0ms
sendTimingEvent(InnerEvent event, long taskTime) Sends a scheduled event to the queue. It is executed at taskTime. If the taskTime is smaller than the current time, it is executed immediately with LOW priority
sendTimingEvent(InnerEvent event, long taskTime, EventHandler.Priority priority) Sends a priority event to the queue, executed at taskTime or immediately if taskTime is less than the current time
postTimingTask(Runnable task, long taskTime) Send a Runnable task to the queue and execute it at taskTime. If the taskTime is smaller than the current time, execute it immediately with LOW priority
postTimingTask(Runnable task, long taskTime, EventHandler.Priority priority) Send a Runnable task with priority to the queue and execute it at taskTime or immediately if the taskTime is less than the current time
removeEvent(int eventId) Deletes an event with a specified ID
removeEvent(int eventId, long param) Deletes events with the specified ID and param
removeEvent(int eventId, long param, Object object) Deletes events with the specified ID, param, and Object
removeAllEvent() Delete all events for the EventHandler
getEventName(InnerEvent event) Gets the name of the event
getEventRunner() Gets the EventRunner for the EventHandler binding
isIdle() Checks whether the queue is empty
HasInnerEvent (Runnable Runnable) Checks if there are any unprocessed tasks based on the specified runnable parameter. Check can be performed according to different input parameters, see detailsEventHandler

Third, EventRunner

EventRunner, which creates and manages event queues in the current thread.

After calling the run() method, EventRunner retrieves events consecutively from the event queue and dispatches them to the matching EventHandler. The EventHandler#processEvent (InnerEvent) method is then called to process the event.

EventRunner class definition.

java.lang.Object

|---ohos.eventhandler.EventRunner

public final class EventRunner extends Object
Copy the code

Main methods of EventRunner:

The interface name describe
create() Create an EventRunner with a new thread
create(boolean inNewThread) Create an EventRunner with a new thread. If inNewThread is true, the EventRunner is in managed mode and the system will automatically manage the EventRunner. If inNewThread is false, the EventRunner mode is manual
create(String newThreadName) Create an EventRunner with a new thread named newThreadName
current() Gets the EventRunner for the current thread
run() When EventRunner is in manual mode, this method is called to start a new thread
stop() When EventRunner is in manual mode, this method is called to stop the new thread

Four, InnerEvent

InnerEvent, which defines the structure of the event that can be sent to EventHandler.

InnerEvent class definition:

public final class InnerEvent
extends Object
implements Sequenceable
Copy the code

An InnerEvent object that contains an extra integer field and an extra object field to carry specific data.

InnerEvent properties:

attribute describe
eventId Event ID, defined by the developer to identify the event
object Object information carried by the event
param The long data carried by the event

The InnerEvent constructor is private. Therefore, the get() method is called to create the InnerEvent instance. This method extracts the InnerEvent instance from the pool of reclaimed objects.

Common methods:

The method name describe
drop() Releases an event instance
get() Get an event instance
get(int eventId) Gets an event instance of the specified eventId
get(int eventId, long param) Gets an event instance of the specified eventId and Param
get(int eventId, long param, Object object) Gets an event instance of the specified eventId, Param, and Object
get(int eventId, Object object) Gets an event instance of the specified eventId and Object
PacMap getPacMap() Get PacMap, if not, create a new one
Runnable getTask() Get the Runnable task
PacMap peekPacMap() Get PacMap
void setPacMap(PacMap pacMap) Set the PacMap

Please check out the official API for more methods

5. Process logic

5.1 EventHandler delivers the InnerEvent event

The EventHandler delivers the InnerEvent and processes the event by priority and delay as follows:

  1. Create a subclass of EventHandler and override the implementation method processEvent() to handle the event.
	 private static final int EVENT_MESSAGE_NORMAL = 1;
   private static final int EVENT_MESSAGE_DELAY = 2;
   
   private class MyEventHandler extends EventHandler {
       private MyEventHandler(EventRunner runner) {
           super(runner);
       }
       // Override the processEvent method
       @Override
       public void processEvent(InnerEvent event) {
           super.processEvent(event);
           if (event == null) {
               return;
           }
           int eventId = event.eventId;
           switch (eventId) {
               case EVENT_MESSAGE_NORMAL:
                   // The action to be performed is defined by the developer
                   break;
               case EVENT_MESSAGE_DELAY:
                   // The action to be performed is defined by the developer
                   break;
               default:
                   break; }}}Copy the code
  1. Create an EventRunner, using manual mode as an example.
   EventRunner runner = EventRunner.create(false);// Managed mode when create() is true
Copy the code
  1. Create an instance of the EventHandler subclass.
MyEventHandler myHandler = new MyEventHandler(runner);
Copy the code
  1. Gets the InnerEvent event.
   EventId, Param, object are determined by the developer.
   long param = 0L; 
   Object object = null; 
   InnerEvent normalInnerEvent = InnerEvent.get(EVENT_MESSAGE_NORMAL, param, object);
   InnerEvent delayInnerEvent = InnerEvent.get(EVENT_MESSAGE_DELAY, param, object);
Copy the code
  1. The delivery event takes IMMEDIATE as an example. The delivery delay is set to 0ms or 2ms.
/ / the IMMEDIATE Priority, the processed immediately after delivery, delay of 0 ms, this statement is equivalent to synchronous delivery sendSyncEvent (event1, EventHandler. Priority. IMMEDIATE);
myHandler.sendEvent(normalInnerEvent, 0, EventHandler.Priority.IMMEDIATE);
myHandler.sendEvent(delayInnerEvent, 2, EventHandler.Priority.IMMEDIATE); // Process immediately after 2ms delay
Copy the code
  1. Start and stop EventRunner. This step is not required if you are in hosted mode.
   runner.run();// Run runner. Stop (); // Developers discontinue EventRunner when appropriate, depending on business needs
Copy the code

5.2 EventHandler delivers Runnable tasks

EventHandler delivers Runnable tasks and processes them according to priority and latency as follows:

  1. Create a subclass of EventHandler, create An EventRunner, and create an instance of an EventHandler subclass as you did in steps 1-3 for EventHandler to post the InnerEvent scene.

  2. Create a Runnable task.

   Runnable normalTask = new Runnable() {
       @Override
       public void run(a) {
           // The action to be performed is defined by the developer}}; Runnable delayTask =new Runnable() {
       @Override
       public void run(a) {
           // The action to be performed is defined by the developer}};Copy the code
  1. The delivery priority of the Runnable task is IMMEDIATE, and the delivery delay is set to 0ms or 2ms.
   / / for the immediate Priority, delay 0 ms, this statement is equivalent to the synchronous delivery myHandler. PostSyncTask (task1, EventHandler. Priority. Immediate);
   myHandler.postTask(normalTask, 0, EventHandler.Priority.IMMEDIATE);
   
   myHandler.postTask(delayTask, 2, EventHandler.Priority.IMMEDIATE);// Execute immediately after 2ms delay
Copy the code
  1. Start and stop EventRunner. This step is not required if you are in hosted mode.
   runner.run();
   // Operation to be performed
   
   runner.stop();/ / stop EventRunner
Copy the code

5.3 Post events in the newly created thread to the original thread

EventHandler posts events from the newly created thread to the original thread and processes them as follows:

  1. Create a subclass of EventHandler and override the implementation method processEvent() to handle the event.
   private static final int EVENT_MESSAGE_CROSS_THREAD = 1;
   
   private class MyEventHandler extends EventHandler {
       private MyEventHandler(EventRunner runner) {
           super(runner);
       }
       // Override the processEvent method
       @Override
       public void processEvent(InnerEvent event) {
           super.processEvent(event);
           if (event == null) {
               return;
           }
           int eventId = event.eventId;
           switch (eventId) {
               case EVENT_MESSAGE_CROSS_THREAD:
                   Object object = event.object;
                   if (object instanceof EventRunner) {
                       // Post the EventRunner instance of the original thread to the newly created thread
                       EventRunner runner2 = (EventRunner) object;
                       // Bind the EventRunner instance of the original thread to the EventHandler of the newly created thread
                       EventHandler myHandler2 = new EventHandler(runner2) {
                           @Override
                           public void processEvent(InnerEvent event) {
                               // The operation that needs to be performed in the original thread}};int eventId2 = 1; 
                       long param2 = 0L; 
                       Object object2 = null; 
                       InnerEvent event2 = InnerEvent.get(eventId2, param2, object2);
                       myHandler2.sendEvent(event2); // post the event to the original thread
                   }
                   break;
               default:
                   break; }}}Copy the code
  1. Create an EventRunner, using manual mode as an example.
   EventRunner runner = EventRunner.create(false);// Managed mode when create() is true.
Copy the code
  1. Create an instance of the EventHandler subclass.
   MyEventHandler myHandler = new MyEventHandler(runner);
Copy the code
  1. Gets the InnerEvent event.
EventId, Param, object are determined by the developer.
long param = 0L; 
InnerEvent event = InnerEvent.get(EVENT_MESSAGE_CROSS_THREAD, param, EventRunner.current());
Copy the code
  1. Post events, handled directly on the new thread.
// Post the EventRunner bound to the current thread to the new thread created with Runner
myHandler.sendEvent(event);
Copy the code
  1. Start and stop EventRunner. This step is not required if you are in hosted mode.
   runner.run();// Operation to be performed
   runner.stop();/ / stop EventRunner
Copy the code

6, complete

Unmanaged situation:

/ / global:
public static final int CODE_DOWNLOAD_FILE1 = 1;
public static final int CODE_DOWNLOAD_FILE2 = 2;
public static final int CODE_DOWNLOAD_FILE3 = 3;

// thread A:
EventRunner runnerA = EventRunner.create(false);
runnerA.run(); // Run has been stuck here since then, so we need to create a new thread run

// thread B:
// 1. Create class inheriting EventHandler
public class MyEventHandler extends EventHandler {
    private MyEventHandler(EventRunner runner) {
        super(runner);
    }

    @Override
    public void processEvent(InnerEvent event) {
        super.processEvent(event);
        if (event == null) {
            return;
        }

        int eventId = event.eventId;
        switch (eventId) {
            case CODE_DOWNLOAD_FILE1: {
                // The action to be performed is defined by the developer
                break;
            }
            case CODE_DOWNLOAD_FILE2: {
                // The action to be performed is defined by the developer
                break;
            }
            case CODE_DOWNLOAD_FILE3: {
                // The action to be performed is defined by the developer
                break;
            }
            default:
                break; }}}// 2. Create MyEventHandler instance
MyEventHandler handler = new MyEventHandler(runnerA);

// 3. Send events to thread A
handler.sendEvent(CODE_DOWNLOAD_FILE1);
handler.sendEvent(CODE_DOWNLOAD_FILE2);
handler.sendEvent(CODE_DOWNLOAD_FILE3);

// 4. RunnerA exits after it is no longer used
runnerA.stop();
Copy the code

Trusteeship:

/ / global:
public static final int CODE_DOWNLOAD_FILE1 = 1;
public static final int CODE_DOWNLOAD_FILE2 = 2;
public static final int CODE_DOWNLOAD_FILE3 = 3;

// create EventRunner A:
EventRunner runnerA = EventRunner.create("downloadRunner"); // a new thread is created internally

// 2. Create class inheriting EventHandler
public class MyEventHandler extends EventHandler {
    private MyEventHandler(EventRunner runner) {
        super(runner);
    }

    @Override
    public void processEvent(InnerEvent event) {
        super.processEvent(event);
        if (event == null) {
            return;
        }

        int eventId = event.eventId;
        switch (eventId) {
            case CODE_DOWNLOAD_FILE1: {
                // The action to be performed is defined by the developer
                break;
            }
            case CODE_DOWNLOAD_FILE2: {
                // The action to be performed is defined by the developer
                break;
            }
            case CODE_DOWNLOAD_FILE3: {
                // The action to be performed is defined by the developer
                break;
            }
            default:
                break; }}}// 3. Create MyEventHandler instance
MyEventHandler handler = new MyEventHandler(runnerA);

// 4. Send events to thread A
handler.sendEvent(CODE_DOWNLOAD_FILE1);
handler.sendEvent(CODE_DOWNLOAD_FILE2);
handler.sendEvent(CODE_DOWNLOAD_FILE3);

// 5.runnerA is automatically reclaimed by the thread when no object is imported
runnerA = null;
Copy the code

### ##

1. EventHandler delivers the InnerEvent event

We now put a button in ability_main.xml:

<? xml version="1.0" encoding="utf-8"? > <DirectionalLayout xmlns:ohos="http://schemas.huawei.com/res/ohos"
    ohos:height="match_parent"
    ohos:width="match_parent"
    ohos:padding="20vp"
    ohos:orientation="vertical">


    <Button
        ohos:id="$+id:btn1"
        ohos:height="match_content"
        ohos:width="match_content"
        ohos:text="EventHandler delivers InnerEvent event"
        ohos:background_element="#eeeeee"
        ohos:padding="20vp"
        ohos:multiple_lines="true"
        ohos:text_size="20fp"
        ohos:margin="10vp"
        />


</DirectionalLayout>
Copy the code

Then handle the button click event in MainAbility and post the InnerEvent event:

package com.example.hanrueventhandler.slice;

import com.example.hanrueventhandler.ResourceTable;
import ohos.aafwk.ability.AbilitySlice;
import ohos.aafwk.content.Intent;
import ohos.agp.components.Button;
import ohos.agp.components.Component;
import ohos.agp.components.Text;
import ohos.eventhandler.EventHandler;
import ohos.eventhandler.EventRunner;
import ohos.eventhandler.InnerEvent;
import ohos.hiviewdfx.HiLog;
import ohos.hiviewdfx.HiLogLabel;

public class MainAbilitySlice extends AbilitySlice {

    private static final int EVENT_MESSAGE_NORMAL = 1;
    private static final int EVENT_MESSAGE_DELAY = 2;
    // Define log labels
    private static final HiLogLabel LABEL = new HiLogLabel(HiLog.LOG_APP, 0x00201."MY_TAG");

    @Override
    public void onStart(Intent intent) {
        super.onStart(intent);
        super.setUIContent(ResourceTable.Layout_ability_main);
        initComponent();

    }

    public void initComponent(a){
        findComponentById(ResourceTable.Id_btn1).setClickedListener(component -> eventHandlerPostInnerEvent());
    }


    // Button 1: EventHandler delivers the InnerEvent event
    public void eventHandlerPostInnerEvent(a){
        // 2. Create EventRunner in manual or hosted mode
        EventRunner runner = EventRunner.create(true);// Managed mode when create() is true

        // 3. Create an instance of the EventHandler subclass.
        MyEventHandler myHandler = new MyEventHandler(runner);

        // 4. Get the InnerEvent event.
        // Get the event instance whose attributes eventId, Param, object are determined by the developer.
        long param1 = 9527L;
        Object object1 = "I am Wang Ergou.";
        InnerEvent normalInnerEvent = InnerEvent.get(EVENT_MESSAGE_NORMAL, param1, object1);

        long param2 = 1314L;
        Object object2 = "Hung Mun Bus";
        InnerEvent delayInnerEvent = InnerEvent.get(EVENT_MESSAGE_DELAY, param2, object2);

        HiLog.info(LABEL,"...");


        // 5. The delivery event takes IMMEDIATE as an example. The delivery delay is 0ms or 2ms
        / / the IMMEDIATE Priority, the processed immediately after delivery, delay of 0 ms, this statement is equivalent to synchronous delivery sendSyncEvent (event1, EventHandler. Priority. IMMEDIATE);
        myHandler.sendEvent(normalInnerEvent, 0, EventHandler.Priority.IMMEDIATE); // Immediate processing
        myHandler.sendEvent(delayInnerEvent, 2, EventHandler.Priority.IMMEDIATE); // Process immediately after 2ms delay

        // 6. Start and stop EventRunner. This step is not required if you are in hosted mode.
        // runner.run();
        // Operation to be performed
        // runner.stop(); // Developers discontinue EventRunner when appropriate, depending on business needs

    }

    // 1. Create a subclass of EventHandler and override the implementation method processEvent() to handle events.
    private class MyEventHandler extends EventHandler {
        private MyEventHandler(EventRunner runner) {
            super(runner);
        }
        // Override the processEvent method
        @Override
        public void processEvent(InnerEvent event) {
            super.processEvent(event);
            if (event == null) {
                return;
            }
            int eventId = event.eventId;
            long param = event.param;
            Object object = event.object;
            HiLog.info(LABEL,"Child thread... The thread ID"+Thread.currentThread().getId()+", thread name:+Thread.currentThread().getName());
            switch (eventId) {
                case EVENT_MESSAGE_NORMAL:
                    // The action to be performed is defined by the developer
                    HiLog.info(LABEL,"Operation 1 to be processed in child thread..."+param+","+ object.toString());

                    break;
                case EVENT_MESSAGE_DELAY:
                    // The action to be performed is defined by the developer
                    HiLog.info(LABEL,"Operation 2 to be processed in child thread..."+param+","+ object.toString());
                    break;
                default:
                    break; }}}}Copy the code

Run the program and click button 1:

EventHandler delivers Runnable tasks

Now in ability_main.xml, put another button:

<? xml version="1.0" encoding="utf-8"? > <DirectionalLayout xmlns:ohos="http://schemas.huawei.com/res/ohos"
    ohos:height="match_parent"
    ohos:width="match_parent"
    ohos:padding="20vp"
    ohos:orientation="vertical">... <Button ohos:id="$+id:btn2"
        ohos:height="match_content"
        ohos:width="match_content"
        ohos:text="EventHandler delivers Runnable task"
        ohos:background_element="#eeeeee"
        ohos:multiple_lines="true"
        ohos:padding="20vp"
        ohos:text_size="20fp"
        ohos:margin="10vp"
        />


</DirectionalLayout>
Copy the code

Then handle the button click event in MainAbility and post the Runnable task:


    public void initComponent(a){
        findComponentById(ResourceTable.Id_btn1).setClickedListener(component -> eventHandlerPostInnerEvent());
        findComponentById(ResourceTable.Id_btn2).setClickedListener(component -> eventHandlerPostRunnableTask());
    }

    // 2.EventHandler posts the Runnable task
    public void eventHandlerPostRunnableTask(a){
        // 2. Create EventRunner in manual or hosted mode
        EventRunner runner = EventRunner.create(true);// Managed mode when create() is true

        // 3. Create an instance of the EventHandler subclass.
        MyEventHandler myHandler = new MyEventHandler(runner);

        Create a Runnable task.
        Runnable normalTask = new Runnable() {
            @Override
            public void run(a) {
                // The action to be performed is defined by the developer
                HiLog.info(LABEL,"Child thread ID:+Thread.currentThread().getId()+", child thread name:"+Thread.currentThread().getName()+"-- - > Runnable normalTask." "); }}; Runnable delayTask =new Runnable() {
            @Override
            public void run(a) {
                // The action to be performed is defined by the developer
                HiLog.info(LABEL,"Child thread ID:+Thread.currentThread().getId()+", child thread name:"+Thread.currentThread().getName()+"-- - > Runnable delayTask." "); }}; HiLog.info(LABEL,"...");
        / / 5. Delivery
        / / for the immediate Priority, delay 0 ms, this statement is equivalent to the synchronous delivery myHandler. PostSyncTask (task1, EventHandler. Priority. Immediate);
        myHandler.postTask(normalTask, 0, EventHandler.Priority.IMMEDIATE);

        myHandler.postTask(delayTask, 2, EventHandler.Priority.IMMEDIATE);// Execute immediately after 2ms delay



        // 6. Start and stop EventRunner. This step is not required if you are in hosted mode.
        // runner.run();
        // Operation to be performed
        // runner.stop(); / / stop EventRunner
    }

    
Copy the code

Run the program and click button 2:

Post events in the newly created thread to the original thread

Now in ability_main.xml, put another button:

<? xml version="1.0" encoding="utf-8"? > <DirectionalLayout xmlns:ohos="http://schemas.huawei.com/res/ohos"
    ohos:height="match_parent"
    ohos:width="match_parent"
    ohos:padding="20vp"
    ohos:orientation="vertical">... <Button ohos:id="$+id:btn3"
        ohos:height="match_content"
        ohos:width="match_content"
        ohos:text="Post events to the original thread in the newly created thread"
        ohos:background_element="#eeeeee"
        ohos:padding="20vp"
        ohos:multiple_lines="true"
        ohos:text_size="20fp"
        ohos:margin="10vp"
        />


</DirectionalLayout>
Copy the code

Then handle the button click event in MainAbility and post the event to the original thread in the newly created thread:

public void initComponent(a){
        findComponentById(ResourceTable.Id_btn1).setClickedListener(component -> eventHandlerPostInnerEvent());
        findComponentById(ResourceTable.Id_btn2).setClickedListener(component -> eventHandlerPostRunnableTask());
        findComponentById(ResourceTable.Id_btn3).setClickedListener(component -> postInnerEventToOriginalThread());
    }

    // 3. Post events in the newly created thread to the original thread
    public void postInnerEventToOriginalThread(a){
        // 2. Create EventRunner in manual or hosted mode
        EventRunner runner = EventRunner.create(true);// Managed mode when create() is true

        // 3. Create an instance of the EventHandler subclass.
        MyEventHandler myHandler = new MyEventHandler(runner);

        // 4. Get the InnerEvent event.
        // Get the event instance whose attributes eventId, Param, object are determined by the developer.
        long param = 723L;
        // Note that the third argument, Object, is passed to the current thread Object.
        InnerEvent event = InnerEvent.get(EVENT_MESSAGE_CROSS_THREAD, param, EventRunner.current());

        // 5. Post the EventRunner bound to the current thread to the new thread created with Runner
        myHandler.sendEvent(event);


        // 6. Start and stop EventRunner. This step is not required if you are in hosted mode.
        // runner.run();
        // Operation to be performed
        // runner.stop(); // Developers discontinue EventRunner when appropriate, depending on business needs
    }
Copy the code

Then we add another case to the MyEventHandler:

private class MyEventHandler extends EventHandler {
        private MyEventHandler(EventRunner runner) {
            super(runner);
        }
        // Override the processEvent method
        @Override
        public void processEvent(InnerEvent event) {
            super.processEvent(event);
            if (event == null) {
                return;
            }
            int eventId = event.eventId;
            long param = event.param;
            Object object = event.object;
            HiLog.info(LABEL,"Child thread... The thread ID"+Thread.currentThread().getId()+", thread name:+Thread.currentThread().getName());
            switch (eventId) {
                case EVENT_MESSAGE_NORMAL:
                    // The action to be performed is defined by the developer
                    break;
                case EVENT_MESSAGE_DELAY:
                    // The action to be performed is defined by the developer
                    break;
                case EVENT_MESSAGE_CROSS_THREAD:
                    if (object instanceof EventRunner) {
                        HiLog.info(LABEL,"Operation 3 to be processed in child thread..."+param+","+ object.toString());
                        // Post the EventRunner instance of the original thread to the newly created thread
                        EventRunner runner2 = (EventRunner) object;
                        // Bind the EventRunner instance of the original thread to the EventHandler of the newly created thread
                        EventHandler myHandler2 = new EventHandler(runner2) {
                            @Override
                            public void processEvent(InnerEvent event) {
                                // The operation that needs to be performed in the original thread
                                HiLog.info(LABEL,"The original thread..."+Thread.currentThread().getId()+","+Thread.currentThread().getName());
                                HiLog.info(LABEL,"The original thread... eventId"+event.eventId+", Param:+event.param+", object:"+event.object); }};int eventId2 = 1;
                        long param2 = 9988L;
                        Object object2 = "I am a cabbage.";
                        InnerEvent event2 = InnerEvent.get(eventId2, param2, object2);
                        myHandler2.sendEvent(event2); // post the event to the original thread
                    }
                    break;
                default:
                    break; }}}Copy the code

Run the program and click button 3: