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
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
sitesinindependencies
bölümüne ekleyin:implementation 'com.google.android.gms:play-services-gni-native-c:1.0.0-beta2'
Prefab desteğini etkinleştirmek için aşağıdaki kodu
android
bölümüne ekleyin:buildFeatures { prefab true }
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
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)
target_link_libraries
bölümüne aşağıdaki satırı ekleyin:PUBLIC com.google.android.gms.gni.c::gni_shared
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")
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
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 yeniShowNativeNotification()
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); }
Bildirime özel sabit değerleri ve bildirimi tanımlayın işleyici işlevleri
CharSequenceFromCString()
veCreateNotification()
: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 JavaNotificationCompat.Builder
.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(¬ification_manager_as_object); NotificationManager::destroy(notification_manager); }
Daha önce oluşturduğunuz
ShowNativeNotification()
işlevini şuna güncelleyin:CreateNotificationChannel()
numaralı telefonu arayın. Aşağıdaki koduShowNativeNotification()
: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(¬ification); NotificationManagerCompat::destroy(¬ification_manager); }
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 | bug_report |
Dokümanlar | bug_report |