Kitaplık sarmalayıcı kılavuzu

Bu kılavuzda, Android API kitaplığı sarmalayıcısının nasıl kullanılacağı açıklanmaktadır. Kitaplık sarmalayıcı komut satırı aracı, Java Android için C dili sarmalayıcı kodu oluşturur API'ler sayesinde Java kitaplıklarını yerel C/C++ Android uygulamalarına entegre edebilirsiniz. Kitaplık sarmalayıcı hakkında daha fazla bilgi için bkz. Android API'leri için kitaplık sarmalayıcı

Bu adım adım açıklamalı kılavuzda, bir SDK'yı entegre etmek için sarmalayıcı Java kitaplığını yerel Android uygulamasına dönüştürme. Örneğin, bu kılavuzda androidx.core.app paketinin bildirim kitaplığının entegre edilmesi. Bu kitaplık hakkında daha fazla bilgi edinmek için Bildirim Oluşturma başlıklı makaleye bakın.

Ön koşullar

Bu kılavuzda, mevcut bir yerel Android projeniz olduğu varsayılmıştır. Aynı zamanda Gradle derleme sistemini kullanır. Mevcut bir projeniz yoksa yeni bir Yerel C++ şablonunu kullanarak Android Studio'da yeni bir tane oluşturun.

Bu kılavuzdaki örnek kod, my_project/ dizinini kullanır. Yerel kodu, sitenizin varsayılan dizini olan my_project/app/src/main/cpp/ konumundadır. Android Studio projeleri.

Kitaplık sarmalayıcı aracınız henüz yoksa indirin ve sıkıştırılmış dosyayı açın paketini istediğiniz dizine ekleyebilirsiniz. Bu CLI aracı, Java Runtime'ı gerektiriyor Ortam (JRE).

Yerel kod oluştur

Java kitaplığını entegre ederken sarmalayıcı aracını kullanarak yerel kod sarmalayıcı oluşturabilirsiniz. İlk adım, sarmalayıcıyı yapılandırmaktır.

Sarmalayıcı yapılandırmasını oluşturma

Kitaplık sarmalayıcı yapılandırma dosyalarını çıktısı için ekleyebilirsiniz. Bu dosyanın özelliklerinden biri, sınıfları ve yöntemleri öğreneceğiz.

Bildirim kitaplığı için sarmalama yöntemi çok olmadığından şunları yapabilirsiniz: bunları doğrudan custom_classes bölümünde tanımlayabilirsiniz. Yeni oluştur Yöntemleri tanımlamak için projenizin herhangi bir yerinde config.json kaynağı kullanın. Örneğin, my_project/library_wrapper/config.json oluşturup aşağıdakileri yapıştırabilirsiniz örnek yapılandırma:

{
  "custom_classes": [
    {
      "class_name": "class java.lang.CharSequence"
    },
    {
      "class_name": "class java.lang.Object",
      "methods": [
        "java.lang.String toString()"
      ]
    },
    {
      "class_name": "class java.lang.String"
    },
    {
      "class_name": "class android.content.Context",
      "methods": [
        "java.lang.Object getSystemService(java.lang.String name)"
      ]
    },
    {
      "class_name": "class android.app.Notification"
    },
    {
      "class_name": "class android.app.NotificationManager",
      "methods": [
        "void createNotificationChannel(android.app.NotificationChannel channel)"
      ]
    },
    {
      "class_name": "class android.app.NotificationChannel",
      "methods": [
        "NotificationChannel(java.lang.String id, java.lang.CharSequence name, int importance)",
        "void setDescription(java.lang.String description)"
      ]
    },
    {
      "class_name": "class androidx.core.app.NotificationCompat"
    },
    {
      "class_name": "class androidx.core.app.NotificationCompat$Builder",
      "methods": [
        "Builder(android.content.Context context, java.lang.String channelId)",
        "androidx.core.app.NotificationCompat$Builder setContentText(java.lang.CharSequence text)",
        "androidx.core.app.NotificationCompat$Builder setContentTitle(java.lang.CharSequence title)",
        "androidx.core.app.NotificationCompat$Builder setSmallIcon(int icon)",
        "androidx.core.app.NotificationCompat$Builder setPriority(int pri)",
        "android.app.Notification build()"
      ]
    },
    {
      "class_name": "class androidx.core.app.NotificationManagerCompat",
      "methods": [
        "static androidx.core.app.NotificationManagerCompat from(android.content.Context context)",
        "void notify(int id, android.app.Notification notification)"
      ]
    }
  ]
}

