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. QString and Android String are not comparable??
Forum Update on Monday, May 27th 2025

QString and Android String are not comparable??

Scheduled Pinned Locked Moved Solved Mobile and Embedded
6 Posts 2 Posters 850 Views
  • 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
    Gourmet
    wrote on 12 Aug 2019, 20:08 last edited by Gourmet 8 Dec 2019, 20:10
    #1

    Sorry if it was already discussed but I never met this in Internet. I did not find this in Qt Bug report site. Please let me know if I missed something.

    I call Java function like this:

    bool res = QAndroidJniObject::callStaticMethod<jboolean>( PCpath, 
                               "setAccountName", "(Ljava/lang/String;)Z", 
                               QAndroidJniObject::fromString( QString("stringInJavaCode") ).object<jstring>() );
    qWarning()<<res;
    

    The PCpath is static const char* string with proper content. The java method looks like:

        public static boolean setAccountName( String accountName )
        {
            //accountName = "stringInJavaCode";
            if( accountName == "stringInJavaCode" ) // defenitely the same cause it was copy-pasted
            {
                DebugMessage("BUT IT IS TRUE!!!");
                return true;
            }
            return false;
        }
    
    

    And the output:

     : (null):0 ((null)): false
    

    Uncomment accountName assignment and it will print:

     : (null):0 ((null)): "BUT IT IS TRUE!!!"
     : (null):0 ((null)): true
    

    When printing both strings in Java code they are look identically. No difference. I suppose there was left invisible character from QString - the trailing '\0'. Looks like a bug in QAndroidJniObject::fromString() - it must convert QString content clearly. If there is trailing '\0' then it must be removed. Java strings are not null terminated. Backward conversion must add trailing zero.

    J 1 Reply Last reply 13 Aug 2019, 05:50
    1
    • G Gourmet
      12 Aug 2019, 20:08

      Sorry if it was already discussed but I never met this in Internet. I did not find this in Qt Bug report site. Please let me know if I missed something.

      I call Java function like this:

      bool res = QAndroidJniObject::callStaticMethod<jboolean>( PCpath, 
                                 "setAccountName", "(Ljava/lang/String;)Z", 
                                 QAndroidJniObject::fromString( QString("stringInJavaCode") ).object<jstring>() );
      qWarning()<<res;
      

      The PCpath is static const char* string with proper content. The java method looks like:

          public static boolean setAccountName( String accountName )
          {
              //accountName = "stringInJavaCode";
              if( accountName == "stringInJavaCode" ) // defenitely the same cause it was copy-pasted
              {
                  DebugMessage("BUT IT IS TRUE!!!");
                  return true;
              }
              return false;
          }
      
      

      And the output:

       : (null):0 ((null)): false
      

      Uncomment accountName assignment and it will print:

       : (null):0 ((null)): "BUT IT IS TRUE!!!"
       : (null):0 ((null)): true
      

      When printing both strings in Java code they are look identically. No difference. I suppose there was left invisible character from QString - the trailing '\0'. Looks like a bug in QAndroidJniObject::fromString() - it must convert QString content clearly. If there is trailing '\0' then it must be removed. Java strings are not null terminated. Backward conversion must add trailing zero.

      J Offline
      J Offline
      J.Hilk
      Moderators
      wrote on 13 Aug 2019, 05:50 last edited by
      #2

      @gourmet
      interesting, it shouldn't

      this is the fromString function

      QJNIObjectPrivate QJNIObjectPrivate::fromString(const QString &string)
      {
          QJNIEnvironmentPrivate env;
          jstring res = env->NewString(reinterpret_cast<const jchar*>(string.constData()),
                                              string.length());
          QJNIObjectPrivate obj(res);
          env->DeleteLocalRef(res);
          return obj;
      }
      

      QString::length returns the number of chars that excludes the 0 termination QString("Hello").length() == 5

      what do you get, when you log the string and the length of the string on the Java side?


      Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


      Q: What's that?
      A: It's blue light.
      Q: What does it do?
      A: It turns blue.

      G 1 Reply Last reply 13 Aug 2019, 09:30
      1
      • J J.Hilk
        13 Aug 2019, 05:50

        @gourmet
        interesting, it shouldn't

        this is the fromString function

        QJNIObjectPrivate QJNIObjectPrivate::fromString(const QString &string)
        {
            QJNIEnvironmentPrivate env;
            jstring res = env->NewString(reinterpret_cast<const jchar*>(string.constData()),
                                                string.length());
            QJNIObjectPrivate obj(res);
            env->DeleteLocalRef(res);
            return obj;
        }
        

        QString::length returns the number of chars that excludes the 0 termination QString("Hello").length() == 5

        what do you get, when you log the string and the length of the string on the Java side?

        G Offline
        G Offline
        Gourmet
        wrote on 13 Aug 2019, 09:30 last edited by Gourmet
        #3

        @j-hilk Of course length() function excludes trailing zero. This is not a visible character and it is not taken in QString comparison.

        @j-hilk said in QString and Android String are not comparable??:

        when you log the string and the length of the string on the Java side?

        Prints equal sizes.

            public static boolean setAccountName( String accountName )
            {
                String line = "stringInJavaCode";
                if( accountName == line ) // defenitely the same cause it was copy-pasted
                {
                    DebugMessage("BUT IT IS TRUE!!!");
                    return true;
                }
                DebugMessage(accountName.length()+" "+line.length());
                return false;
            }
        
        : (null):0 ((null)): "16 16"
        : (null):0 ((null)): false
        
        J 1 Reply Last reply 13 Aug 2019, 09:42
        0
        • G Offline
          G Offline
          Gourmet
          wrote on 13 Aug 2019, 09:37 last edited by
          #4

          Sorry I have find workaround this bug. It stopped my development. I will post official bug report later but now I finish discuss it here.

          1 Reply Last reply
          0
          • G Gourmet
            13 Aug 2019, 09:30

            @j-hilk Of course length() function excludes trailing zero. This is not a visible character and it is not taken in QString comparison.

            @j-hilk said in QString and Android String are not comparable??:

            when you log the string and the length of the string on the Java side?

            Prints equal sizes.

                public static boolean setAccountName( String accountName )
                {
                    String line = "stringInJavaCode";
                    if( accountName == line ) // defenitely the same cause it was copy-pasted
                    {
                        DebugMessage("BUT IT IS TRUE!!!");
                        return true;
                    }
                    DebugMessage(accountName.length()+" "+line.length());
                    return false;
                }
            
            : (null):0 ((null)): "16 16"
            : (null):0 ((null)): false
            
            J Offline
            J Offline
            J.Hilk
            Moderators
            wrote on 13 Aug 2019, 09:42 last edited by J.Hilk
            #5

            @gourmet

            well, to investigate further I suggest the following:

            public static boolean setAccountName( String accountName )
                {
                    String line = "stringInJavaCode";
                    
                   int l1 = accountName.length();
                   int l2 = line.length();
                   int lmin = Math.min(l1, l2); 
              
                    for (int i = 0; i < lmin; i++) { 
                        int str1_ch = (int)str1.charAt(i); 
                        int str2_ch = (int)str2.charAt(i); 
            
                        if(str1_ch != str2_ch)
                           //Diff at index i
                        DebugMessage("Diff here");
            
                    }
                    if( accountName == line ) // defenitely the same cause it was copy-pasted
                    {
                        DebugMessage("BUT IT IS TRUE!!!");
                        return true;
                    }
                    DebugMessage(accountName.length()+" "+line.length());
                    return false;
                }
            

            Actually, in Java, == tests for reference equality (wether they are the same object) and .equals() tests for value equality (wether they are logically equal)

            // These two have the same value
            new String("test").equals("test") // --> true 
            
            // ... but they are not the same object
            new String("test") == "test" // --> false 
            
            // ... neither are these
            new String("test") == new String("test") // --> false 
            

            I guess,
            working as indented...


            Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


            Q: What's that?
            A: It's blue light.
            Q: What does it do?
            A: It turns blue.

            G 1 Reply Last reply 13 Aug 2019, 10:14
            3
            • J J.Hilk
              13 Aug 2019, 09:42

              @gourmet

              well, to investigate further I suggest the following:

              public static boolean setAccountName( String accountName )
                  {
                      String line = "stringInJavaCode";
                      
                     int l1 = accountName.length();
                     int l2 = line.length();
                     int lmin = Math.min(l1, l2); 
                
                      for (int i = 0; i < lmin; i++) { 
                          int str1_ch = (int)str1.charAt(i); 
                          int str2_ch = (int)str2.charAt(i); 
              
                          if(str1_ch != str2_ch)
                             //Diff at index i
                          DebugMessage("Diff here");
              
                      }
                      if( accountName == line ) // defenitely the same cause it was copy-pasted
                      {
                          DebugMessage("BUT IT IS TRUE!!!");
                          return true;
                      }
                      DebugMessage(accountName.length()+" "+line.length());
                      return false;
                  }
              

              Actually, in Java, == tests for reference equality (wether they are the same object) and .equals() tests for value equality (wether they are logically equal)

              // These two have the same value
              new String("test").equals("test") // --> true 
              
              // ... but they are not the same object
              new String("test") == "test" // --> false 
              
              // ... neither are these
              new String("test") == new String("test") // --> false 
              

              I guess,
              working as indented...

              G Offline
              G Offline
              Gourmet
              wrote on 13 Aug 2019, 10:14 last edited by
              #6
              if( accountName.equals( line ) )
              

              This works. Hmmm... No wonder I hate Java.

              1 Reply Last reply
              0

              5/6

              13 Aug 2019, 09:42

              • Login

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