42

मुझे wakelock के बारे में सवाल है। नीचे दिखाए गए मामलों में, एंड्रॉइड ओएस रिलीज वाकेलॉक (PARTIAL_WAKE_LOCK यदि आपको निर्दिष्ट करने की आवश्यकता है) को रोकने के लिए wakelock को छोड़ दिया गया था और बिजली बंद करने तक (बैटरी नहीं) तक बैटरी बर्बाद कर रहा था।क्या एंड्रॉइड ओएस एक वॉकलॉक जारी करता है यदि ऐप या सेवा को मार दिया जाता है?

केस 1-एक:
अनुप्रयोग wakelock (/ ओ टाइमआउट विकल्प डब्ल्यू) अपने धागे में से एक में (कृपया लगता है कि यह इस मामले में उचित है) का अधिग्रहण किया गया है और यह wakelock जारी करने के लिए जब गंभीर कार्य था डिजाइन किया गया था ख़त्म होना। ऐप को टास्कमैनगर या कुख्यात टास्ककिल्लर द्वारा मारा जा सकता है, और ऐप के पास थ्रेड रिलीज वाकेलॉक देने का कोई मौका नहीं है। उस वाकेलॉक का क्या होता है?

केस 1-बी:
(। अगर मामला 1-एक का जवाब है "हाँ, चिंता मत करो", तो इस मामले को अनदेखा करें) जैसा भी मामला 1-एक लेकिन एप्लिकेशन ही दे दी है टाइमआउट विकल्प wakelock करने के लिए, 3 सेकंड कहते हैं। क्या यह टाइमआउट विकल्प मान्य रखा गया है?

मामला 2-एक:
कृपया कल्पना एक सेवा है जो (ब्रॉडकास्ट रिसीवर के माध्यम से) AlarmManager द्वारा शुरू किया गया है और सेवा एक wakelock (w/ओ टाइमआउट विकल्प) हासिल कर ली है। यह सेवा कमजोर-अधिग्रहित-न्यूनतम न्यूनतम बनाने के लिए डिज़ाइन की गई है। लेकिन दुर्भाग्यवश, एंड्रॉइड ओएस ने मेमोरी क्रंच के कारण मारने के लिए इस सेवा को चुना। (मुझे नहीं पता कि क्या वाकेलॉक अधिग्रहित होने पर ओएस सेवा नहीं मार पाएगा, लेकिन मुझे लगता है कि ओएस परवाह नहीं है। लेकिन मुझे उम्मीद है कि ओएस बाद में वाकेलॉक जारी करेगा।) उस वाकेलॉक का क्या होता है?

केस 2-बी:
(। अगर मामला 2-एक का जवाब है "हाँ, चिंता मत करो", तो इस मामले को अनदेखा करें) जैसा भी मामला 2-एक लेकिन सेवा ही दे दी है टाइमआउट विकल्प wakelock करने के लिए, 3 सेकंड कहते हैं। क्या यह टाइमआउट विकल्प मान्य रखा गया है?

उत्तर

43

Wakelock कार्यान्वयन अवलोकन

हम pm.newWakeLock का उपयोग करते हैं एक नया wakelock बनाने के लिए, PowerManager बस एक नया Wakelock वस्तु और रिटर्न पैदा करता है। WakeLock ऑब्जेक्ट एक बाइंडर ऑब्जेक्ट नहीं है, इसलिए इसे एकाधिक प्रक्रियाओं के माध्यम से उपयोग नहीं किया जा सकता है। हालांकि, उस वेकलॉक ऑब्जेक्ट में, इसमें एमटीकेन नामक एक बाइंडर ऑब्जेक्ट होता है।

WakeLock(int flags, String tag) { 
     mFlags = flags; 
     mTag = tag; 
     mToken = new Binder(); 
    } 

तो जब आप अधिग्रहण या इस Wakelock वस्तु पर जारी कहते हैं, यह वास्तव में PowerManagerService है कि टोकन गुजरता है। कैसे काम करता है PowerManagerService जब प्राप्त या एक wakelock रिहा आप अपने सवाल का जवाब में मदद मिलेगी में

private void acquireLocked() { 
     if (!mRefCounted || mCount++ == 0) { 
      mHandler.removeCallbacks(mReleaser); 
      try { 
       mService.acquireWakeLock(mToken, mFlags, mTag, mWorkSource); 
      } catch (RemoteException e) { 
      } 
      mHeld = true; 
     } 
    } 

देखो।

