QString and Android String are not comparable??



  • 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.


  • Moderators

    @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?



  • @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
    


  • 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.


  • Moderators

    @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...



  • if( accountName.equals( line ) )
    

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


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.