Yukarıdaki örnekte, yerel sarmalayıcı kodu gerektirir.

Kitaplık sarmalayıcıyı çalıştırma

Sarmalayıcı yapılandırma dosyanız tanımlandığında, yeni bir etiket oluşturmak için yerel sarmalayıcı kodu. Kitaplık sarmalayıcıyı çıkardığınız bir terminal açın ve aşağıdaki komutu çalıştırın:

java -jar lw.jar \
  -o "my_project/app/src/main/cpp/native_wrappers" \
  -c "my_project/library_wrapper/config.json"

Önceki örnekte, sarmalayıcınızı belirtmek için -c parametresini kullanırsınız yapılandırma konumunu ve oluşturulan kod dizinini tanımlamak için -o parametresini kullanın. Aracı çalıştırdıktan sonra, aracı çağırmak için gerekli olan koda Yerel uygulamanızdan Java tabanlı bildirim API'si.

Yerel bildirimleri uygulayın

Bu bölümde, Android bildirimleri kitaplığını yerel uygulama oluşturun. İlk adım, projenin uygulama düzeyindeki gradle.build kaynağı (my_project/app/gradle.build).

gradle.build uygulamasını güncelle

  1. GNI, oluşturulan sarmalayıcı kodunun gerektirdiği bir destek kitaplığıdır. Tüm projeler bu kitaplığa referansta bulunması gerekir. Bu kitaplığa referansta bulunmak için şu satırı build.gradle sitesinin dependencies bölümüne ekleyin:

    implementation 'com.google.android.gms:play-services-gni-native-c:1.0.0-beta2'
    
  2. Prefab desteğini etkinleştirmek için aşağıdaki kodu android bölümüne ekleyin:

    buildFeatures {
      prefab true
    }
    
  3. cmake hizmetini yapılandırmak içincmake android/defaultConfig bölümü:

    externalNativeBuild {
      cmake {
          arguments '-DANDROID_STL=c++_shared'
      }
    }
    

Tamamlanmış build.gradle yapılandırmanız şuna benzeyecektir:

android {
    ...

    buildFeatures {
        prefab true
    }

    defaultConfig {
        ...

        externalNativeBuild {
            cmake {
                arguments '-DANDROID_STL=c++_shared'
            }
        }
    }
}

dependencies {
    ...
    implementation 'com.google.android.gms:play-services-gni-native-c:1.0.0-beta2'
    ...
}

CMakeLists öğesini değiştir

  1. GNI kitaplığını projenizin CMakeLists.txt öğesine ekleyin (my_project/app/src/main/cpp/CMakeLists.txt) şu satırı ekleyerek: dosyanın en üst düzeyi:

    find_package(com.google.android.gms.gni.c REQUIRED CONFIG)
    
  2. target_link_libraries bölümüne aşağıdaki satırı ekleyin:

    PUBLIC com.google.android.gms.gni.c::gni_shared
    
  3. Oluşturulan koda bir referans eklemek için dosyanın en üst düzeyi:

    file(GLOB_RECURSE native_wrappers CONFIGURE_DEPENDS "native_wrappers/*.cpp" "native_wrappers/*.cc")
    
  4. Dosyanın sonuna şu satırları ekleyin:

    include_directories(./native_wrappers/c)
    include_directories(./native_wrappers/cpp)
    

Güncellenen CMakeLists.txt kaynağınız aşağıdaki örneğe benzeyecektir:

cmake_minimum_required(VERSION 3.18.1)

project("my_project")

file(GLOB_RECURSE native_wrappers CONFIGURE_DEPENDS "native_wrappers/*.cpp" "native_wrappers/*.cc")

add_library(
        my_project
        SHARED
        native-lib.cpp
        ${native_wrappers}
        )

find_library(
        log-lib
        log)

find_package(com.google.android.gms.gni.c REQUIRED CONFIG)

