Qt Android Programlama: Java Kodları Nasıl Çağrılır? [Konu Anlatımı]

Başlatan Limonata, 07 Mart 2017 - 21:10:09

« önceki - sonraki »

0 Üyeler ve 1 Ziyaretçi konuyu incelemekte.

Limonata

Selamün Aleyküm;
Qt ile Android programlama yapan arkadaşlara faydalı olması için QAndroidExtras modülünde bulunan Java ve Android SDK kodlarını çağırmamızı sağlayan sınıfları ve üye verilerini anlatacağım. Yeri gelmişken Qt'da mobil uygulama geliştirmek için her zaman QtQuick Controls 2 proje türü tercih edilmesi daha doğru olur.

Öncelikle QAndroidExtras modülünü kullanabilmemiz için .pro dosyamıza şu kodu eklememiz gerekli:

android {
  QT += androidextras
}


C++'da şu başlık dosyaları kullanılacak:

#include <QtAndroid>
#include <QAndroidJniObject>


Konuya girmeden önce şunu da unutmayın: Android için proje klasörünü oluşturmalıyız. Bunun için Qt Creator'dan şu adımları uygulayıp Android dizinimizi oluşturmalıyız:



Eğer Java kodlarımızı tuttuğumuz kendi Java dosyamızı kullanacaksak şu şekilde oluşturduğumuz android klasörüne src adlı bir klasör oluşturup, onun da içine paketimizi oluşturup Java dosyamızı içine atmalıyız:


(Not: Aşağıda anlatacağım örneklerde com.javakodu paketini ve Picker.java dosyasını yeri geldiğince kullanacağım).

QAndroidJniObject Sınıfı
(http://doc.qt.io/qt-5/qandroidjniobject.html)

Java metotları çağıran üye fonksiyonların aldığı parametreler şu şekilde kullanılır:
className: Bu parametreye paket ismi ile beraber sınıf ismi yazılır, paketler '/' ile ayrılır.
Örnek: com/javakodu/SinifAdi
methodName: Java metodunun ismi yazılır. Örnek: metoduCagir
signature: Çağrılan metodun aldığı parametrelerin türleri ve metodun dönüş türü yazılır. Kullanımı için sözdizimi şöyledir: (ParametreTürleri)MetodunDönüşTürü
Örnek: (I)V    ==> Tam sayı parametre alan ve geriye bir şey döndürmeyen bir metot.
            (Ljava/lang/String;I)Ljava/lang/String;   ==> String ve tam sayı parametre alan ve geriye String döndüren bir metot.













İmzaTür
Zboolean
Bbyte
Cchar
Sshort
Iint
Jlong
Ffloat
Ddouble
Lpaket/adi/SinifAdi;paket.adı.SınıfAdı
[TürDizi

... : Bu son parametre Java metoduna gönderilecek olan argümanları alır. (C / C++ dillerindeki değişken fonksiyonlar (variadic functions) konusuna bakılabilir: http://en.cppreference.com/w/cpp/utility/variadic)

callStaticMethod Üye Fonksiyonu:
Statik olan ve ilkel (primitive) veri türü döndüren bir Java metodu çağırmak için callStaticMethod üye fonksiyonu kullanılır, 4 tane aşırı yüklenmiş biçimi vardır:

T callStaticMethod(const char *className, const char *methodName)

T callStaticMethod(const char *className, const char *methodName, const char *signature, ...)

T callStaticMethod(jclass clazz, const char *methodName)

T callStaticMethod(jclass clazz, const char *methodName, const char *signature, ...)

Örnek:
Çağrılacak Java Metodu:

package com.javakodu;
public class Picker
{
  public static int faktoriyel(int n)
  {
    return (n > 1) ? n * faktoriyel(n – 1) : 1;
  }
}

C++ Tarafından Çağrılması:

int sonuc = QAndroidJniObject::callStaticMethod<int>("com/javakodu/Picker",
                                                     "faktoriyel",
                                                     "(I)I",
                                                     7);


callStaticObjectMethod Üye Fonksiyonu:
callStaticMethod üye fonksiyonunun yalnızca ilkel veri türü döndüren metodu çağırabildiğini söylemiştim. İşte burada callStaticObjectMethod üye fonksiyonu ile diğer veri türlerini döndüren statik bir Java metodunu çağırabiliriz. 4 tane aşırı yüklenmiş biçimi vardır:

QAndroidJniObject callStaticObjectMethod(const char *className, const char *methodName)

QAndroidJniObject callStaticObjectMethod(const char *className, const char *methodName, const char *signature, ...)

QAndroidJniObject callStaticObjectMethod(jclass clazz, const char *methodName)

QAndroidJniObject callStaticObjectMethod(jclass clazz, const char *methodName, const char *signature, ...)

Örnek:
Çağrılacak Java Metodu:

public String merhabaDunya()
{
  return "Merhaba Dünya!\n";
}

C++ Tarafından Çağrılması:

QAndroidJniObject alinanDeger = QAndroidJniObject::callStaticObjectMethod(
      "com/javakodu/Picker",
      "merhabaDunya",
      "()Ljava/lang/String;");



Misal olarak Android SDK'da bulunan Toast iletisini kullanmak istersek şöyle bir şey yapabiliriz:

Normalde Android'de şöyle kullanabiliyorduk:

Toast toast = Toast.makeText(getApplicationContext(), "Selam", Toast.LENGTH_LONG);
toast.show();

Bunu Qt'da şu şekilde kullanabiliriz:

const int LENGTH_SHORT = 0;
const int LENGTH_LONG = 1;

QtAndroid::runOnAndroidThread([]()
{
  QAndroidJniObject toast = QAndroidJniObject::callStaticObjectMethod(
      "android/widget/Toast",
      "makeText",
      "(Landroid/content/Context;Ljava/lang/CharSequence;I)Landroid/widget/Toast;",
      QtAndroid::androidActivity().object(),
      QAndroidJniObject::fromString("Selam").object(),
      LENGTH_LONG);
 
  toast.callMethod<void>("show");
});


fromString Üye Fonksiyonu:
QAndroidJniObject fromString(const QString &string)

QString türünden Java'daki String sınıfına dönüşüm yapmamız gerekiyor. Bu üye fonksiyon bu işe yarıyor. QString türü direk olarak Java metoduna aktarılamaz.

Örnek:
Yukarıdaki Toast iletisini çağırma örneğini inceleyiniz.

callMethod Üye Fonksiyonu:
Statik olmayan, bu yüzden oluşturulan bir nesneden kullanılabilen, sadece ilkel veri türü döndüren Java metotlarını çağırmak için kullanılır, 2 tane aşırı yüklenmiş üye fonksiyonu vardır:

T callMethod(const char *methodName) const;

T callMethod(const char *methodName, const char *signature, ...) const;

callObjectMethod Üye Fonksiyonu:
callMethod üye fonksiyonunu sadece ilkel veri türlerini döndüren Java metotlarını çağırabiliyordu. Bu metot ise diğer veri türlerini döndüren Java metotlarını çağırıyor. 2 tane aşırı yüklenmiş üye fonksiyonu vardır:

QAndroidJniObject callObjectMethod(const char *methodName) const;

QAndroidJniObject callObjectMethod(const char *methodName, const char *signature, ...) const;

Bu callMethod ve callObjectMethod'a örnek vermeme sanırım gerek yok. Çünkü yukarıda Toast  örneğinde kullandım.

Şimdilik bu kadar. Daha ayrıntılı bilgiler için Qt'un dökümanlarını okuyabilirsiniz. Eğer sormak istediğiniz sualleriniz olursa sorabilirsiniz.