Lifecycle of a Processing sketch

codeanticode edited this page Dec 22, 2017 · 6 revisions

This page is intended to give an overview of how a Processing for Android sketch is initialized and run by the Android system, and to help understanding what classes from the core library are involved in handling the low-level rendering and input operations through the Android API. This lifecyle is different depending if the sketch is run as a regular app, a live wallpaper, a watch face, or a VR app. Let's start looking into the details for a regular app:

Running a sketch as a regular app

Every time you run a sketch from from the Android mode as a regular app, for example something as simple as the following code:

void setup() {
  fullScreen(P2D);
}
void draw() {
  if (mousePressed) {
    ellipse(mouseX, mouseY, 50, 50);
  }
}

Processing will automatically convert this code into a valid Android project, which will then build into an app package (.apk) using Gradle, and finally install on the device or in the emulator using the Android Debug Bridge (adb) tool available in the Android SDK.

For the code above, Processing will generate two separate java files, one holding the sketch itself and another the main activity that will launch the sketch inside a fragment that contains nothing but our sketch:

Main Activity:

package core_debug;

import android.os.Bundle;
import android.content.Intent;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import android.support.v7.app.AppCompatActivity;

import processing.android.PFragment;
import processing.android.CompatUtils;
import processing.core.PApplet;

public class MainActivity extends AppCompatActivity {
  private PApplet sketch;

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    FrameLayout frame = new FrameLayout(this);
    frame.setId(CompatUtils.getUniqueViewId());
    setContentView(frame, new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
                                                     ViewGroup.LayoutParams.MATCH_PARENT));

    sketch = new Sketch();
    PFragment fragment = new PFragment(sketch);
    fragment.setView(frame, this);
  }

  @Override
  public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
    if (sketch != null) {
      sketch.onRequestPermissionsResult(
      requestCode, permissions, grantResults);
    }
  }

  @Override
  public void onNewIntent(Intent intent) {
    if (sketch != null) {
      sketch.onNewIntent(intent);
    }
  }
}

Processing sketch:

package core_debug;

import processing.core.PApplet;

public class Sketch extends PApplet {
  public void settings() {
    fullScreen(P2D);
  }

  public void draw() {
    if (mousePressed) {
      ellipse(mouseX, mouseY, 50, 50);
    }
  }
}

You will notice that the sketch code is different from what we originally wrote in the PDE. It is all included in a subclass of PApplet, which is the base class containing most of the Processing API. Another detail is that the fullScreen() call was moved from setup() into settings(). We will see why in a bit. These transformations in the code are carried out by the Processing pre-processor, which makes sure that our Processing sketch (which as it is is not 100% syntactically valid Java) is ready to be compiled by the standard Java compiler.

The important part in the Main Activity code is the three lines at the end of the onCreate() method:

sketch = new Sketch();
PFragment fragment = new PFragment(sketch);
fragment.setView(frame, this);

There, we are creating an instance of our sketch and the containing PFragment (which is a subclass of Android's Fragment, specialized to contain Processing sketches and part of the Processing core library for Android), passing the sketch to the fragment, and then setting the FrameLayout view object we created earlier as the view where the PFragment will be added to as part of the activity layout. With these steps, our sketch will be properly initialized and the rendering thread will be launched when the onCreateView() of the PFragment:

Fragment lifecycle

You can’t perform that action at this time.
You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session.
Press h to open a hovercard with more details.