"Runtime" generally refers to the library routines that handle the creating and keeping track of objects, adding methods and/or ivars to those objects, and calling methods. How you call those library routines can vary.
In a traditional JVM implementation, a class-file will compile down to bytecode, and the bytecode interpreter turns the relevant ops into calls to the runtime routines.
JNI provides another way to call the runtime routines (using C++ calling conventions), and for the runtime to call back into your code.
So, for example, if you have a method that adds two numbers together defined on the Foo class, then you want to instantiate that class and call that method from your app, you would compile the "add two numbers" method down to machine code. You'd pass the location of the compiled method to the runtime, registering it with the Foo class, using JNI. Then you'd compile your app code (that will instantiate the class and call the method) to machine code with instructions to set up the stack and jump to the JNI routines to instantiate the class and finally call the method.
Make sense?