Skip to content
This repository
Browse code

jni: add a quick readme

  • Loading branch information...
commit 8a614eb5361a7b792e46aa3f2cb72408fd7bf8d3 1 parent 63c6f37
authored May 02, 2013

Showing 1 changed file with 150 additions and 0 deletions. Show diff stats Hide diff stats

  1. 150  xbmc/android/jni/README
150  xbmc/android/jni/README
... ...
@@ -0,0 +1,150 @@
  1
+(soon-to-be) libjni-android
  2
+
  3
+Quick and dirty readme.
  4
+
  5
+1. What is this?
  6
+
  7
+It is a native wrapper for JNI specifically designed to provide easy access
  8
+to the Android API. The goal is to create a 1:1 mapping of java functionality
  9
+to native apps.
  10
+
  11
+2. Is that possible?
  12
+
  13
+No. But we can try :)
  14
+Java and c++ have some fundamental differences that make an exact mapping
  15
+impossible. But we can come close.
  16
+
  17
+3. How does it work?
  18
+
  19
+The native classes use JNI to call into java while hiding the gory details from
  20
+the user. Under the hood it's quite un-elegant. Typical JNI objects created and
  21
+passed around using a thin wrapper. This wrapper is a heavily modified version
  22
+of one found in libcrystax. Thanks crystax!
  23
+
  24
+4. What does it look like?
  25
+
  26
+  Here's a quick example:
  27
+
  28
+  void MyFunction()
  29
+  {
  30
+    // Find the launch intent for a package and start its activity
  31
+    CJNIPackageManager manager = getPackageManager();
  32
+    CJNIIntent intent = manager.getLaunchIntentForPackage("org.xbmc.xbmc");
  33
+    startActivity(sendIntent);
  34
+  }
  35
+
  36
+This tiny bit of functionality would require dozens of lines if using JNI
  37
+directly, but here it looks just like java code.
  38
+
  39
+5. How do I use it in my app?
  40
+It is assumed that you are using a NativeActivity. Apps should create a main
  41
+class that inherits from CJNIContext, and passes android_app->state->clazz to
  42
+the constructor. This class now acts like a standard NativeActivity which
  43
+inherits from Context. This class can now call the same functions that a Java
  44
+activity can. Additionally, a virtual OnReceive function will catch broadcast
  45
+events.
  46
+
  47
+TODO: Rename and make the distinction between NativeActivity and Context
  48
+classes.
  49
+
  50
+6. How do I interact with the classes?
  51
+
  52
+Just as you would with java. There is no documentation for usage, because the
  53
+Android API documentation should be sufficient.
  54
+
  55
+7. What are the caveats?
  56
+
  57
+With any luck, very few. This library is still very new and has not been
  58
+exposed to many use-cases yet. Here are a few:
  59
+
  60
+a. Java can return NULL objects (not null-pointers).
  61
+workaround: objects can be tested as a bool.
  62
+
  63
+Here's an example of a function that would crash:
  64
+
  65
+  void MyFunction()
  66
+  {
  67
+    std::string externalDir = getExternalFilesDir("foo").getAbsolutePath();
  68
+    return externalDir;
  69
+  }
  70
+
  71
+The Android API specifies that getExternalFilesDir("") can return NULL if the
  72
+path is not found. Thus getAbsolutePath() has no instance and would crash when
  73
+called.
  74
+
  75
+The fix:
  76
+
  77
+  std::string MyFunction()
  78
+  {
  79
+    std::string externalDir;
  80
+    CJNIFile myFile = getExternalFilesDir("foo");
  81
+    if (myFile)
  82
+      externalDir myFile.getAbsolutePath();
  83
+    retrun externalDir;
  84
+  }
  85
+
  86
+b. Probably lots more.
  87
+
  88
+8. Is the entire API implemented?
  89
+Not even close! Classes and individual functions have been added as-needed.
  90
+
  91
+9. OK, how do I add xyz class?
  92
+Each (non-static) class inherits from CJNIBase. This class stores an object
  93
+for the subclass, handles copying, etc. The class is expected to provide
  94
+functions and members of the same name as the Android api. Helper functions
  95
+are used to make JNI usage less painful.
  96
+
  97
+Simplified Example:
  98
+
  99
+  #include "JNIBase.h"
  100
+  class CJNISomeClass : public CJNIBase
  101
+  {
  102
+  public:
  103
+    CJNISomeClass();
  104
+    CJNISomeClass(const jni::jhobject &object) : CJNIBase(object){};
  105
+    std::string getSomeString();
  106
+  };
  107
+
  108
+  CJNISomeClass::CJNISomeClass() : CJNIBase("android/some/ClassName")
  109
+  {
  110
+    m_object = new_object(GetClassName());
  111
+  }
  112
+
  113
+  std::string CJNISomeClass::getSomeString()
  114
+  {
  115
+    return jcast<std::string>(call_method<jhstring>(m_object, "getSomeString", "()Ljava/lang/String;"));
  116
+  }
  117
+
  118
+When a CJNISomeClass is created, it will use the hard-coded classname to
  119
+construct a new instance (<init> is called on the class).
  120
+If a CJNISomeClass is created from another CJNISomeClass, its underlying object
  121
+will be used to create a new copy.
  122
+
  123
+Note that jhobjects can be cast to and from their parent classes. This is to
  124
+facilitate easy chaining of functions.
  125
+
  126
+new_object and call_method are helper functions that do auto-lookups and
  127
+casting of params and the result. See jutils/jutils-details.hpp for more
  128
+helpers.
  129
+
  130
+10. What is the lifetime of the created objects?
  131
+All native objects are returned as Global refs. This is overkill, but it was
  132
+done in order to reduce complexity. All refs are automatically destroyed when
  133
+objects go out of scope. Because of this, all objects should be passed as
  134
+const ref whenever possible to avoid unnecessary reference creation.
  135
+
  136
+CJNISomeClass objects should almost never be long-lived, as some environments
  137
+may have hard-limits for the amount that can be allocated.
  138
+
  139
+11. Why bother? Aren't there programs to generate these wrappers automatically?
  140
+Sure, but none of them seemed to do it in a way that reduced complexity to a
  141
+nominal level.
  142
+
  143
+12. Is it stable?
  144
+It works as-tested, but hasn't seen much real-world exposure. Time will tell.
  145
+Don't use it in production.
  146
+
  147
+13. What's with the CJNI naming?
  148
+This library was created for XBMC and classes were created using XBMC
  149
+naming conventions. If it is adopted elsewhere, the names should be changed to
  150
+something more standard.

0 notes on commit 8a614eb

Please sign in to comment.
Something went wrong with that request. Please try again.