Qtandroid detailed (1): Qandroidjniobject

Source: Internet
Author: User

After Qt 5.3, the Qtandroid namespaces are added with the following four methods:

    • Qandroidjniobject androidactivity ()
    • int Androidsdkversion ()
    • voidstartactivity (const Qandroidjniobject & Intent, int receiverrequestcode, Qandroidactivityresultreceiver * resultreceiver = 0)
    • voidStartintentsender (const qandroidjniobject & intentsender, int receiverrequestcode, Qandroidactivityresultreceiver * resultreceiver = 0)

My book "Qt on Android Core programming" with the QT SDK version for 5.2.0 (the first officially supported Android version of the QT SDK), the writing process 5.3 released, the book is simply a brief introduction of the existence of the next qtandroid, the above several methods did not do the actual Research, starting from this article, I will start with Qt 5.3.1, to introduce the Qtandroid namespace and its closely related qandroidjniobject.

Qandroidjniobject

Before introducing the methods in Qtandroid, you must introduce the Qandroidjniobject class. Leaving Qandroidjniobject is a difficult move because it is programmed to use the JNI functionality provided by Qt.

Qandroidjniobject belongs to the Androidextras module, to use it, you need to include the following code in the pro file:

QT + = Androidextras

The Androidextras was introduced from Qt 5.2. The Qandroidjnienvironment class is also included in this module, and qandroidjnienvironment represents the JNI environment, which is usually the jnienv when we use JNI programming. When we use QT for JNI programming, we construct a Qandroidjnienvironment object to get the jnienv pointer, and we can further use the JNIEnv method to implement certain functions, such as checking if an exception occurred during the JNI call, cleaning the exception, and so on. For more details, refer to Qt Help and jni.h (this header file is available in the JDK to open browsing).

Our highlight is qandroidjniobject.

Qandroidjniobject is an encapsulation of the original JNI type, representing a Java object (an instance of the class) that provides many ways for developers to use it, and I divide it into three categories:

    • Constructs a Java object
    • Calling the Java static (Class) method
    • Invoking a Java instance method

Let's look at it one by one.

Constructing Java objects

To invoke the Java class Library, you need to construct a Java object, which is the first and possibly the hardest step. However, with the introduction of this article, you will soon know how to construct a JNI object that corresponds to a Java object.

Qandroidjniobject provides the following constructors to create JNI objects:

    1. Qandroidjniobject ()
    2. Qandroidjniobject (const char * className)
    3. Qandroidjniobject (const char * className, const char * signature, ...)
    4. Qandroidjniobject (Jclass clazz)
    5. Qandroidjniobject (Jclass clazz, const char * signature, ...)
    6. Qandroidjniobject (Jobject object)

There is also a static and convenient way for us to construct a String object in Java from a QString object:

    • Qandroidjniobjectfromstring (const QString & String)

FromString need not speak, simple and clear. Let's look at the constructor.

The constructors are divided into two categories, one is to create JNI objects according to the Java class name and the Java class constructor signature, and the other is to create the Qandroidjniobject object based on the existing JNI object (which can also be signed with the Java constructor). Let's simplify it by just looking at 1, 2, 3, and creating Qandroidjniobject from the Java class name, and then the first constructor has no arguments and no introduction, leaving the two behind.

Two-point basis for using JNI

The full path class name for Java, which is the package name. Java package, can be analogous to C + + namespace, a package can contain multiple classes, on the one hand to facilitate the organization of associated classes together, on the other hand can also avoid name collisions.

We use the String class to illustrate.

The String class is in package Java.lang, and the full path class is named Java.lang.String. When we describe a Java class as a string in C + +, we need to replace "." with "/", such as Java.lang.String, where the string is described as "java/lang/string". Also like Android.content.Intent, the string is described as "android/content/intent".

Well, this is our first foundation for JNI programming with Qandroidjniobject in Qt.

Since there is the first one, there is a second one. Wood Fault, the second Foundation is the method signature.

About the method signature, I am in the "QT on Android core Programming" 15.2.1 section has the detailed introduction, QT Help searches the Qandroidjniobject also has the introduction, here we only briefly explain.

Method signature representation: (Arguments) returntype. In parentheses is the argument list, followed by the return value type. For example, "(I) C" means that the parameter is int and the return value is char. When a Java method parameter or return value type is an object, the full path class name is used, prefixed with "L" and suffix ";". such as "(ljava/lang/string;) ljava/lang/string;", which means that the parameter type of a method is string and the return value is also a string.

The method signature is introduced here. Refer to my book or Qt Help for details.

Qandroidjniobject (const char * className)

The constructor with the const char * className parameter, which constructs the JNI object based only on the class name, invokes the default constructor for the Java class specified by ClassName.

We understand how to use a string to describe a Java class, and the constructor for Qandroidjniobject (const char*) is easy to understand.

Let's take a few examples.

The Intent class is a mechanism provided by Android for communication between components. With Intent, you can invoke other system functions or functions provided by a third party, such as the ability to call calls, to display contacts, or to call the camera. When we use Intent, we can specify an action that represents the action you want to do, which is what you want to do, and you can carry data to the called Party in Intent. Very convenient to use. The full path class of Intent is named Android.content.Intent.

We can construct a Intent object like this:

Qandroidjniobject Intent ("android/content/intent");

The code above calls Intent's default constructor to construct a Intent object.

