Open Source & Free  

New Android Peer Mode

New Android Peer Mode

Header Image

As we mentioned recently we have a new idea on how peering can be improved
and we just deployed a this into our build servers in the weekend update. This is highly experimental and might
crash instantly which is why we hope you give it a test drive and see how it feels before we switch it on by default.

To recap: Peers (or heavyweight components) are OS native widgets. E.g. when you use the BrowserComponent
we effectively load the OS’s native webkit renderer and use that instead of showing HTML ourselves. This is good
as it allows us to use OS native functionality, however it’s bad because peers have a lot of limitations
which we covered in depth here.

One of the biggest limitations has been that peers are always drawn on top of the UI as they are drawn separately
from Codename One. With the original implementation of Codename One which was double buffered this made
a lot of sense, you can’t conceivably implement peers in any other way. However, newer implementations moved
to a more dynamic architecture so we can take better advantage of hardware acceleration…​

With that we can also use this architecture to draw peers directly into the rendering graph which is exactly what
we do in the new Android pipeline changes. Since this is such a huge change we left it off by default and you will
need to set the build hint: android.newPeer=true.

We will remove that build hint in the future so it is undocumented in the developer guide, it’s hard to maintain
that peer due to the complexity of the fork

Please try your apps with the new flag and let us know about crashes, memory leaks or problematic functionality
that didn’t exist before.

This should allow a lot of very exciting functionality, e.g. features like ToastBar, glasspane, layered layout etc.
will work with peer components and will allow you things like drawing on top of a map, video, browser etc.

Notice that this isn’t available on the simulator/iOS at this time so you can only see this working on Android devices.
We plan to add something similar to iOS and the simulator as we move forward.

9 Comments

  • Fabrizio Grassi says:

    Could this affect also the text editing?

  • Diamond says:

    Hi Shai,

    I tested this feature on Samsung S5 mini. App crashes when I tried to open web browser. Some transparency on components overlaid on Google Maps and Google Maps requires touching to get refreshed before it shows, while the overlaid component is already shown. These are the issues I found so far, I will keep testing.

  • Shai Almog says:

    Right now we didn’t touch the text editing code which is a bit of a special case. We might change it in the future.

  • Shai Almog says:

    Thanks. Can you try and get a stack trace from the crash?
    I’m not sure how well transparency will work in these situations. Transparency requires the underlying component to paint itself and we don’t always have a way to force that.

  • Jonathan says:

    Can you use it on the camera live mode ( Capture.capturePhoto()) ?

  • Shai Almog says:

    Capture doesn’t use peer components. It’s a monolithic API.
    One could use a peer component to map to low lever camera native API’s in a cn1lib in a similar way to the native maps implementation. We might do this ourselves at some point but right now our task list is so full I just don’t see this happening.

  • Lukman Javalove Idealist Jaji says:

    Hi Diamond,

    Could you help with how you laid components on a Map? I’ve been wanting to do that

  • Diamond says:

    Hi Lukman, It’s as simple as placing the component in your LayeredPane after adding your map to the form center layout position. remember to add Build Hint “android.newPeer=true” until it’s true by default.

    It’s advisable to do this in postFormShow(), if hand-coded form, do it in the addShowListener() and inside CallSerially. Example 1 – Hand-Coded form:

    form.addShowListener((evt) -> {
    removeAllShowListeners();
    Display.getInstance().callSerially(new Runnable() {
    @Override
    public void run() {
    MapContainer mc = new MapContainer();
    form.add(BorderLayout.CENTER, mc);
    form.getLayeredPane().add(FlowLayout.encloseCenterMiddle(myTestingLabel));
    form.revalidate();
    form.getLayeredPane().revalidate();
    }
    });
    });
    Example 2 – GUI form:

    @Override
    protected void postMyForm(final Form f) {
    Display.getInstance().callSerially(new Runnable() {
    @Override
    public void run() {
    MapContainer mc = new MapContainer();
    f.add(BorderLayout.CENTER, mc);
    f.getLayeredPane().add(FlowLayout.encloseCenterMiddle(myTestingLabel));
    f.revalidate();
    f.getLayeredPane().revalidate();
    }
    });
    }

    THIS code is written here and was not tested.

  • Lukman Javalove Idealist Jaji says:

    Ngiyabonga Diamond ..it worked … 🙂 Thanks for your help once again….

Leave a Reply