Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. Mobile and Embedded
  4. Problem when viewing web pages in QML using android.webkit.WebView

Problem when viewing web pages in QML using android.webkit.WebView

Scheduled Pinned Locked Moved Solved Mobile and Embedded
11 Posts 3 Posters 5.9k Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • G Offline
    G Offline
    g00dnight
    wrote on last edited by A Former User
    #1

    Hi. I'm trying to create WebView-analogue QML component for Android. The problem is, when I call LoadUrl method for android.webkit.WebView I get a crash somewhere in com.android.webview.chromium.WebViewChromium. URL in loadUrl method can be any, even "about:blank". More details below:

    Some code:

    @AndroidWebView::AndroidWebView(QQuickItem *parent)
    : QQuickItem(parent)
    {
    setFlag(QQuickItem::ItemHasContents);
    }@

    @void AndroidWebView::componentComplete()
    {
    qDebug() << "AndroidWebView::componentComplete";

    QQuickItem::componentComplete();
    
    // Get activity object of our application
    QAndroidJniObject qObjActivity = QtAndroid::androidActivity();
    
    // Create WebView and set default background color
    qObjWebView = QAndroidJniObject("android/webkit/WebView", "(Landroid/content/Context;)V", qObjActivity.object<jobject>());
    jint backgroundColor = 0xFF000000;
    qObjWebView.callObjectMethod("setBackgroundColor", "(I)V", backgroundColor);
    
    // Construct LayoutParams object
    jint width = 100;
    jint height = 100;
    jint x = 0;
    jint y = 0;
    QAndroidJniObject qObjLayoutParams("android/widget/AbsoluteLayout/LayoutParams", "(IIII)V", width, height, x, y);
    
    // Add WebView as content view for our activity
    qObjActivity.callObjectMethod("addContentView", "(Landroid/view/View;Landroid/view/ViewGroup/LayoutParams;)V", qObjWebView.object<jobject>(), qObjLayoutParams.object<jobject>());
    

    }@

    @void AndroidWebView::loadURL(QString url)
    {
    qDebug() << "AndroidWebView::loadURL" << url;
    QAndroidJniObject qObjUrlString = QAndroidJniObject::fromString(url);
    // The crash happens when I call this method
    qObjWebView.callObjectMethod("loadUrl", "(Ljava/lang/String;)V", qObjUrlString.object<jstring>());
    }@

    Here is what I have got in QML:
    @AndroidWebView {
    id: androidWebView
    anchors.fill: parent
    Component.onCompleted: androidWebView.loadURL("about:blank");
    }@

    EDIT:
    And here is a log:
    @D/Qt (21155): ../MyApp/android/AndroidWebView.cpp:10 (AndroidWebView::AndroidWebView(QQuickItem*)): AndroidWebView::componentComplete
    D/Qt (21155): ../MyApp/android/AndroidWebView.cpp:82 (void AndroidWebView::loadURL(QString)): AndroidWebView::loadURL "about:blank"
    V/WebViewChromiumFactoryProvider(21155): Binding Chromium to main looper Looper (main, tid 1) {42dec630}
    I/LibraryLoader(21155): Expected native library version number "",actual native library version number ""
    I/chromium(21155): [INFO:library_loader_hooks.cc(116)] Chromium logging enabled: level = 0, default verbosity = 0
    I/BrowserStartupController(21155): Initializing chromium process, renderers=0
    E/AudioManagerAndroid(21155): BLUETOOTH permission is missing!
    E/dalvikvm(21155): JNI ERROR (app bug): attempt to use stale local reference 0x1
    E/dalvikvm(21155): VM aborting
    F/libc (21155): Fatal signal 6 (SIGABRT) at 0x000052a3 (code=-6), thread 21171 (qtproject.MyApp)
    D/AndroidRuntime(21155): Shutting down VM
    W/dalvikvm(21155): threadid=1: thread exiting with uncaught exception (group=0x41600d88)
    E/AndroidRuntime(21155): FATAL EXCEPTION: main
    E/AndroidRuntime(21155): Process: org.qtproject.MyApp, PID: 21155
    E/AndroidRuntime(21155): java.lang.NullPointerException
    E/AndroidRuntime(21155): at com.android.webview.chromium.WebViewChromium$15.run(WebViewChromium.java:616)
    E/AndroidRuntime(21155): at com.android.webview.chromium.WebViewChromium$WebViewChromiumRunQueue.drainQueue(WebViewChromium.java:113)
    E/AndroidRuntime(21155): at com.android.webview.chromium.WebViewChromium$WebViewChromiumRunQueue$1.run(WebViewChromium.java:100)
    E/AndroidRuntime(21155): at android.os.Handler.handleCallback(Handler.java:733)
    E/AndroidRuntime(21155): at android.os.Handler.dispatchMessage(Handler.java:95)
    E/AndroidRuntime(21155): at android.os.Looper.loop(Looper.java:212)
    E/AndroidRuntime(21155): at android.app.ActivityThread.main(ActivityThread.java:5135)
    E/AndroidRuntime(21155): at java.lang.reflect.Method.invokeNative(Native Method)
    E/AndroidRuntime(21155): at java.lang.reflect.Method.invoke(Method.java:515)
    E/AndroidRuntime(21155): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:877)
    E/AndroidRuntime(21155): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:693)
    E/AndroidRuntime(21155): at dalvik.system.NativeStart.main(Native Method)@

    One more interesting fact, when I don't call loadURL that crash not happens, but I can't see a view. There must be black square 100x100 pixels, if my code is correct, but I can't see anything like this. Am I doing it wrong?

    Thanks!

    1 Reply Last reply
    0
    • N Offline
      N Offline
      nologinma
      wrote on last edited by
      #2

      I have checked in several forums and I have found this:

      The "stale local reference" error means that you're saving a local reference to some Java object between JNI calls;

      You need to convert that reference to a global reference using the NewGlobalRef method before doing anything that would cause the reference to persist outside the scope of the one JNI call.

      @jclass jc = env->FindClass(callbacks.name);
      // Since Android ICS, class references are not global so we need to peg a
      // global reference to the jclass returned by FindClass(), otherwise we get
      // following error in the log:
      // "JNI ERROR (app bug): attempt to use stale local reference 0xHHHHHHHH".
      callbacks._class = static_cast<jclass>(env->NewGlobalRef(jc));@

      In you case try to convert that reference to a global reference.....

      @jclass jc = env->FindClass(callbacks.name);
      callbacks._class = static_cast<jclass>(env->NewGlobalRef(jc));@

      in any case I think that the error is the following block:

      @void AndroidWebView::loadURL(QString url)
      {
      qDebug() << "AndroidWebView::loadURL" << url;
      QAndroidJniObject qObjUrlString = QAndroidJniObject::fromString(url);
      // The crash happens when I call this method
      qObjWebView.callObjectMethod("loadUrl", "(Ljava/lang/String;)V", qObjUrlString.object<jstring>());
      }@

      because loadUrl is a method of QDesktopServices class and I don't see this class in your code.

      your code will be the following:

      @void AndroidWebView::loadURL(QString url)
      {
      qDebug() << "AndroidWebView::loadURL" << url;

      QAndroidJniObject javaClass("QDesktopServices");

      QAndroidJniEnvironment env;

      jclass objectClass = env->GetObjectClass(javaClass.object<jobject>());

      objectClass.callObjectMethod("loadUrl", "(Ljava/lang/String;)V", qObjUrlString.object<jstring>());

      }@

      1 Reply Last reply
      0
      • SGaistS Offline
        SGaistS Offline
        SGaist
        Lifetime Qt Champion
        wrote on last edited by
        #3

        Hi,

        There's now the "QtWebView module":https://qt.gitorious.org/qt/qtwebview/source/a2dd3fb028d731b3971e442db81b693c98849900 that can be used on android

        Interested in AI ? www.idiap.ch
        Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

        1 Reply Last reply
        0
        • G Offline
          G Offline
          g00dnight
          wrote on last edited by
          #4

          [quote author="nologinma" date="1408629120"]
          You need to convert that reference to a global reference using the NewGlobalRef method before doing anything that would cause the reference to persist outside the scope of the one JNI call.
          [/quote]
          Hi! Thanks for help. I tried to call NewGlobalRef for all jobjects and jclasses I using in my code, but I still get the same error.

          [quote author="nologinma" date="1408629120"]
          because loadUrl is a method of QDesktopServices class and I don't see this class in your code.
          [/quote]
          But I think I don't need to call any methods of QDesktopServices class. loadUrl, in this case, is the method of android.webkit.WebView class and described "here":http://developer.android.com/reference/android/webkit/WebView.html#loadUrl(java.lang.String).

          [quote author="SGaist" date="1408630724"]Hi,
          There's now the "QtWebView module":https://qt.gitorious.org/qt/qtwebview/source/a2dd3fb028d731b3971e442db81b693c98849900 that can be used on android[/quote]
          Hi. Thanks, this looks very closely to my needs. But I don't sure how I should build this? Can I build it with Qt5.3?

          1 Reply Last reply
          0
          • SGaistS Offline
            SGaistS Offline
            SGaist
            Lifetime Qt Champion
            wrote on last edited by
            #5

            Using qmake, AFAIK yes

            Interested in AI ? www.idiap.ch
            Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

            1 Reply Last reply
            0
            • G Offline
              G Offline
              g00dnight
              wrote on last edited by
              #6

              [quote author="SGaist" date="1408723811"]Using qmake, AFAIK yes[/quote]
              Got these results:
              Alexeys-MacBook-Pro:qtwebview alexeykolikov$ ~/Qt5.3.1/5.3/android_armv7/bin/qmake
              Alexeys-MacBook-Pro:qtwebview alexeykolikov$ make
              cd src/ && ( test -e Makefile || /Users/alexeykolikov/Qt5.3.1/5.3/android_armv7/bin/qmake /Users/alexeykolikov/Documents/github/qtwebview/src/src.pro -o Makefile ) && make -f Makefile
              cd webview/ && ( test -e Makefile || /Users/alexeykolikov/Qt5.3.1/5.3/android_armv7/bin/qmake /Users/alexeykolikov/Documents/github/qtwebview/src/webview/webview.pro -o Makefile ) && make -f Makefile
              Project WARNING: You should probably load(qt_build_config) first in webview.pro for QtWebView, as the latter also load()s qt_module.
              Project MESSAGE: Not doing so may lead to qt_module.prf overriding compiler/linker options in your .pro file.
              Project MESSAGE: Ignore this warning with CONFIG+=no_qt_module_warning if you know what you are doing.
              Project ERROR: Module does not define version.
              make[1]: *** [sub-webview-make_first] Error 3
              make: *** [sub-src-make_first] Error 2

              I guess it's not supposed to be built in this way. Looks like I should build it as a new Qt module like described "here":http://qt-project.org/wiki/Creating-a-new-module-or-tool-for-Qt#55af8d3b581bc7a96ac2a08eb19da92c. Please correct me if I'm wrong.

              1 Reply Last reply
              0
              • N Offline
                N Offline
                nologinma
                wrote on last edited by
                #7

                In my app I have used the following called in c++

                @QAndroidJniObject m_url = QAndroidJniObject::fromString("storage/sdcard0/gps/gps.kml");
                QAndroidJniObject m_application_type = QAndroidJniObject::fromString("application/vnd.google-earth.kml+xml");
                QAndroidJniObject::callStaticMethod<void>("org/qtproject/example/Chronometer/Next72Utility", "openUrl", "(Ljava/lang/String;Ljava/lang/String;)V",m_url.object<jstring>(),m_application_type.object<jstring>());@

                and the java class is the following:

                @//
                // Next72Utility.java
                //
                package org.qtproject.example.Chronometer;

                import android.content.Context;
                import android.app.Activity;
                import java.lang.Runnable;

                import android.content.Intent;
                import java.io.File;
                import android.net.Uri;

                public class Next72Utility extends org.qtproject.qt5.android.bindings.QtActivity
                {

                public static Next72Utility m_istance;

                public Next72Utility()
                {
                m_istance = this;
                }

                public static void openUrl(final String m_url, final String m_application_type)
                {
                m_istance.runOnUiThread(new Runnable() {
                public void run() {

                         Intent intent = new Intent();
                         intent.setAction(android.content.Intent.ACTION_VIEW);
                         File file = new File&#40;m_url&#41;;
                         intent.setDataAndType(Uri.fromFile&#40;file&#41;, m_application_type);
                         m_istance.startActivity(intent);
                     }
                   });
                

                }

                }
                @

                I hope that solves your case.

                1 Reply Last reply
                0
                • SGaistS Offline
                  SGaistS Offline
                  SGaist
                  Lifetime Qt Champion
                  wrote on last edited by
                  #8

                  Indeed, it seems that there are some details missing. Patch underway

                  Interested in AI ? www.idiap.ch
                  Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                  1 Reply Last reply
                  0
                  • G Offline
                    G Offline
                    g00dnight
                    wrote on last edited by
                    #9

                    [quote author="nologinma" date="1408733638"]
                    and the java class is the following.[/quote]

                    Hi. What do I need to do for inclusion of .java files in my QtCreator poject?

                    1 Reply Last reply
                    0
                    • N Offline
                      N Offline
                      nologinma
                      wrote on last edited by
                      #10

                      I have write the steps to introduce the java code into qt project into follwing post: ? "[SOLVED] Qt on Android : How to Vibrate the device ?":https://qt-project.org/forums/viewreply/190435/

                      I hope that it is usefull here.....

                      1 Reply Last reply
                      0
                      • G Offline
                        G Offline
                        g00dnight
                        wrote on last edited by
                        #11

                        Now it works! Thank you very much, man!

                        1 Reply Last reply
                        0

                        • Login

                        • Login or register to search.
                        • First post
                          Last post
                        0
                        • Categories
                        • Recent
                        • Tags
                        • Popular
                        • Users
                        • Groups
                        • Search
                        • Get Qt Extensions
                        • Unsolved