1 unstable release
0.1.0 | Dec 26, 2018 |
---|
#290 in Rendering
19KB
186 lines
android_base
- A base to create android applications with ease
android_base
provides an api to develop applications in rust for android without worrying about android specific details like opengl implementations or the event loop, all while having its exposed functions be very abstract in terms of what you can do
example
This is basically the same example as shown in the piston getting started page, except with inverted colours.
Note that this example requires some basic knowledge of rust and working with android
Getting started:
Make sure you've followed the getting set up
section of this readme beforehand to setup the environment/dependencies
Setting up the project
To set up the cargo project follow the standard procedure you'd go through with for any other binary rust application:
- Run
cargo new android_example --bin
in the directory you want to create the project in - Inside the newly created
android_example
folder, edit theCargo.toml
file and addandroid_base = "0.1.0"
as a dependency
Take note that this is the only dependency you are required to add; android_base automatically imports the right versions of all the crates you'll need in the form of a prelude
Writing the code
- Now we'll start writing the app. For simplicity's sake you can just copy the following example, but feel free to experiment and play around with it.
#![feature(uniform_paths)]
//automatically imports right versions of crates
use android_base::*;
use graphics::*;
use android_glue::*;
pub struct App {
rotation: f64
}
impl App {
pub fn new() -> Self {
Self {rotation: 0.}
}
}
impl AppImpl for App {
fn draw(&mut self, c: Context, gl: &mut GlGraphics, args: &RenderArgs){
clear([1., 0., 0., 1.], gl);
let transform = c.transform
.trans(args.width as f64 / 2., args.height as f64 / 2.)
.rot_rad(self.rotation)
.trans(-75., -75.);
rectangle([0., 1., 0., 1.], [0., 0., 150., 150.], transform, gl);
}
fn update(&mut self, args: &UpdateArgs) {
self.rotation += args.dt;
}
fn cancel_poll(&self) -> bool {
false
}
}
fn main() {
enable_backtrace();
let mut container = AppContainer::init(App::new(), AppConfig::new());
container.run();
}
- Now let's tear this down piece by piece:
- Because prelude importing extern crates' members is unstable, we add a flag to enable this, hence the
#![feature(uniform_paths)]
at the start - Then we import
android_base
and two important dependencies in making an android app with piston;graphics
andandroid_glue
. For now I'll just assume you know whatgraphics
does, butandroid_glue
serves as the, well, glue between your app and android's events - To basically copy what the piston example does, we create a similar struct containing our app, holding a rotation; but notice that we don't have to hold any kind of opengl stuff or even have to import it, there'll be more on this later when I'm talking about the
draw
method. - We have added a
new
function for simplicity, but we could just use the constructor instead, either way works - We then implement a pretty self-explanatory trait for the app,
AppImpl
, which holds all the important functions that can be implemented for your app:draw
: This holds all the drawing functionality for your app, and takes the parameters supplied fromGlGraphics
' draw method, so thatandroid_base
takes care of getting ready to draw, and you just drawupdate
: This holds information when your app is needed to draw; this is basically just a passthrough frompiston::event_loop::Events::next()
when it emits an update flag.cancel_poll
: This polls your app if it should stop running, when it returns true, it will stop executing, even if it is only meant to render a numbered amount of frames (Look at the part on configuration below)- There are many more functions you can take a look at that you can override in
src/app_implementor.rs
- In our main function we do the following:
- Set the environment variable
RUST_BACKTRACE
to 1 to allow debugging backtraces; this just makes debugging easier - We initialize an
AppContainer
with our app, and a default configuration. Configuring theAppContainer
with anAppConfig
can make it run only a certain number of frames, or call a reset function onrun()
- Which leads us to the
run
function which will run our app untilcancel_poll
returns true (Which it won't because it's set to false)
- Set the environment variable
- Because prelude importing extern crates' members is unstable, we add a flag to enable this, hence the
Building and running with cargo-apk
- We then need to prepare to build, so add the following to your
Cargo.toml
:
[package.metadata.android]
build_targets = [ "arm-linux-androideabi" ]
Note that this example will follow the steps for compiling to a real device running arm linux android and will not detail how to start an emulator or even how to install one
- And then we'll install the necessary target for rustc:
$ rustup target add arm-linux-androideabi
- And to get adb ready:
- Connect your device physically to the computer and run
adb tcpip 5555
- Disconnect your device and find out the ip address (Usually found out by going to your internet settings and tapping on your currently connected network)
- Run
adb connect <your ip address>
to connect over wifi to make things easier for repeated runs
- Connect your device physically to the computer and run
- And now run
cargo-apk run
, and if it doesn't work:- Open a separate terminal and run
adb logcat
and re-open your app - The call to
enable_backtrace
inmain
will print out a backtrace whenpanic!()
occurs - Post an issue describing your problem, and me or someone else will help you debug it
- Open a separate terminal and run
Getting set up
- Follow the instructions for installing rust at rustup.rs
- Install cargo directly from github by calling
cargo install --git https://github.com/tomaka/android-rs-glue.git --rev 1d095846a687f873b6aed7d62ee32bc5a062e534 --force cargo-apk
- Follow the instructions for getting manual usage ready under
Setting up your environment
but without re-installing cargo-apk because the published version is out of date - If when following the above instructions for compiling and running an example you get a missing dependency error of some sort, look it up online to figure out how to install it for your system, and if not, open an issue to get some help figuring it out
Note: This readme/setup/example is meant for users either on ubuntu or on on WSL (Which I personally use), I've found that windows directly doesn't work
Another note: due to a minor implementation detail in the latest version of
cargo-apk
is broken and you can't callcargo apk
and instead have to callcargo-apk
.
Another note: This crate includes a git clone of
opengles_graphics
which is a fork ofopengl_graphics
meant to work with opengles, but it hasn't been updated for over 2 years. I therefore updated its dependencies to accomodate for newer versions of other crates. I do not claim to have developed the entirety of it, and have only made minor changes, and instead give credit to Drakulix and the Piston team
Dependencies
~6–15MB
~200K SLoC