Yerel kodda özel iz etkinlikleri
Koleksiyonlar ile düzeninizi koruyun
İçeriği tercihlerinize göre kaydedin ve kategorilere ayırın.
Android 6.0 (API düzeyi 23) ve sonraki sürümler yerel izleme API'sini (trace.h
) destekler.
sistem arabelleğine izleme etkinlikleri yazmak için sistem arabelleğine
Perfetto veya sistem izleme. Bu API'nin yaygın kullanım alanları arasında saatin kaç olduğunu
belirli bir kod bloğunun bir kod bloğunu yürütmek ve ilişkilendirmek için
istenmeyen sistem davranışıyla karşılaşabilir.
Not: API düzeyi 27 ve önceki sürümleri çalıştıran cihazlarda ve emülatörlerde (varsa)
yoksa veya bellek çok parçalıysa
şu mesaj var: Atrace could not allocate enough memory to record a trace
.
Bu durum yaşanırsa ve yakalamanızda tam bir veri kümesi yoksa
arka plan işlemlerini kapatmalı veya cihazı ya da emülatörü yeniden başlatmalı.
Uygulama veya oyununuzun yerel kodunda bulunan özel etkinlikleri tanımlamak için
aşağıdaki adımları tamamlayın:
Şu işlemlerde kullandığınız ATrace işlevleri için fonksiyon işaretçileri tanımlayın:
aşağıdaki kodda gösterildiği gibi, uygulama veya oyununuzdaki özel etkinlikleri yakalama
snippet:
#include <android/trace.h>
#include <dlfcn.h>
void *(*ATrace_beginSection) (const char* sectionName);
void *(*ATrace_endSection) (void);
typedef void *(*fp_ATrace_beginSection) (const char* sectionName);
typedef void *(*fp_ATrace_endSection) (void);
ATrace simgelerini aşağıdaki kodda gösterildiği gibi çalışma zamanında yükleyin
snippet'i Bu işlemi genellikle bir nesne oluşturucuda gerçekleştirirsiniz.
// Retrieve a handle to libandroid.
void *lib = dlopen("libandroid.so", RTLD_NOW | RTLD_LOCAL);
// Access the native tracing functions.
if (lib != NULL) {
// Use dlsym() to prevent crashes on devices running Android 5.1
// (API level 22) or lower.
ATrace_beginSection = reinterpret_cast<fp_ATrace_beginSection>(
dlsym(lib, "ATrace_beginSection"));
ATrace_endSection = reinterpret_cast<fp_ATrace_endSection>(
dlsym(lib, "ATrace_endSection"));
}
Dikkat: Güvenlik nedeniyle,
dlopen()
yalnızca uygulama veya oyununuzun hata ayıklama sürümünde kullanılabilir.
Not: İzleme desteği sağlamak için
Android 4.3 (API düzeyi 18) yüklüyse şuradaki yöntemleri çağırmak için JNI'yi kullanabilirsiniz:
yönetilen kod,
snippet'i ekleyin.
ATrace_beginSection()
adlı kişiyi arayın ve
(sırasıyla başında ve sonunda ATrace_endSection()
)
Özel etkinliğiniz:
#include <android/trace.h>
char *customEventName = new char[32];
sprintf(customEventName, "User tapped %s button", buttonName);
ATrace_beginSection(customEventName);
// Your app or game's response to the button being pressed.
ATrace_endSection();
Not: ATrace_beginSection()
adlı kişiyi birden fazla aradığınızda
kez, ATrace_endSection()
araması en çok sona eren
yakın zamanda ATrace_beginSection()
yöntemi olarak adlandırıldı. İç içe yerleştirilmiş öğeler için
her çağrıyı doğru şekilde eşleştirdiğinizden emin olun.
ATrace_beginSection()
adlı kişiye çağrı:
ATrace_endSection()
.
Ayrıca, ATrace_beginSection()
numaralı telefonu telefonla arayamazsınız
ve başka bir ileti dizisinden sonlandırın. Her iki işlevi de aynı
ileti dizisi.
Faydalı ipuçları
Aşağıdaki ipuçları isteğe bağlı olsa da yerel reklam öğelerinizi analiz etmenizi kolaylaştırabilir
girin.
Bir fonksiyonun tamamını izleme
Çağrı yığınınızı veya işlev zamanlamanızı ayarlarken bunu faydalı bulabilirsiniz.
fonksiyonların tamamını izlemektir. Bunu yapmak için ATRACE_CALL()
makrosunu kullanabilirsiniz
ayarlamak daha kolay. Ayrıca, bu tür bir makro,
izlenen işlevin kullanılabileceği durumlar için try
ve catch
blokları
istisna bildirin veya erkenden return
adlı kişiyi arayın.
Bir işlevin tamamını izlemek üzere makro oluşturmak için aşağıdaki adımları tamamlayın:
Makroyu tanımlayın:
#define ATRACE_NAME(name) ScopedTrace ___tracer(name)
// ATRACE_CALL is an ATRACE_NAME that uses the current function name.
#define ATRACE_CALL() ATRACE_NAME(__FUNCTION__)
class ScopedTrace {
public:
inline ScopedTrace(const char *name) {
ATrace_beginSection(name);
}
inline ~ScopedTrace() {
ATrace_endSection();
}
};
İzlemek istediğiniz işlevin içindeki makroyu çağırın:
void myExpensiveFunction() {
ATRACE_CALL();
// Code that you want to trace.
}
İleti dizilerinizi adlandırın
Aşağıda gösterildiği gibi, etkinliklerinizin gerçekleştiği her bir ileti dizisine bir ad verebilirsiniz
değerini girin. Bu adım, ileti dizilerini tanımlamayı kolaylaştırır.
dönüşüm hunisinin orta kısmına yönelik stratejilere yatırım yapmanızı öneririm.
#include <pthread.h>
static void *render_scene(void *parm) {
// Code for preparing your app or game's visual components.
}
static void *load_main_menu(void *parm) {
// Code that executes your app or game's main logic.
}
void init_threads() {
pthread_t render_thread, main_thread;
pthread_create(&render_thread, NULL, render_scene, NULL);
pthread_create(&main_thread, NULL, load_main_menu, NULL);
pthread_setname_np(render_thread, "MyRenderer");
pthread_setname_np(main_thread, "MyMainMenu");
}
Sizin için önerilenler
ziyaret edin.
Bu sayfadaki içerik ve kod örnekleri, İçerik Lisansı sayfasında açıklanan lisanslara tabidir. Java ve OpenJDK, Oracle ve/veya satış ortaklarının tescilli ticari markasıdır.
Son güncelleme tarihi: 2025-07-27 UTC.
[[["Anlaması kolay","easyToUnderstand","thumb-up"],["Sorunumu çözdü","solvedMyProblem","thumb-up"],["Diğer","otherUp","thumb-up"]],[["İhtiyacım olan bilgiler yok","missingTheInformationINeed","thumb-down"],["Çok karmaşık / çok fazla adım var","tooComplicatedTooManySteps","thumb-down"],["Güncel değil","outOfDate","thumb-down"],["Çeviri sorunu","translationIssue","thumb-down"],["Örnek veya kod sorunu","samplesCodeIssue","thumb-down"],["Diğer","otherDown","thumb-down"]],["Son güncelleme tarihi: 2025-07-27 UTC."],[],[],null,["# Custom trace events in native code\n\nAndroid 6.0 (API level 23) and higher support a native tracing API, `trace.h`,\nto write trace events to the system buffer that you can then analyze using\nPerfetto or systrace. Common use cases for this API include observing the time\nthat a particular block of code takes to execute and associating a block of code\nwith undesirable system behavior.\n\n**Note:** On devices and emulators running API level 27 and lower, if there\nisn't enough memory available or the memory is too fragmented, you'll get the\nfollowing message: `Atrace could not allocate enough memory to record a trace`.\nIf this happens and your capture does not have a complete set of data, then you\nshould close background processes or restart the device or emulator.\n\nTo define custom events that occur in the native code within your app or game,\ncomplete the following steps:\n\n1. Define function pointers for the ATrace functions that you use to\n capture custom events within your app or game, as shown in the following code\n snippet:\n\n ```c++\n #include \u003candroid/trace.h\u003e\n #include \u003cdlfcn.h\u003e\n\n void *(*ATrace_beginSection) (const char* sectionName);\n void *(*ATrace_endSection) (void);\n\n typedef void *(*fp_ATrace_beginSection) (const char* sectionName);\n typedef void *(*fp_ATrace_endSection) (void);\n ```\n2. Load the ATrace symbols at runtime, as shown in the following code\n snippet. Usually, you perform this process in an object constructor.\n\n ```c++\n // Retrieve a handle to libandroid.\n void *lib = dlopen(\"libandroid.so\", RTLD_NOW | RTLD_LOCAL);\n\n // Access the native tracing functions.\n if (lib != NULL) {\n // Use dlsym() to prevent crashes on devices running Android 5.1\n // (API level 22) or lower.\n ATrace_beginSection = reinterpret_cast\u003cfp_ATrace_beginSection\u003e(\n dlsym(lib, \"ATrace_beginSection\"));\n ATrace_endSection = reinterpret_cast\u003cfp_ATrace_endSection\u003e(\n dlsym(lib, \"ATrace_endSection\"));\n }\n ```\n\n **Caution:** For security reasons, include calls to\n `dlopen()` only in the debug version of your app or game.\n\n **Note:** To provide tracing support further back to\n Android 4.3 (API level 18), you can use JNI to call the methods in\n [managed code](#managed-code) around the code shown in the\n preceding snippet.\n3. Call `ATrace_beginSection()` and\n `ATrace_endSection()` at the beginning and end, respectively, of\n your custom event:\n\n ```c++\n #include \u003candroid/trace.h\u003e\n\n char *customEventName = new char[32];\n sprintf(customEventName, \"User tapped %s button\", buttonName);\n\n ATrace_beginSection(customEventName);\n // Your app or game's response to the button being pressed.\n ATrace_endSection();\n ``` \n **Note:** When you call `ATrace_beginSection()` multiple\n times, calling `ATrace_endSection()` ends only the most\n recently called `ATrace_beginSection()` method. So, for nested\n calls, make sure that you properly match each call to\n `ATrace_beginSection()` with a call to\n `ATrace_endSection()`.\n\n Additionally, you cannot call `ATrace_beginSection()` on one\n thread and end it from another. You must call both functions from the same\n thread.\n\nConvenience tips\n================\n\nThe following tips are optional but might make it easier to analyze your native\ncode.\n\nTrace an entire function\n------------------------\n\nWhen instrumenting your call stack or function timing, you might find it useful\nto trace entire functions. You can use the `ATRACE_CALL()` macro to make this\ntype of tracing easier to set up. Furthermore, such a macro allows you to skip\ncreating `try` and `catch` blocks for cases where the traced function might\nthrow an exception or call `return` early.\n\nTo create a macro for tracing an entire function, complete the following steps:\n\n1. Define the macro:\n\n ```c++\n #define ATRACE_NAME(name) ScopedTrace ___tracer(name)\n\n // ATRACE_CALL is an ATRACE_NAME that uses the current function name.\n #define ATRACE_CALL() ATRACE_NAME(__FUNCTION__)\n\n class ScopedTrace {\n public:\n inline ScopedTrace(const char *name) {\n ATrace_beginSection(name);\n }\n\n inline ~ScopedTrace() {\n ATrace_endSection();\n }\n };\n ```\n2. Call the macro within the function that you want to trace:\n\n ```c++\n void myExpensiveFunction() {\n ATRACE_CALL();\n // Code that you want to trace.\n }\n ```\n\nName your threads\n-----------------\n\nYou can give a name to each thread in which your events occur, as demonstrated\nin the following code snippet. This step makes it easier to identify the threads\nthat belong to specific actions within your game. \n\n```c++\n#include \u003cpthread.h\u003e\n\nstatic void *render_scene(void *parm) {\n // Code for preparing your app or game's visual components.\n}\n\nstatic void *load_main_menu(void *parm) {\n // Code that executes your app or game's main logic.\n}\n\nvoid init_threads() {\n pthread_t render_thread, main_thread;\n\n pthread_create(&render_thread, NULL, render_scene, NULL);\n pthread_create(&main_thread, NULL, load_main_menu, NULL);\n\n pthread_setname_np(render_thread, \"MyRenderer\");\n pthread_setname_np(main_thread, \"MyMainMenu\");\n}\n```\n\nRecommended for you\n-------------------\n\n- Note: link text is displayed when JavaScript is off\n- [Best practices for SQLite performance](/topic/performance/sqlite-performance-best-practices)\n- [Create and measure Baseline Profiles without Macrobenchmark](/topic/performance/baselineprofiles/manually-create-measure)"]]