Qt on Android: Use JNI and third-party jar packages

Source: Internet
Author: User

Qt on Android: Use JNI and third-party jar packages

Many of my friends asked this in the Forum and QQ group. Today I have time to write a simple example.

The function is simple. You can enter a web page address and use the Java download class library to download it and use QTextEdit to display it.

 

Effect display

The initial effect 1 is shown in the following figure:

Figure 1 initial effect of useJar

Figure 2 shows the effect of clicking the GET button and downloading it to the corresponding page:

Figure 2 successfully downloaded the page

In the download section, I used asynchttpclient to show how to use the jar package. For more information, see my blog: Android open-source framework AsyncHttpClient (android-async-http.

Project Creation

For more information, see Qt on Android: the full process of Hello World.

Add "QT + = androidextras" to the pro file ".

Create an AndroidManifest named an. qt. useJar.

All Rights Reserved: foruok. For more information, see http://blog.csdn.net/foruok.

Add Java source code

You can edit the java source code in any text editor, add it to the project through the Qt Creator project view, right-click other files, and select Add existing files. See the following figure.

Figure 3 shortcut menu for adding Java source code

Figure 4 selecting a Java source file

Figure 5 add a Java source file OK

Modify AndroidManifest and change the android: name attribute value of the activity tag to an. qt. useJar. ExtendsQtWithJava. This is required because the name of the Activity implemented by ExtendsQtWithJava. java is used.

Now, the Java code is added.

Add third-party jar packages

There is nothing to say about it. Just put it in the android/libs directory. Figure:

Figure 6 put the jar package

As long as you set the location, Qt Creator will package the jar package into the APK when compiling the project.

Use the jar package for Java source code

This is the content of java programming. You can use the import package name.

Source code analysis

Let's take a look at the Java-side code first.

Java code

ExtendsQtWithJava. java:

 

package an.qt.useJar;import java.lang.String;import android.content.Context;import android.content.Intent;import android.app.PendingIntent;import android.os.Handler;import android.os.Message;import android.util.Log;import android.net.ConnectivityManager;import android.net.NetworkInfo;import android.net.Uri;import android.location.Criteria;import android.provider.Settings;import android.os.Bundle;import android.os.Environment;import java.io.File;import com.loopj.android.http.AsyncHttpClient;import com.loopj.android.http.AsyncHttpResponseHandler;public class ExtendsQtWithJava extends org.qtproject.qt5.android.bindings.QtActivity{    private static ExtendsQtWithJava m_instance;    private final static String TAG = extendsQt;    private static String m_pageUri = null;    private static Handler m_handler = new Handler() {        @Override        public void handleMessage(Message msg) {            switch (msg.what) {            case 1:                if(m_pageUri == null){                    m_pageUri = (String)msg.obj;                    m_instance.downloadText(m_pageUri);                }else{                    m_instance.notifyQt(0, (String)msg.obj, Downloader is Busy now!);                }                break;            };        }    };        public ExtendsQtWithJava(){        m_instance = this;    }    public static int networkState(){        ConnectivityManager conMan = (ConnectivityManager) m_instance.getSystemService(Context.CONNECTIVITY_SERVICE);        return conMan.getActiveNetworkInfo() == null ? 0 : 1;    }    public static AsyncHttpClient m_httpc = new AsyncHttpClient();    public static ExtendsQtNative m_nativeNotify = null;    public void downloadText(String uri){        Log.d(TAG, start downloadText);        m_httpc.get(uri, null, new AsyncHttpResponseHandler(){            @Override            public void onSuccess(String data){                notifyQt(1, m_pageUri, data);                m_pageUri = null;            }            @Override            public void onFailure(Throwable e, String data){                notifyQt(-1, m_pageUri, data);                m_pageUri = null;            }        });    }        public static void downloadWebPage(String uri){        Log.d(TAG, downloadWebPage);        m_handler.sendMessage(m_handler.obtainMessage(1, uri));    }        private void notifyQt(int result, String uri, String data){        if(m_nativeNotify == null){            m_nativeNotify = new ExtendsQtNative();        }        m_nativeNotify.OnDownloaded(result, uri, data);    }}

ExtendsQtNative. java:

 

 

package an.qt.useJar;import java.lang.String;public class ExtendsQtNative{    public native void OnDownloaded(int result, String url, String content);}

The basic idea is soy sauce:

 

Qt calls java downloadWebPage. the Java code uses asynchttpclient to download a webpage, and then calls ExtendsQtNative to notify Qt C ++ code.

C ++ code

The JNI method is implemented in two parts. The other part is to call Java class methods.

Implement and register the JNI Method

Let's first look at the JNI implementation corresponding to ExtendsQtNative, which is listed in main. cpp:

 

#include widget.h#include 
 
  #include 
  
   #include 
   
    #include 
    
     #include ../simpleCustomEvent.h#include 
     
      QObject *g_listener = 0;// result: -1 failed; 1 success; 0 busy;static void onDownloaded(JNIEnv *env, jobject thiz,int result, jstring uri, jstring data){    QString qstrData;    const char *nativeString = env->GetStringUTFChars(data, 0);    qstrData = nativeString;    env->ReleaseStringUTFChars(data, nativeString);    QCoreApplication::postEvent(g_listener, new SimpleCustomEvent(result, qstrData));}bool registerNativeMethods(){    JNINativeMethod methods[] {        {OnDownloaded, (ILjava/lang/String;Ljava/lang/String;)V, (void*)onDownloaded}    };    const char *classname = an/qt/useJar/ExtendsQtNative;    jclass clazz;    QAndroidJniEnvironment env;    QAndroidJniObject javaClass(classname);    clazz = env->GetObjectClass(javaClass.object
      
       ()); qDebug() << find ExtendsQtNative - << clazz; bool result = false; if(clazz) { jint ret = env->RegisterNatives(clazz, methods, sizeof(methods) / sizeof(methods[0])); env->DeleteLocalRef(clazz); qDebug() << RegisterNatives return - << ret; result = ret >= 0; } if(env->ExceptionCheck()) env->ExceptionClear(); return result;}int main(int argc, char *argv[]){ QApplication a(argc, argv); SimpleCustomEvent::eventType(); registerNativeMethods(); Widget w; g_listener = qobject_cast
       
        (&w); w.show(); return a.exec();}
       
      
     
    
   
  
 