void acquireWakeLockInternal(IBinder lock, int flags, String tag, WorkSource ws, 
     int uid, int pid) { 
    synchronized (mLock) { 
     ... 
     WakeLock wakeLock; 
     int index = findWakeLockIndexLocked(lock); 
     if (index >= 0) { 
      ... 
      // Update existing wake lock. This shouldn't happen but is harmless. 
      ... 
     } else { 
      wakeLock = new WakeLock(lock, flags, tag, ws, uid, pid); 
      try { 
       lock.linkToDeath(wakeLock, 0); 
      } catch (RemoteException ex) { 
       throw new IllegalArgumentException("Wake lock is already dead."); 
      } 
      notifyWakeLockAcquiredLocked(wakeLock); 
      mWakeLocks.add(wakeLock); 
     } 
     ... 
    } 
    ... 
} 

मुख्य विवरण lock.linkToDeath(wakeLock, 0); है। वह lock बिल्कुल एमओकेन है जिसे हमने पहले उल्लेख किया था। यदि यह बाइंडर चला जाता है तो यह विधि प्राप्तकर्ता के लिए प्राप्तकर्ता (wakeLock) पंजीकृत करती है।यदि यह बाइंडर ऑब्जेक्ट अप्रत्याशित रूप से चला जाता है (आमतौर पर क्योंकि इसकी होस्टिंग प्रक्रिया मारे जा चुकी है), तो प्राप्तकर्ता पर binderDied विधि कॉल की जाएगी।

ध्यान दें कि PowerManagerService में वेक लॉक PowerManager में वेक लॉक से अलग है, यह IBinder.DeathRecipient का कार्यान्वयन है। तो इसकी binderDied विधि देखें।

@Override 
    public void binderDied() { 
     PowerManagerService.this.handleWakeLockDeath(this); 
    } 

handleWakeLockDeath उस wakelock को जारी करेगा।

private void handleWakeLockDeath(WakeLock wakeLock) { 
    synchronized (mLock) { 
     ... 
     int index = mWakeLocks.indexOf(wakeLock); 
     if (index < 0) { 
      return; 
     } 

     mWakeLocks.remove(index); 
     notifyWakeLockReleasedLocked(wakeLock); 

     applyWakeLockFlagsOnReleaseLocked(wakeLock); 
     mDirty |= DIRTY_WAKE_LOCKS; 
     updatePowerStateLocked(); 
    } 
} 

तो मुझे लगता है कि आपके प्रश्न में दोनों मामलों में, जवाब चिंता नहीं है। कम से कम एंड्रॉइड 4.2 (जहां से कोड आता है) में, यह सच है। इसके अलावा, PowerManager में वेक लॉक क्लास पर एक अंतिम विधि है, लेकिन यह आपके प्रश्न की कुंजी नहीं है।

+4

इस 2 साल के पुराने प्रश्न के आपके विस्तृत, स्पष्ट उत्तर के लिए धन्यवाद। आपका जवाब निश्चित रूप से मेरे सहित कई डेवलपर्स की सहायता करता है। – Tomcat

+1

खुशी के साथ, मुझे नहीं पता कि यह पुराना सवाल दिलचस्प क्यों क्रमबद्ध प्रश्न सूची के पहले स्थान पर पहुंचा। @Tomcat – StarPinkER

6

मुझे लगता है कि (मुझे यह निश्चित रूप से पता नहीं है) एंड्रॉइड सिस्टम मारे गए प्रक्रियाओं के लिए wakelocks नहीं रखता है। सबसे अधिक संभावना है कि जब यह सिगकिल के साथ एक प्रक्रिया को मारता है तो यह उस प्रक्रिया द्वारा आयोजित किसी भी वाकेलॉक्स को भी हटा देता है।

अन्यथा, जैसा कि आप कहते हैं, क्रैश से फोन हमेशा जाग रहा है, जिसे मैंने नहीं देखा है।

+0

यह मेरे लिए उचित लगता है। मुझे लगता है की आप सही हो। मुझे आशा है कि एसडीके स्पष्ट रूप से इस व्यवहार का वर्णन करेगा। – Tomcat

+0

मुझे वैकेलॉक के लिए टाइमआउट भी मिला है [लिंक] http://code.google.com/p/android/issues/detail?id=14184 ताकि हम इसे कुशल तरीके से उपयोग नहीं कर सकें। (मैंने इसे OS2.2 के साथ करने की कोशिश की और असफल रहा, फिर Google ने उस लिंक का नेतृत्व किया।) – Tomcat

+1

एक साधारण परीक्षण एक ऐसा एप्लिकेशन बनाना होगा जो वॉकलॉक पर रखरखाव स्क्रीन सेट करता है, उसके बाद ऐप में एक बटन है जो जानबूझकर एफसी का कारण बनता है। फिर बस प्रतीक्षा करें और देखें कि स्क्रीन बंद हो गई है या नहीं। –