Event Dispatching fails when Called from Initialize

package space.themelon.dispatchtest;

import android.util.Log;
import com.google.appinventor.components.annotations.DesignerComponent;
import com.google.appinventor.components.annotations.SimpleEvent;
import com.google.appinventor.components.annotations.SimpleFunction;
import com.google.appinventor.components.annotations.SimpleObject;
import com.google.appinventor.components.common.ComponentCategory;
import com.google.appinventor.components.runtime.AndroidNonvisibleComponent;
import com.google.appinventor.components.runtime.EventDispatcher;
import com.google.appinventor.components.runtime.Form;

@DesignerComponent(version = 1,
        category = ComponentCategory.EXTENSION,
        nonVisible = true)
@SimpleObject(external = true)
public class DispatchTest extends AndroidNonvisibleComponent {

  private static final String TAG = "DispatchTest";

  public DispatchTest(Form form) {
    super(form);
  }

  @SimpleFunction
  public void DispatchEvent() {
    MyEvent("hello world");
  }

  @SimpleEvent
  public void MyEvent(String arg) {
    boolean dispatched = EventDispatcher.dispatchEvent(this, "MyEvent", arg);
    Log.d(TAG, "Event Dispatched = " + dispatched);
  }
}

The above code contains simple blocks, a block called DispatchEvent() that calls MyEvent("hello world"). This is expected to work correctly, but the following behaviour happens:

  • When DispatchEvent() block is called from Initialize event block, EventDispatcher.dispatchEvent() returns false.

  • When DispatchEvent() block is called on an event of a Button click, the event gets dispatched successfully.

[kumaraswamy@ekita ~]$ adb logcat -s DispatchTest
--------- beginning of main
05-19 22:12:29.488  5765  5765 D DispatchTest: Event Dispatched = false
05-19 22:12:31.039  5765  5765 D DispatchTest: Event Dispatched = true

DispatchTest.aia (5.7 KB)
space.themelon.dispatchtest.aix (5.0 KB)

Tested in compiled application.

3 Likes
package space.themelon.dispatchtest;

import android.os.Handler;
import android.util.Log;
import com.google.appinventor.components.annotations.DesignerComponent;
import com.google.appinventor.components.annotations.SimpleEvent;
import com.google.appinventor.components.annotations.SimpleFunction;
import com.google.appinventor.components.annotations.SimpleObject;
import com.google.appinventor.components.common.ComponentCategory;
import com.google.appinventor.components.runtime.AndroidNonvisibleComponent;
import com.google.appinventor.components.runtime.EventDispatcher;
import com.google.appinventor.components.runtime.Form;

@DesignerComponent(
        version = 1,
        description = "A test extension to dispatch an event.",
        category = ComponentCategory.EXTENSION,
        nonVisible = true,
        iconName = "images/extension.png"
)
@SimpleObject(external = true)
public class DispatchTest extends AndroidNonvisibleComponent {

    private static final String TAG = "DispatchTest";

    public DispatchTest(Form form) {
        super(form);
    }

    @SimpleFunction(description = "Dispatches MyEvent with the given argument.")
    public void DispatchEvent() {
        Handler handler = new Handler();
        handler.postDelayed(new Runnable() {
            @Override
            public void run() {
                MyEvent("hello world");
            }
        }, 100); 
    }

    @SimpleEvent(description = "This event is triggered with a string argument.")
    public void MyEvent(String arg) {
        boolean dispatched = EventDispatcher.dispatchEvent(this, "MyEvent", arg);
        Log.d(TAG, "Event Dispatched = " + dispatched);
    }
}

Hopefully, this Java code can do what you want to do @Kumaraswamy

1 Like

This is by design. No events can be dispatched until the screen finishes initializing and its Initialize event runs. If you have events you need to dispatch, you should defer them until after initialization of the screen has completed.

1 Like

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.

One might expect special design rules to apply to processing done from within Screen1.initialize. Inference from the following topic, suggests that at least some events cannot be scheduled/queued from initialize execution.

I suspect the following simple app, init_sandbox, illustrates such a case having to do with events being "scheduled" or "queued" during Screen1.Initialize execution.

init_sandbox.aia (23.6 KB)

Once the app in installed, the phone settings is used to enable permissions for CAMERA and CONTACT.

When the init_sandbox app starts, Screen1.Initialize requests permission for CAMERA and CONTACT access. But neither the PermissionGranted nor the PermissionDenied event is execute.

When the Re-initialze button is pressed, the same permissions are requested and both are granted giving rise to the execution of the PermissionGranted event for both of them.

Is there something more complex going on here OR is it simply that events scheduled during Screen1.Initialize are ignored?

Are there other restrictions to processing done in Screen1.Initiallize?

Kind regards,
-Randal