Processing with Android

What is Processing?

Well, you better visit this website.

How to Use Processing in Android Studio?

Processing 3 has a nice IDE that can directly run your sketches on your phone. It can even export a sketch as an Android project. The problem is when you try to import and use it in Android Studio, you encounter various problems. After I examined the export files and learned how it works, I decided to try to create a new project in Android Studio and run a simple sketch without ever using Processing's own IDE. There are some tutorials on the Internet about this subject, but I realized many of them are not up-to-date and/or they miss some important points. So, I decided to write a simple tutorial. I'm not an expert and I don't consider myself good at teaching, but I think it will definitely help you.

  1. Open Android Studio and create a new project as usual. Nothing special. Leave MainActivity as it is for now, we will get there.
  2. Find app/libs folder at your project location and paste the processing-core.jar. You can also paste it directly from Android Studio but you need to switch your view from "Android" to "Project Files". I got that .jar file directly from the Android export I had examined before, but it's available online. I think you can also use the core.jar from core/library at your Processing 3 location.
  3. After you paste it, make sure you update the dependencies under your module-level Gradle build. Mine looks like this:
  4. dependencies {
        compile fileTree(dir: 'libs', include: ['*.jar']) // I'm not sure why this doesn't work and I had to manually add the 5th line.
        testCompile 'junit:junit:4.12'
        compile 'com.android.support:appcompat-v7:24.2.1'
        compile files('libs/processing-core.jar') // This is the line I added. Note that it should point to your specific .jar file. If yours has a different name, make the necessary changes.
    }
  5. Create a new Java class, I named mine "MySketch". This class will contain your sketch, so it must extend PApplet:
  6. public class MySketch extends PApplet {
    
    }
  7. Now you can code your sketch inside this class as if you are using the Processing IDE! The only difference in the syntax is you have to use access modifiers for your methods, so our setup() and draw() methods are declared as public. You can use them with variables as well. I wrote something very simple. The background changes color whenever you touch the screen:
  8. import processing.core.*;
    
    public class MySketch extends PApplet {
    
        public void setup() {
            fullScreen();
            background(0);
        }
    
        public void draw() {
            background(0);
            if (mousePressed) {
                background(255);
            }
        }
    }
  9. We're not done, though. You need to add a settings() method and move fullScreen() into that method to run the sketch in fullscreen. I'm not sure why, some stuff that works in PDE doesn't work outside, as processing.org informs us (also, check this). So, fullScreen(), size() and smooth() methods should be moved into settings(), which runs before everything else. I also found the good old main() method in the exported file I examined! If you don't include this, I think the sketch inherits the main method of the PApplet class, which does nothing. So, it's not always necessary. If your application is something more than just a Processing sketch, you may want to pass some arguments.
  10. import processing.core.*;
    
    public class MySketch extends PApplet {
    
        public void setup() {
            background(0);
        }
    
        public void draw() {
            background(0);
            if (mousePressed) {
                background(255);
            }
        }
    
        public void settings() {  fullScreen(); } // It was previously inside setup().
        
        public static void main(String[] passedArgs) {
            String[] appletArgs = new String[] { "MySketch" };
            if (passedArgs != null) {
                PApplet.main(concat(appletArgs, passedArgs));
            } else {
                PApplet.main(appletArgs);
            }
        }
    }
    Honestly, I don't know much why the main() method is written that way, I just used the way I saw in the export (except mine is "public static" rather than "static public", which theoretically makes no difference). I've also seen the same thing when I looked at Processing tutorials which are written for Eclipse instead. It seems like whatever you write there instead of "MySketch", it works. At least for our case.
  11. Your sketch is ready, but you cannot directly display it as it extends PApplet instead of AppCompatActivity. So, we need to use a fragment in MainActivity. You can just copy this and change the class name at line 26, according to your sketch's class:
  12. import android.app.FragmentTransaction;
    import android.support.v7.app.AppCompatActivity;
    import android.os.Bundle;
    import android.view.ViewGroup;
    import android.view.Window;
    import android.view.WindowManager;
    import android.widget.FrameLayout;
    
    import processing.core.PApplet;
    
    public class MainActivity extends AppCompatActivity {
        PApplet fragment;
        private static final String MAIN_FRAGMENT_TAG = "main_fragment";
        int viewId = 0x1000;
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            Window window = getWindow();
            requestWindowFeature(Window.FEATURE_NO_TITLE);
            window.setFlags(WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN,WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN);
            window.setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,WindowManager.LayoutParams.FLAG_FULLSCREEN);
            FrameLayout frame = new FrameLayout(this);
            frame.setId(viewId);
            setContentView(frame, new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
            if (savedInstanceState == null) {
                fragment = new MySketch();
                FragmentTransaction ft = getFragmentManager().beginTransaction();
                ft.add(frame.getId(), fragment, MAIN_FRAGMENT_TAG).commit();
            } else {
                fragment = (PApplet) getFragmentManager().findFragmentByTag(MAIN_FRAGMENT_TAG);
            }
        }
        @Override
        public void onBackPressed() {
            fragment.onBackPressed();
            super.onBackPressed();
        }
    }

Keep in mind some of the imports may not work for you and cause an error.

That's it, you know the basics now.