नेटिव कोड में कस्टम ट्रेस इवेंट

Android 6.0 (एपीआई लेवल 23) और उसके बाद के वर्शन में, नेटिव ट्रेसिंग एपीआई trace.h, का इस्तेमाल करके सिस्टम बफ़र में ट्रेस इवेंट लिखें. बाद में इनका इस्तेमाल करके विश्लेषण किया जा सकता है परफ़ेटो या सिस्ट्रेस. इस एपीआई के सामान्य इस्तेमाल के उदाहरणों में, समय के बारे में जानकारी शामिल है जिसे कोड के एक ब्लॉक को एक्ज़ीक्यूट करने और जोड़ने के लिए इस्तेमाल किया जाता है असामान्य तरीके से काम नहीं करता है.

ध्यान दें: एपीआई लेवल 27 और उससे पहले के वर्शन वाले डिवाइसों और एम्युलेटर पर, अगर वहां पर्याप्त मेमोरी उपलब्ध नहीं है या मेमोरी बहुत फ़्रैगमेंट की गई है, तो आपको नीचे दिया गया मैसेज: Atrace could not allocate enough memory to record a trace. अगर ऐसा होता है और आपके कैप्चर किए गए डेटा में डेटा का पूरा सेट नहीं है, तो को बैकग्राउंड की प्रोसेस बंद करनी चाहिए या डिवाइस या एम्युलेटर को रीस्टार्ट करना चाहिए.

अपने ऐप्लिकेशन या गेम में नेटिव कोड में होने वाले कस्टम इवेंट तय करने के लिए, इन चरणों को पूरा करें:

  1. जिन ATrace फ़ंक्शन का इस्तेमाल किया जाता है उनके लिए फ़ंक्शन पॉइंटर तय करना अपने ऐप्लिकेशन या गेम में कस्टम इवेंट कैप्चर करें, जैसा कि इस कोड में दिखाया गया है 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);
    
  2. इस कोड में दिखाए गए तरीके से, रनटाइम के दौरान एट्रेस सिंबल लोड करें स्निपेट. आम तौर पर, यह प्रोसेस किसी ऑब्जेक्ट कंस्ट्रक्टर में की जाती है.

    // 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"));
    }
    

    चेतावनी: सुरक्षा वजहों से, dlopen() की वैल्यू सिर्फ़ आपके ऐप्लिकेशन या गेम के डीबग वर्शन में उपलब्ध है.

    ध्यान दें: आने वाले समय में, ट्रेस करने की सुविधा उपलब्ध कराई जा सके Android 4.3 (एपीआई लेवल 18) के साथ काम करता है, तो JNI का इस्तेमाल करके मैनेज किया जा रहा कोड पिछला स्निपेट.

  3. ATrace_beginSection() पर कॉल करें और ATrace_endSection() इसके पहले और आखिर में, आपका कस्टम इवेंट:

    #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();
    

    ध्यान दें: जब आप ATrace_beginSection() को एक से ज़्यादा कॉल करते हैं बार-बार, ATrace_endSection() को कॉल करने की सुविधा बहुत ज़्यादा बार बंद होती है हाल ही में ATrace_beginSection() तरीका कहा गया. इसलिए, नेस्ट किए गए कॉल करते हैं, तो सुनिश्चित करें कि आप इनको कॉल करने वाला ATrace_beginSection() ATrace_endSection().

    इसके अलावा, आप ATrace_beginSection() को एक नंबर पर कॉल नहीं कर सकते थ्रेड और इसे किसी दूसरी थ्रेड से खत्म करें. आपको दोनों फ़ंक्शन को एक ही से कॉल करना होगा थ्रेड.

सुविधा के बारे में सलाह

नीचे दी गई सलाह ज़रूरी नहीं है. हालांकि, इनसे आपकी साइट के पेजों का विश्लेषण करना आसान हो सकता है कोड.

पूरे फ़ंक्शन को ट्रेस करना

कॉल स्टैक या फ़ंक्शन का समय इंस्ट्रुमेंट करते समय, यह आपको काम का लग सकता है का इस्तेमाल करके, पूरे फ़ंक्शन को ट्रेस किया जा सकता है. इसे बनाने के लिए, ATRACE_CALL() मैक्रो का इस्तेमाल किया जा सकता है ट्रेस करने की प्रोसेस को आसानी से सेट अप किया जा सकता है. इसके अलावा, ऐसे मैक्रो से आपको दो अलग-अलग तरीकों से तेज़ी से उन मामलों के लिए try और catch ब्लॉक बनाया जा रहा है जहां ट्रेस किया गया फ़ंक्शन शायद कोई अपवाद दें या return को पहले कॉल करें.

पूरे फ़ंक्शन को ट्रेस करने के लिए मैक्रो बनाने के लिए, नीचे दिए गए चरणों को पूरा करें:

  1. मैक्रो निर्धारित करें:

    #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();
        }
    };
    
  2. उस फ़ंक्शन में मैक्रो को कॉल करें जिसे आप ट्रेस करना चाहते हैं:

    void myExpensiveFunction() {
      ATRACE_CALL();
      // Code that you want to trace.
    }
    

अपने थ्रेड को नाम दें

जैसा कि दिखाया गया है, आप हर उस थ्रेड को नाम दे सकते हैं जिसमें आपके इवेंट होते हैं को जोड़ना होगा. इस चरण से थ्रेड की पहचान करना आसान हो जाता है जो आपके गेम में हुई खास कार्रवाइयों से जुड़े हैं.

#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");
}