Skip to content
This repository has been archived by the owner on Jun 28, 2019. It is now read-only.

[Design] MayLoon prototype design

qi.zhang edited this page Dec 23, 2013 · 2 revisions
 

Table of Contents

Introduction

Goal

MayLoon project’s goal is to get android application executed on browser. Currently Chrome is the target browser.

Scope

This document describes the design of MayLoon. MayLoon is a project to get android application executed on browser. To achieve this goal

1 .Target android application which is coded with JAVA should be compiled with J2S into a JavaScript application. In the future version, J2S should be modified to generate an entry web page which will load MayLoon application framework.

2. MayLoon project should provide a library which includes android application framework in JavaScript named MayLoon application framework.

Structure

.


MayLoon Overview

The whole framework is started through art. MayLoon implements several Android concepts which are different from the original android version. In android, there are some services which are called remotely. In MayLoon, they are all local calls.

C:\Users\siyugu\Desktop\ClassDiagram.png

Context:

In MayLoon framework, there are two types context related: Context of whole framework, context for one Activity (which is the Activity object itself).

PackageManager:

Due to the limitation of browser, MayLoon can only execute one package a time. So PackageManager just parses AndroidManifest.xml under current directory to get the activity info. But in this demo, there is only one activity in Calculator application. PackageManager is not so useful here.

ActivityManager:

553x520px

  1. Get ActivityInfo from PackageManager (there is no this step in this demo)
  2. Create the new activity
  3. Attach the global context to the new Activity
  4. Call OnCreate of new Acitivity

ResourceManager:

When Android’s SDK creating an application’s APK, it convert the application’s XML configure file into binary format, assigns every resource an ID, and write the IDs into the binary file. So it loads these IDs from the binary file when Android framework starts the application. In this demo, we just hard coded these resource informations in AssetManager.

553x331px

Parsing XML in inflator as following:

553x296px

WindowManager

In MayLoon, the window is mainly managed by browser. So MayLoon’s WindowManager is just an entrance for mouse event. When an activity is started, an android.view.Window object is created and registered to WindowManager. In MayLoon, every Android’s View has a corresponding “span” in DOM tree. When this “span” is clicked, MayLoon framework will dispatch the event as following:

553x565px

Display

In MayLoon, one Activity object has a reference to a Window object, and one Window object has a reference to a ViewRoot object. MayLoon will have two things to do before we can see something on the browser.

Inflate

First, we need to inflate the entire view tree. This process is started in Window’s setContentView function. First, we create a DecorView object, this object serves as the container of the activity’s all UI elements, including content panel and menu. And in HTML DOM tree, DecorView’s correspondent element is a span and is the child of document.body. Then, we need to inflate content panel and menu. To inflate content panel, we first parse screen_simple.xml to create a parent node (FrameLayout) in view tree for all UI elements in the content panel. This FrameLayout should be a child of DecorView. Then, according to the main.xml file, we can inflate a sub-tree, whose root is created according to the root node’s information in the xml file. And finally, we make this sub-root a child of FrameLayout. At this point, we finish inflating the content panel and inflating menu is the same. Inflating process is shown in the following diagram.

C:\Users\siyugu\Desktop\inflate.png

In rInflate function, we create, add and inflate all child nodes (with layout parameters set) according to xml file. Inflating menu is the same. When we add one node to its parent’s children list, we call parent view’s addView function. In addView, we call assignParent function of child view, and in this function we use javascript native code to create DOM node. In this way, every widget can override assignParent function and create DOM node in the way it wants.

Measure and Layout

After we have inflated the whole view tree, we can start to display them by calling Window’s startLayout function. This will set DecorView as child node of ViewRoot. ViewRoot object is the true root of the view tree as mentioned above and it is responsible for starting measure pass and layout pass, after which we will have UI elements displayed in the browser.

When ViewRoot thinks it should start measure pass and layout pass, we traverse the whole view tree, figure out how big each UI element should be and calculate the position parameters for them. There are a lot of cases in which ViewRoot thinks it needs to start measure and layout pass, such as first time set ViewRoot’s child view, set visibility of one View and so on.

Using Java inheritance feature, classes that inherit View class can override the onMeasure function in order to carry out their specific measurement on themselves and generate specific layout parameters to their children, and onLayout function in order to use their own strategy when positioning their children. This process is shown in the following diagram.

C:\Users\siyugu\Desktop\measure&layout.png

Generally, ViewGroups’ overridden onMeasure and onLayout function will call their children’s measure and layout function, thus we can measure and layout the whole view tree. We use javascript native to set DOM elements’ attributes after calculating.

After this, all our visible UI elements should be in their right sizes and right positions on the screen.

Opens

N/A

References

  1. Building and Running in Android Developer
  2. Apache Ant Manual
  3. Redline RPM project