GithubHelp home page GithubHelp logo

isabella232 / libandroidjni Goto Github PK

View Code? Open in Web Editor NEW

This project forked from xbmc/libandroidjni

0.0 0.0 0.0 423.97 MB

Android JNI bindings library

License: GNU General Public License v2.0

C++ 99.13% C 0.39% Pawn 0.37% CMake 0.10%

libandroidjni's Introduction

libandroidjni
=============

Quick and dirty readme.

1. What is this?

It is a native wrapper for JNI specifically designed to provide easy access
to the Android API. The goal is to create a 1:1 mapping of java functionality
to native apps.

2. Is that possible?

No. But we can try :)
Java and c++ have some fundamental differences that make an exact mapping
impossible. But we can come close.

3. How does it work?

The native classes use JNI to call into java while hiding the gory details from
the user. Under the hood it's quite un-elegant. Typical JNI objects created and
passed around using a thin wrapper. This wrapper is a heavily modified version
of one found in libcrystax. Thanks crystax!

4. What does it look like?

  Here's a quick example:

  void MyFunction()
  {
    // Find the launch intent for a package and start its activity
    CJNIPackageManager manager = getPackageManager();
    CJNIIntent intent = manager.getLaunchIntentForPackage("org.xbmc.kodi");
    startActivity(sendIntent);
  }

This tiny bit of functionality would require dozens of lines if using JNI
directly, but here it looks just like java code.

5. How do I use it in my app?
It is assumed that you are using a NativeActivity. Apps should create a main
class that inherits from CJNIContext, and passes android_app->state->clazz to
the constructor. This class now acts like a standard NativeActivity which
inherits from Context. This class can now call the same functions that a Java
activity can. Additionally, a virtual OnReceive function will catch broadcast
events.

TODO: Rename and make the distinction between NativeActivity and Context
classes.

6. How do I interact with the classes?

Just as you would with java. There is no documentation for usage, because the
Android API documentation should be sufficient.

7. What are the caveats?

With any luck, very few. This library is still very new and has not been
exposed to many use-cases yet. Here are a few:

a. Java can return NULL objects (not null-pointers).
workaround: objects can be tested as a bool.

Here's an example of a function that would crash:

  void MyFunction()
  {
    std::string externalDir = getExternalFilesDir("foo").getAbsolutePath();
    return externalDir;
  }

The Android API specifies that getExternalFilesDir("") can return NULL if the
path is not found. Thus getAbsolutePath() has no instance and would crash when
called.

The fix:

  std::string MyFunction()
  {
    std::string externalDir;
    CJNIFile myFile = getExternalFilesDir("foo");
    if (myFile)
      externalDir myFile.getAbsolutePath();
    retrun externalDir;
  }

b. Java has an understanding of arrays like Type[] which contain size info.
   C-style arrays don't carry size information, so passing a c-array as a
   parameter does not provide enough info to work with it realistically.

   workaround: Data should be passed in/out of Java arrays as std::vectors of
   primitive types or jni classes.
   Care should be taken to avoid making needless copies of objects in the
   process. To automate this, jcast() can be used to convert a j(h)objectArray
   directly to a vector of native objects. For example:

  std::vector<CJNIFoo> example()
  {
    return jcast<std::vector<CJNIFoo> >(call_method<jhobjectArray>(object, "function", "()[Lsome/Class;"))
  }

c. Probably lots more.

8. Is the entire API implemented?
Not even close! Classes and individual functions have been added as-needed.

9. OK, how do I add xyz class?
Each (non-static) class inherits from CJNIBase. This class stores an object
for the subclass, handles copying, etc. The class is expected to provide
functions and members of the same name as the Android api. Helper functions
are used to make JNI usage less painful.

Simplified Example:

  #include "JNIBase.h"
  class CJNISomeClass : public CJNIBase
  {
  public:
    CJNISomeClass();
    CJNISomeClass(const jni::jhobject &object) : CJNIBase(object){};
    std::string getSomeString();
  };

  CJNISomeClass::CJNISomeClass() : CJNIBase("android/some/ClassName")
  {
    m_object = new_object(GetClassName());
  }

  std::string CJNISomeClass::getSomeString()
  {
    return jcast<std::string>(call_method<jhstring>(m_object, "getSomeString", "()Ljava/lang/String;"));
  }

When a CJNISomeClass is created, it will use the hard-coded classname to
construct a new instance (<init> is called on the class).
If a CJNISomeClass is created from another CJNISomeClass, its underlying object
will be used to create a new copy.

Note that jhobjects can be cast to and from their parent classes. This is to
facilitate easy chaining of functions.

new_object and call_method are helper functions that do auto-lookups and
casting of params and the result. See jutils/jutils-details.hpp for more
helpers.

10. What is the lifetime of the created objects?
All native objects are returned as Global refs. This is overkill, but it was
done in order to reduce complexity. All refs are automatically destroyed when
objects go out of scope. Because of this, all objects should be passed as
const ref whenever possible to avoid unnecessary reference creation.

CJNISomeClass objects should almost never be long-lived, as some environments
may have hard-limits for the amount that can be allocated.

11. Why bother? Aren't there programs to generate these wrappers automatically?
Sure, but none of them seemed to do it in a way that reduced complexity to a
nominal level.

12. Is it stable?
It works as-tested, but hasn't seen much real-world exposure. Time will tell.
Don't use it in production.

13. What's with the CJNI naming?
This library was created for XBMC and classes were created using XBMC
naming conventions. If it is adopted elsewhere, the names should be changed to
something more standard.

libandroidjni's People

Contributors

aballier avatar ace20022 avatar alanwww1 avatar alcoheca avatar amejia1 avatar amet avatar anssih avatar davilla avatar elupus avatar fernetmenta avatar fritsch avatar huceke avatar jezzx avatar jmarshallnz avatar karlson2k avatar koying avatar martijnkaijser avatar memphiz avatar mkortstiege avatar montellese avatar night199uk avatar opdenkamp avatar pieh avatar popcornmix avatar ronie avatar t-nelson avatar topfs2 avatar ulion avatar wsnipex avatar xhaggi avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.