target_link_libraries(
        my_project
        PUBLIC com.google.android.gms.gni.c::gni_shared
        ${log-lib})

include_directories(./native_wrappers/c)
include_directories(./native_wrappers/cpp)

Bildirim mantığını uygulayın

  1. Bildirimi uygulamak istediğiniz kaynak dosyayı açın veya oluşturun özellikler. Bu dosyaya gni.h başlık dosyasını dahil edin ve bir yeni ShowNativeNotification() işlevi:

    #include "gni/gni.h"
    
    void ShowNativeNotification(JNIEnv *env, jobject main_activity, int icon_id) {
      // Get the JavaVM from the JNIEnv.
      JavaVM *java_vm;
      env->GetJavaVM(&java_vm);
    
      // Initialize the GNI runtime. This function needs to be called before any
      // call to the generated code.
      GniCore_init(java_vm, main_activity);
    }
    
  2. Bildirime özel sabit değerleri ve bildirimi tanımlayın işleyici işlevleri CharSequenceFromCString() ve CreateNotification():

    C

    const int32_t IMPORTANCE_HIGH = 4;  // NotificationManager.IMPORTANCE_HIGH
    const int32_t PRIORITY_MAX = 2;  // NotificationCompat.PRIORITY_MAX
    const int32_t NOTIFICATION_ID = 123;  // User defined notification id.
    
    // Convert a C string into CharSequence.
    CharSequence *CharSequenceFromCString(const char *text) {
       String *string = String_fromCString(text);
       // Cast String to CharSequence. In Java, a String implements CharSequence.
       CharSequence *result = GNI_CAST(CharSequence, String, string);
       // Casting creates a new object, so it needs to be destroyed as normal.
       String_destroy(string);
       return result;
    }
    
    // Create a notification.
    Notification *
    CreateNotification(Context *context, String *channel_id,
                       const char *title, const char *content,
                       int32_t icon_id) {
       // Convert C strings to CharSequence.
       CharSequence *title_chars = CharSequenceFromCString(title);
       CharSequence *content_chars = CharSequenceFromCString(content);
    
       // Create a NotificationCompat.Builder and set all required properties.
       NotificationCompat_Builder *notification_builder =
           NotificationCompat_Builder_construct(context, channel_id);
       NotificationCompat_Builder_setContentTitle(notification_builder,
                                                  title_chars);
       NotificationCompat_Builder_setContentText(notification_builder,
                                                 content_chars);
       NotificationCompat_Builder_setSmallIcon(notification_builder, icon_id);
       NotificationCompat_Builder_setPriority(notification_builder,
                                              PRIORITY_MAX);
    
       // Build a notification.
       Notification *notification =
           NotificationCompat_Builder_build(notification_builder);
    
       // Clean up allocated objects.
       NotificationCompat_Builder_destroy(notification_builder);
       CharSequence_destroy(title_chars);
       CharSequence_destroy(content_chars);
    
       return notification;
    }
    

    C++

    const int32_t IMPORTANCE_HIGH = 4;  // NotificationManager.IMPORTANCE_HIGH
    const int32_t PRIORITY_MAX = 2;  // NotificationCompat.PRIORITY_MAX
    const int32_t NOTIFICATION_ID = 123;  // User defined notification id.
    
    // Convert a C string into CharSequence.
    CharSequence *CharSequenceFromCString(const char *text) {
       String *string = String_fromCString(text);
       // Cast String to CharSequence. In Java, a String implements CharSequence.
       CharSequence *result = new CharSequence(string->GetImpl());
       // Casting creates a new object, so it needs to be destroyed as normal.
       String::destroy(string);
       return result;
    }
    
    // Create a notification.
    Notification&
    CreateNotification(Context *context, String *channel_id, const char *title,
                       const char *content, int32_t icon_id) {
       // Convert C strings to CharSequence.
       CharSequence *title_chars = CharSequenceFromCString(title);
       CharSequence *content_chars = CharSequenceFromCString(content);
    
       // Create a NotificationCompat.Builder and set all required properties.
    
       NotificationCompat::Builder *notification_builder = new NotificationCompat::Builder(*context, *channel_id);
       notification_builder->setContentTitle(*title_chars);
       notification_builder->setContentText(*content_chars);
       notification_builder->setSmallIcon(icon_id);
       notification_builder->setPriority(PRIORITY_MAX);
    
       // Build a notification.
       Notification& notification = notification_builder->build();
    
       // Clean up allocated objects.
       NotificationCompat::Builder::destroy(notification_builder);
       CharSequence::destroy(title_chars);
       CharSequence::destroy(content_chars);
    
       return notification;
    }
    

    Bildirim kitaplığının bazı işlevleri şunun yerine CharSequence alır: String. CharSequenceFromCString() işlevi, dönüşüm izleme özelliğini devre dışı bırakır. CreateNotification() işlevi, Bildirim oluşturmak için Java NotificationCompat.Builder.

  3. Aşağıdakini yapıştırarak bildirim kanalı oluşturmak için mantık ekleyin işlev, CreateNotificationChannel():

    C

    void CreateNotificationChannel(Context *context, String *channel_id) {
       CharSequence *channel_name = CharSequenceFromCString("channel name");
       String *channel_description = String_fromCString("channel description");
       String *system_service_name = String_fromCString("notification");
       NotificationChannel *channel =
           NotificationChannel_construct(channel_id, channel_name,
                                         IMPORTANCE_HIGH);
       NotificationChannel_setDescription(channel, channel_description);
    
       Object *notification_manager_as_object =
           Context_getSystemService(context, system_service_name);
       NotificationManager *notification_manager =
           GNI_CAST(NotificationManager, Object,
                    notification_manager_as_object);
    
       NotificationManager_createNotificationChannel(notification_manager,
                                                     channel);
    
       CharSequence_destroy(channel_name);
       String_destroy(channel_description);
       String_destroy(system_service_name);
       NotificationChannel_destroy(channel);
       Object_destroy(notification_manager_as_object);
       NotificationManager_destroy(notification_manager);
    }
    

    C++

    void CreateNotificationChannel(Context *context, String *channel_id) {
       CharSequence *channel_name = CharSequenceFromCString("channel name");
       String *channel_description = String_fromCString("channel description");
       String *system_service_name = String_fromCString("notification");
       NotificationChannel *channel =
           new NotificationChannel(*channel_id, *channel_name, IMPORTANCE_HIGH);
       channel->setDescription(*channel_description);
    
       Object& notification_manager_as_object =
           context->getSystemService(*system_service_name);
       NotificationManager *notification_manager =
           new NotificationManager(notification_manager_as_object.GetImpl());
    
       notification_manager->createNotificationChannel(*channel);
    
       CharSequence::destroy(channel_name);
       String::destroy(channel_description);
       String::destroy(system_service_name);
       NotificationChannel::destroy(channel);
       Object::destroy(&notification_manager_as_object);
       NotificationManager::destroy(notification_manager);
    }
    
  4. Daha önce oluşturduğunuz ShowNativeNotification() işlevini şuna güncelleyin: CreateNotificationChannel() numaralı telefonu arayın. Aşağıdaki kodu ShowNativeNotification():

    C

    void ShowNativeNotification(JNIEnv *env, jobject main_activity, int icon_id) {
     // ...
    
     // Create a Context object by wrapping an existing JNI reference.
     Context *context = Context_wrapJniReference(main_activity);
    
     // Create a String object.
     String *channel_id = String_fromCString("new_messages");
    
     // Create a notification channel.
     CreateNotificationChannel(context, channel_id);
    
     // Create a notification with a given title, content, and icon.
     Notification *notification =
         CreateNotification(context, channel_id, "My Native Notification",
                            "Hello!", icon_id);
    
     // Create a notification manager and use it to show the notification.
     NotificationManagerCompat *notification_manager =
         NotificationManagerCompat_from(context);
     NotificationManagerCompat_notify(notification_manager, NOTIFICATION_ID,
                                      notification);
    
     // Destroy all objects.
     Context_destroy(context);
     String_destroy(channel_id);
     Notification_destroy(notification);
     NotificationManagerCompat_destroy(notification_manager);
    }
    

    C++

    void ShowNativeNotification(JNIEnv *env, jobject main_activity, int icon_id) {
       // Get the JavaVM from the JNIEnv.
       JavaVM *java_vm;
       env->GetJavaVM(&java_vm);
    
       // Initialize the GNI runtime. This function needs to be called before any
       // call to the generated code.
       GniCore::Init(java_vm, main_activity);
    
       // Create a Context object by wrapping an existing JNI reference.
       Context *context = new Context(main_activity);
    
       // Create a String object.
       String *channel_id = String_fromCString("new_messages");
    
       // Create a notification channel.
       CreateNotificationChannel(context, channel_id);
    
       // Create a notification with a given title, content, and icon.
       Notification& notification =
           CreateNotification(context, channel_id, "My Native Notification",
                              "Hello!", icon_id);
    
       // Create a notification manager and use it to show the notification.
       NotificationManagerCompat& notification_manager =
           NotificationManagerCompat::from(*context);
       notification_manager.notify(NOTIFICATION_ID, notification);
    
       // Destroy all objects.
       Context::destroy(context);
       String::destroy(channel_id);
       Notification::destroy(&notification);
       NotificationManagerCompat::destroy(&notification_manager);
    }   
  5. Mantığınızı tanımladıktan sonra şunu çağırarak bir bildirim tetikleyebilirsiniz: ShowNativeNotification() öğesini projenizde uygun bir konuma yerleştirin.