The full path class of the String class is named Java.lang.String, so you can construct an empty string object:

Qandroidjniobject Str ("java/lang/string");

It is important to note that using the constructor of the Qandroidjniobject (const char * className) to create a Java object, make sure that the Java class you specify has a parameterless constructor (that is, the default constructor).

Qandroidjniobject (const char * className, const char * signature, ...)

This parameter creates a JNI object based on the class name ClassName and the constructor that specifies the signature.

As an example of Intent, Intent has a constructor, the prototype is: Intent (String action). We create Intent objects based on this constructor, and the C + + code is as follows:

    Qandroidjniobject action = qandroidjniobject::fromstring ("com.android.settings.Settings");    Qandroidjniobject Intent ("Android/content/intent", "(ljava/lang/string;) V", action.object<jstring> ());

In the above code, we first use qandroidjniobject::fromstring to construct a Java String object as our action, which opens the Android system settings.

We then call Intent's Intent (String action) constructor to create a Intent class. The constructor has no return value and the argument is String, so the function signature is "(ljava/lang/string;) V". Qandroidjniobject's Object method returns the Java object it holds, and action.object<jstring> () returns jstring.

We'll see later how to use the Intent class to invoke other components in the Android system.

Invoking a Java instance method

With the Java object, we can invoke an instance method of this object.

The so-called instance method, which is a non-static method of a class, requires an object before it can be called. The class method, which refers to the static method of the class, will later talk about how to invoke the class method, here first how to invoke the instance method.

Qandroidjniobject provides the following methods to make it easier for us to invoke Java instance methods:

    1. TCallmethod (const char * methodName) const
    2. TCallmethod (const char * methodName, const char * signature, ...) const
    3. QandroidjniobjectCallobjectmethod (const char * methodName) const
    4. QandroidjniobjectCallobjectmethod (const char * methodName, const char * signature, ...) const

These four methods, the first two are a group, the latter two are a group.

Two Callmethod methods that invoke instance methods of the Java object whose return value is the underlying type (such as int, double, and so on). The two Callobjectmethod methods invoke instance methods of the Java object whose return value is an object (class instance). I think the difference is here, do not know right ah.

Two Callmethod, one with parameters, one without parameters; Callmethod is a template method, and the template parameter is the type of the return value of the Java method. Two callobjectmethod similar.

Let's look at an example to calculate the length of a string. The C + + code is as follows:

Qandroidjniobject action = qandroidjniobject::fromstring ("com.android.settings.Settings");
int = action.callmethod<jint> ("Length");

The above code calls FromString to create a Java string object, and then uses Callmethod to call the string's "int length ()" method to get the length of the strings.

Another example of using Callobjectmethod is the C + + code as follows:

Qandroidjniobject action = qandroidjniobject::fromstring ("com.android.settings.Settings"); jint start = 4; Qandroidjniobject substring = action.callobjectmethod ("substring", "(I) ljava/lang/string", start);

The above code calls the Java string class "string substring (int start)" method to get the substring.

Calling the Java Class (static) method

Call a Java class method without constructing a Java object because the class method is a static method, belongs to a class, and can be called without the need for an object.

Qandroidjniobject provides the following static methods to invoke Java class methods:

  • TCallstaticmethod (const char * className, const char * methodName)
  • TCallstaticmethod (const char * className, const char * methodName, const char * signature, ...)
  • TCallstaticmethod (jclass clazz, const char * methodName)
  • TCallstaticmethod (jclass clazz, const char * methodName, const char * signature, ...)
  • QandroidjniobjectCallstaticobjectmethod (const char * className, const char * methodName)
  • QandroidjniobjectCallstaticobjectmethod (const char * className, const char * methodName, const char * signature, ...)
  • QandroidjniobjectCallstaticobjectmethod (jclass clazz, const char * methodName)
  • QandroidjniobjectCallstaticobjectmethod (jclass clazz, const char * methodName, const char * signature, ...)

Callstaticmethod has four static methods that call the Java class directly and requires a template parameter that corresponds to the return value of the Java class method.

Callstaticobjectmethod also has four static methods that can call the Java class to return objects.

Take a look at some simple code snippets:

Jint a = 2;jint b = 4;jint max = qandroidjniobject::callstaticmethod<jint> (                   "Java/lang/math", "Max", "(II) I", A, b);.. Qandroidjniobject thread =            Qandroidjniobject::callstaticobjectmethod (                "Java/lang/thread", "CurrentThread" ,                 "() ljava/lang/thread;"); ... Qandroidjniobject string =      Qandroidjniobject::callstaticobjectmethod (        "java/lang/string", "ValueOf", "(I) ljava/lang/string; ", 10);

The code snippet above is actually a three small example.

For the first small example, call Java.lang.Math to find the larger of the two numbers. int max (int, int) is used to complete the function of "the larger of the two numbers."

The second small example, called Java.lang.Thread's CurrentThread method, gets the current thread object, the CurrentThread method has no parameters, and the return value is the thread object.

A third small example, calling Java.lang.String's ValueOf method to convert a number to a string. The ValueOf prototype is "String valueOf (int)".


----------

OK, this time we introduce here, with the foundation of this article, we can go on to see how the functions of the Qtandroid namespace, the next time we come to detail them, and provide a simple example to see the effect.

Qtandroid detailed (1): Qandroidjniobject

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.