0

qt c++ コードから Android AccountManager を使用しようとしています。アカウントを追加するには、のインスタンスを作成したいので、次のandroid.accounts.Accountコードでこれを実行しようとしています:

jstring jUsername = QAndroidJniObject::fromString(username).object<jstring>();
jstring jPassword = QAndroidJniObject::fromString(password).object<jstring>();
jstring jType = QAndroidJniObject::fromString(type).object<jstring>();
qDebug()<<"Creating";
QAndroidJniObject accountObject("android.accounts.Account","(Ljava/lang/String;Ljava/lang/String;)V",jUsername,jType);
qDebug()<<"Inserting";

が作成された行で、コード segfaults が発生しますaccountObject(「作成中」は出力されますが、「挿入中」は出力されません)。

JNI ERROR (app bug): accessed deleted global reference 0x100e46
JNI ERROR (app bug): accessed deleted global reference 0xe46

間違った署名でメソッドを呼び出すと、これが発生することを読みましたが、署名は正しいです (こちらを参照)。

4

1 に答える 1

2

見た目では、文字列を作成する方法が問題を引き起こしています。

jstring jUsername = QAndroidJniObject::fromString(username).object<jstring>();

QAndroidJniObjectこれが行うことは、 ( によって返される)匿名の一時的なものを作成し、fromStringそれからラップされたものを抽出しますjobject(そしてそれを にキャストしますjstring)。そのステートメントの実行が終了するまでに、そのステートメントの存続期間は終了QAndroidJniObjectし、ラップされたステートメントへの参照はjobject解放されます。

コードを次のように変更できます。

auto qjUsername = QAndroidJniObject::fromString(username);
auto jUsername = qjUsername.object<jstring>();

または:

jstring jUsername = env->NewLocalRef(QAndroidJniObject::fromString(username).object<jstring>());

を取得する方法があると仮定しますJNIEnv*DeleteLocalRef新しい参照を作成する場合は、必要がなくなったら削除する必要があります。

于 2016-01-10T19:02:46.340 に答える