Uygulamayı çalıştırın

ShowNativeNotification() öğesini çağıran kodu derleyin ve çalıştırın. Basit bir test cihazınızın ekranının üst kısmında bir bildirim görünür.

JAR'lerden sarmalayıcı oluşturma

Önceki örnekte, Java sınıflarını manuel olarak tanımladınız ve yöntemleri için yerel kod kullanmanızı öneririz. Örneğin, bir API'nin büyük bölümlerine erişmesi gerekiyorsa, daha fazla kitaplık JAR'ı yükleyebilirsiniz. Ardından sarmalayıcı, herkese açık tüm sembolleri test eder.

Aşağıdaki örnek, bir kitaplık sağlayarak Notifications API'nin tamamını sarmalar. JAR

Gerekli JAR'leri edinin

Notification API, androidx.core paketinin bir parçasıdır. Google Maven deposunda yer alır. Kitaplık aar dosyasını indirin ve paketi açın. istediğiniz bir dizin oluşturabilirsiniz. classes.jar dosyasını bulun.

classes.jar dosyası, zorunlu bildirimlerimiz dışında çok sayıda sınıf içeriyor kitaplığını açar. Kitaplık sarmalayıcıyı yalnızca classes.jar ile sağlarsanız araç JAR'daki her sınıf için yerel kod oluşturur. Bu da verimsiz ve projemiz için çok gerekli. Bu sorunu çözmek için kod oluşturmayı JAR'ın bildirimiyle kısıtlamak için sarmalayıcı yapılandırması sınıflar.