Register the JNI method and set a global object to receive notifications. For more information, see Qt help.

 

Call the Java method

Call Java methods in Widget. cpp. Check the Code directly.

Widget. h:

 

#ifndef WIDGET_H#define WIDGET_H#include 
 
  #include 
  
   #include 
   
    #include 
    
     class Widget : public QWidget{    Q_OBJECTpublic:    Widget(QWidget *parent = 0);    ~Widget();    bool event(QEvent *e);public slots:    void onGet();private:    QLineEdit * m_urlEdit;    QTextEdit * m_resultView;    QLabel * m_stateLabel;};#endif // WIDGET_H
    
   
  
 

All of them are interface-related and there is nothing to say. View widget. cpp:

 

 

#include widget.h#include 
 
  #include 
  
   #include ../simpleCustomEvent.h#include 
   
    #include 
    
     Widget::Widget(QWidget *parent)    : QWidget(parent){    QVBoxLayout *layout = new QVBoxLayout(this);    QHBoxLayout *getLayout = new QHBoxLayout();    layout->addLayout(getLayout);    m_urlEdit = new QLineEdit(http://blog.csdn.net/foruok);    getLayout->addWidget(m_urlEdit, 1);    QPushButton *getButton = new QPushButton(GET);    getLayout->addWidget(getButton);    connect(getButton, SIGNAL(clicked()), this, SLOT(onGet()));    m_resultView = new QTextEdit();    m_resultView->setReadOnly(true);    layout->addWidget(m_resultView, 1);    m_stateLabel = new QLabel();    layout->addWidget(m_stateLabel);}Widget::~Widget(){}bool Widget::event(QEvent *e){    if(e->type() == SimpleCustomEvent::eventType())    {        e->accept();        SimpleCustomEvent *sce = (SimpleCustomEvent*)e;        switch(sce->m_arg1)        {        case 1:            m_resultView->setText(sce->m_arg2);            m_stateLabel->setText(Success!);            break;        case 0:            m_resultView->setText(sce->m_arg2);            m_stateLabel->setText(Failed!);            break;        case -1:            m_stateLabel->setText(sce->m_arg2);            break;        }        return true;    }    return QWidget::event(e);}void Widget::onGet(){#ifdef WIN32    m_resultView->setText(Sorry, Just for Android!);#elif defined(ANDROID)    QString url = m_urlEdit->text();    QAndroidJniObject javaAction = QAndroidJniObject::fromString(url);    QAndroidJniObject::callStaticMethod
     
      (an/qt/useJar/ExtendsQtWithJava,                                       downloadWebPage,                                       (Ljava/lang/String;)V,                                       javaAction.object
      
       ()); m_stateLabel->setText(Downloading...);#endif}
      
     
    
   
  
 

The code for calling Java is in the onGet () slot, which is very simple and does not need to be explained. If you have any questions, refer to the instructions in the Qt help manual on the QAndroidJniObject class.

 

 

OK. The end is now.

All Rights Reserved: foruok. For more information, see http://blog.csdn.net/foruok.

My Qt on Android series articles:

 

  • Qt on Android: full process of Hello World
  • Introduction to Qt 5.2 for Android development in Windows
  • Analysis of the deployment process of Qt for Android
  • Qt on Android: Output Qt debugging information to logcat.
  • Qt on Android: Qt 5.3.0 released. Improvements for Android
  • Qt on Android Episode 1)
  • Qt on Android Episode 2)
  • Qt on Android Episode 3)
  • Qt on Android Episode 4)
  • Compiling a pure C project using Qt for Android
  • Compiling Android C language executable programs using Qt for Android in Windows
  • Qt on Android: Android SDK Installation
  • Qt on Android: http download and Json Parsing
  • Set the app name for Qt on Android to Chinese
  • Qt on Android: Enables full screen display of Qt Widgets and Qt Quick apps
  • Qt on Android: how to adapt to different screen sizes

     

Related Article

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.