İzin ver filtresi tanımlayın

Filtre dosyaları, kitaplık sarmalayıcınıza sağladığınız düz metin dosyalarıdır. yapılandırma. Dahil edilecek (veya hariç tutulacak) sınıfları tanımlamanıza olanak tanırlar kitaplığına sağlanan JAR dosyalarından alınır.

Projenizde allowed-symbols.txt başlıklı bir dosya oluşturun ve bu dosyayı şu satır:

androidx.core.app.NotificationCompat*

İzin ver filtresi olarak kullanıldığında, önceki kod yalnızca sahiplerin adları androidx.core.app.NotificationCompat ile başlar.

Kitaplık sarmalayıcıyı çalıştırma

JAR dizinine giden bir terminal açın ve aşağıdaki komutu çalıştırın:

java -jar lw.jar \
 -i classes.jar \
 -o "./generated-jar" \
 -c "./config.json" \
 -fa allowed-symbols.txt \
 --skip_deprecated_symbols

Önceki örnek komut, filtrelenmiş sınıflarınız için sarmalayıcı kodu oluşturur generated-jar/ dizinine.

Destek

Kitaplık sarmalayıcı ile ilgili bir sorun tespit ederseniz lütfen bize bildirin.

Hatalara göz at Hata bildir
Mühendislik
Dokümanlar