एंड्रॉइड में वर्तमान अग्रभूमि गतिविधि संदर्भ कैसे प्राप्त करें?


171

जब भी मेरे प्रसारण को निष्पादित किया जाता है तो मैं अग्रभूमि गतिविधि के प्रति सतर्क दिखाना चाहता हूं।


जहां से आप गतिविधि का संदर्भ प्राप्त करना चाहते हैं। क्या यह उर ऐप गतिविधि या अन्य अनुप्रयोग होगा।
AAnkit

यह एक ऐप गतिविधि है। मैंने ब्रॉडकास्टर ऑनरेक्टिव () फंक्शन पर अलर्ट डायलॉग कोडिंग किया है।
दीपाली

एक एप्लिकेशन गतिविधि! क्या यह आपका ऐप है ?? और आप ऐसा क्यों चाहते हैं, इसका कोई कारण हो सकता है, उसी के लिए कोई विकल्प हो सकता है
AAnkit

मैं अपनी अग्रभूमि गतिविधि पर अलर्ट दिखाना चाहता हूं। बिना किसी संदर्भ के अग्रभूमि गतिविधि के प्रति सतर्कता दिखाने का उनका कोई अन्य तरीका है।
दीपाली

1
onreceive only u get COntext in a param के रूप में, आप संदर्भ कह सकते हैं
।getApplicationContext

जवाबों:


39

यह जानते हुए कि ActivityManager का प्रबंधन करता है गतिविधि है, तो हम से जानकारी हासिल कर सकते हैं ActivityManager । हमें वर्तमान अग्रभूमि चल गतिविधि मिलती है

ActivityManager am = (ActivityManager)context.getSystemService(Context.ACTIVITY_SERVICE);
ComponentName cn = am.getRunningTasks(1).get(0).topActivity;

UPDATE 2018/10/03
getRunningTasks () का मूल्यांकन किया गया है। नीचे दिए गए समाधान देखें।

इस विधि को एपीआई स्तर 21 में पदावनत किया गया था। बिल्ड.VERSION_CODES.LOLLIPOP के रूप में, यह विधि अब तीसरे पक्ष के अनुप्रयोगों के लिए उपलब्ध नहीं है: दस्तावेज़-केंद्रित पुनरावृत्तियों की शुरूआत का अर्थ है कि यह व्यक्ति की जानकारी कॉलर को लीक कर सकता है। पीछे की संगतता के लिए, यह अभी भी अपने डेटा का एक छोटा सबसेट लौटाएगा: कम से कम कॉलर के स्वयं के कार्य, और संभवतः घर जैसे कुछ अन्य कार्य जो संवेदनशील नहीं होने के लिए जाने जाते हैं।


16
ऐसा मत सोचो कि मार्टिन, एसडीआर की मदद से getRunningTasks "नोट: यह विधि केवल डिबगिंग और कार्य प्रबंधन उपयोगकर्ता इंटरफ़ेस को प्रस्तुत करने के लिए है। इसे किसी अनुप्रयोग में मुख्य तर्क के लिए उपयोग नहीं किया जाना चाहिए"
ruhalde

3
जाहिरा तौर पर यह केवल एंड्रॉइड 5 / लॉलीपॉप में चलने वाले कार्यों के एक सीमित उपसमूह का समर्थन करता है।
सैम

7
ActivityManager.getRunningTasks () के लिए प्रलेखन "इस विधि को एपीआई स्तर 21 में पदावनत किया गया था"।
मार्कशीट

210

( नोट: एपीआई 14 में एक आधिकारिक एपीआई जोड़ा गया था: इस उत्तर को देखें https://stackoverflow.com/a/29786451/11973333 )

जवाब का उपयोग न करें (waqas716) उत्तर।

गतिविधि के स्थिर संदर्भ के कारण आपको मेमोरी लीक की समस्या होगी। अधिक विवरण के लिए निम्न लिंक देखें http://android-developers.blogspot.fr/2009/01/avoiding-memory-leaks.html

इससे बचने के लिए, आपको गतिविधियों के संदर्भों का प्रबंधन करना चाहिए। मैनिफ़ेस्ट फ़ाइल में एप्लिकेशन का नाम जोड़ें:

<application
    android:name=".MyApp"
    ....
 </application>

आपका आवेदन वर्ग:

  public class MyApp extends Application {
        public void onCreate() {
              super.onCreate();
        }

        private Activity mCurrentActivity = null;
        public Activity getCurrentActivity(){
              return mCurrentActivity;
        }
        public void setCurrentActivity(Activity mCurrentActivity){
              this.mCurrentActivity = mCurrentActivity;
        }
  }

एक नई गतिविधि बनाएँ:

public class MyBaseActivity extends Activity {
    protected MyApp mMyApp;

    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mMyApp = (MyApp)this.getApplicationContext();
    }
    protected void onResume() {
        super.onResume();
        mMyApp.setCurrentActivity(this);
    }
    protected void onPause() {
        clearReferences();
        super.onPause();
    }
    protected void onDestroy() {        
        clearReferences();
        super.onDestroy();
    }

    private void clearReferences(){
        Activity currActivity = mMyApp.getCurrentActivity();
        if (this.equals(currActivity))
            mMyApp.setCurrentActivity(null);
    }
}

इसलिए, अब अपनी गतिविधियों के लिए गतिविधि वर्ग का विस्तार करने के बजाय, बस MyBaseActivity का विस्तार करें। अब, आप आवेदन या गतिविधि संदर्भ से अपनी वर्तमान गतिविधि को इस तरह प्राप्त कर सकते हैं:

Activity currentActivity = ((MyApp)context.getApplicationContext()).getCurrentActivity();

9
आप केवल WeakReference का उपयोग कर सकते हैं और कम कोड के साथ समान परिणाम प्राप्त कर सकते हैं।
नाचो कोलोमा

5
@ नाचो मैं WeakReferencesएंड्रॉइड में उपयोग करने के लिए कभी भी पुनर्संयोजन नहीं होगा जीसी उन्हें तेजी से इकट्ठा करता है फिर आप सोचते हैं।
rekire

4
@MaximKorobov हाँ यदि आप onCreate () से फिनिश () कॉल करते हैं तो यह संभव है, यदि आप किसी अन्य गतिविधि को लॉन्च करने के लिए अपनी गतिविधि का उपयोग करते हैं और इसे रोकते हैं। इस परिदृश्य में यह onPause () और onStoo () को छोड़ देता है। नीचे का नोट देखें: developer.android.com/training/basics/activity-lifecycle/…
Rodrigo Leitão

2
@rekire @NachoColoma का उपयोग WeakReferenceकैशिंग के लिए करने की सलाह नहीं दी जाती है, यह कैशिंग नहीं है, यह mCurrentActivityइच्छाशक्ति का केवल तभी संदर्भ होगा जब यह जीवित हो इसलिए शीर्ष पर WeakReferenceरहते हुए कभी भी एकत्र नहीं किया जाएगा Activity। हालाँकि जो @NachoColoma का सुझाव गलत है, क्योंकि WeakReferenceयदि अभी तक वेरिएबल क्लियर नहीं किया गया है, तो एक गैर- रेज़्यूमे (जीवित / शीर्ष पर नहीं) गतिविधि को संदर्भित कर सकता है!
ट्वीस्टेरोब

14
एंड्रॉइड एपीआई स्तर 14 से शुरू करना संभव होना चाहिए Application .ActivityLifecycleCallbacks, जो अधिक केंद्रीय होगा और आपको अपनी सभी गतिविधियों में कोई प्रबंधन कोड नहीं जोड़ना होगा। इसके अलावा developer.android.com/reference/android/app/…
Filou

68

मैं @ जेज़्डी के उत्तर के शीर्ष पर विस्तार करता हूं।

प्रत्येक गतिविधियों में, Applicationमैनुअल कोडिंग के साथ खुद को "पंजीकृत" करने के बजाय , हम निम्न एपीआई का उपयोग 14 के स्तर से कर सकते हैं, जिससे हमें कम मैनुअल कोडिंग के साथ समान उद्देश्य प्राप्त करने में मदद मिल सके।

public void registerActivityLifecycleCallbacks (Application.ActivityLifecycleCallbacks callback)

http://developer.android.com/reference/android/app/Application.html#registerActivityLifecycleCallbacks%28android.app.Application.ActivityLifecycleCallbacks%29

में Application.ActivityLifecycleCallbacks, आप इसे Activity"संलग्न" या "अलग" कर सकते हैं Application

हालाँकि, यह तकनीक केवल एपीआई स्तर 14 के बाद से उपलब्ध है।


1
अन्य सभी उत्तरों के साथ क्या हो रहा है? स्पष्ट रूप से यह इस उद्देश्य के लिए एपीआई बनाया गया है। शुक्रिया, चोक यान चेंग
माइकल बुशे

2
@MichaelBushe - 2012 में, जब अन्य उत्तर लिखे गए थे, एपीआई स्तर 14 के आधार पर हर डिवाइस पर भरोसा करने के लिए कुछ नहीं था, यह देखते हुए कि एपीआई केवल हाल ही में जारी किया गया था (अक्टूबर 2011)।
टूलमेकरसैट

4
इस दृष्टिकोण का उपयोग करने का तरीका दिखाते हुए एक उत्तर मिला: stackoverflow.com/a/11082332/199364 लाभ यह है कि गतिविधियों को स्वयं करने के लिए कुछ भी करने की आवश्यकता नहीं है ; कोड आपके सभी कस्टम कॉलबैक क्लास में है। आप बस एक वर्ग बनाते हैं implements Application.ActivityLifecycleCallbacks, और इसे लागू करने के तरीके जोड़ते हैं। फिर उस वर्ग के कंस्ट्रक्टर (या onCreate या init या अन्य विधि जो कि उस समय चलती है जब उदाहरण सक्रिय / तैयार हो रहा है), getApplication().registerActivityLifecycleCallbacks(this);अंतिम पंक्ति के रूप में रखा जाता है।
टूलमेकरसैट

मुझे लगता है कि आपका जवाब सबसे अच्छा है
burulangtu

2
बहुत बढ़िया जवाब। केवल नकारात्मक पक्ष यह है कि अगर आपको वर्तमान गतिविधि के लिए अपनी कक्षा को क्वेरी करने की आवश्यकता है, तो आपको गतिविधि को कुछ जगह बचाने की आवश्यकता है। इसलिए आपको अभी भी स्मृति रिसाव से बचने और संदर्भ को शून्य करने की आवश्यकता है।
राफेल सी

56

अपडेट 2 : इसके लिए एक आधिकारिक एपि जोड़ा गया है, कृपया इसके बजाय एक्टिविटी लाइफ़साइकल कॉलबैक का उपयोग करें ।

अपडेट करें:

जैसा कि @gezdy ने बताया है, और मैं इसके लिए आभारी हूं। वर्तमान गतिविधि के लिए भी अशक्त करने के लिए संदर्भ सेट करें , केवल हर onResume को अपडेट करने के बजाय इसे मेमोरी लीक समस्या से बचने के लिए प्रत्येक गतिविधि के onDestroy पर शून्य करने के लिए सेट करें।

कुछ समय पहले मुझे उसी कार्यक्षमता की आवश्यकता थी और यहाँ विधि है कि मैंने इसे कैसे प्राप्त किया। आपकी हर गतिविधि में इन जीवन चक्र विधियों को ओवरराइड किया जाता है।

@Override
protected void onResume() {
    super.onResume();
    appConstantsObj.setCurrentActivity(this);

}

@Override
protected void onPause() {
   clearReferences();
   super.onPause();
}

@Override
protected void onDestroy() {        
   clearReferences();
   super.onDestroy();
}

private void clearReferences(){
          Activity currActivity = appConstantsObj.getCurrentActivity();
          if (this.equals(currActivity))
                appConstantsObj.setCurrentActivity(null);
}

अब अपने प्रसारण वर्ग में आप इस पर सतर्कता दिखाने के लिए वर्तमान गतिविधि तक पहुँच सकते हैं।


3
इस उत्तर को वास्तव में अधिक अप-वोट, सरल समाधान मिलना चाहिए, लेकिन शक्तिशाली जब आपके पास कक्षाएं होती हैं जिन्हें गतिविधियों में हेरफेर करने की आवश्यकता होती है, लेकिन स्वयं गतिविधियां नहीं होती हैं।
ryvianstyron

यह आपकी गतिविधि ऑब्जेक्ट के केवल एक स्थिर संदर्भ के बारे में है। आप इसे जहाँ चाहें बना सकते हैं :)। इससे कोई फर्क नहीं पड़ता।
वकास

यह आपके पिछले उत्तर के बराबर btw है। Applicationकेवल एक बार बनाया जाता है और कचरा कभी भी स्थिर चर की तरह एकत्र नहीं किया जाता है।
zapl

1
पदानुक्रम गतिविधियों के साथ समस्याएं होंगी। जब आप एक बच्चे की गतिविधि से माता-पिता के पास लौटते हैं: (1) को बच्चे का ऑनपॉज़ कहा जाता है; (२) माता-पिता की इच्छा; (3) बच्चे की onDestroy ==> वर्तमान गतिविधि शून्य होगी। आपको विधि क्लीयरेंस में उसके उदाहरण में @gezdy जैसे कुछ चेक करने चाहिए।
आर्ट्स

4
@ waqas716 मैं सुझाव देना चाहूंगा कि इसमें शर्त को सरल बनाया clearReferences()जाए (this.equals(currActivity))
naXa

51

@lockwobr अपडेट के लिए धन्यवाद

यह एपीआई संस्करण 16 में समय का 100% काम नहीं करता है, यदि आप जीथब पर कोड पढ़ते हैं तो फ़ंक्शन "currentActivityThread" किटकैट में बदल गया था, इसलिए मैं संस्करण 19ish कहना चाहता हूं, गिटब में रिलीज के लिए एपीआई संस्करण से मिलान करने के लिए कठिन प्रकार ।

करंट तक पहुंच Activityबहुत आसान है। क्या यह अच्छा होगा कि getActivityकोई अनावश्यक प्रश्नों के साथ वर्तमान गतिविधि को वापस करने वाली एक स्थिर पद्धति हो?

Activityवर्ग बहुत उपयोगी है। यह एप्लिकेशन के UI थ्रेड, व्यूज़, रिसोर्सेज और कई अन्य चीजों तक पहुंच देता है। कई तरीकों की आवश्यकता होती है Context, लेकिन पॉइंटर कैसे प्राप्त करें? यहाँ कुछ तरीके हैं:

  • ओवरराइड जीवन चक्र विधियों का उपयोग करके एप्लिकेशन की स्थिति पर नज़र रखना। आपको वर्तमान गतिविधि को एक स्थिर चर में संग्रहीत करना होगा और आपको सभी गतिविधियों के कोड तक पहुंच की आवश्यकता होगी।
  • इंस्ट्रूमेंटेशन का उपयोग करके एप्लिकेशन की स्थिति को ट्रैक करना। घोषणा में इंस्ट्रूमेंटेशन घोषित करें, इसे लागू करें और गतिविधि परिवर्तनों को ट्रैक करने के लिए अपने तरीकों का उपयोग करें। अपनी गतिविधियों में उपयोग किए जाने वाले तरीकों और कक्षाओं के लिए एक गतिविधि सूचक पास करना। कोड इंजेक्शन पुस्तकालयों में से एक का उपयोग करके सूचक को इंजेक्ट करना। ये सभी दृष्टिकोण बल्कि असुविधाजनक हैं ; सौभाग्य से, वर्तमान गतिविधि को प्राप्त करने का एक बहुत आसान तरीका है।
  • सिस्टम जैसा लगता है कि ऊपर उल्लिखित मुद्दों के बिना सभी गतिविधियों तक पहुंच की आवश्यकता है। तो, सबसे अधिक संभावना है कि केवल स्थिर कॉल का उपयोग करके गतिविधियां प्राप्त करने का एक तरीका है। मैंने grepcode.com पर एंड्रॉइड स्रोतों के माध्यम से खुदाई करने में बहुत समय बिताया, और मुझे वह मिला जो मैं ढूंढ रहा था। नामक एक वर्ग है ActivityThread। इस वर्ग की सभी गतिविधियों तक पहुँच है और, क्या बेहतर है, वर्तमान प्राप्त करने के लिए एक स्थिर तरीका है ActivityThread। केवल एक छोटी सी समस्या है - गतिविधि सूची में पैकेज पहुंच है।

प्रतिबिंब का उपयोग करके हल करना आसान:

public static Activity getActivity() {
    Class activityThreadClass = Class.forName("android.app.ActivityThread");
    Object activityThread = activityThreadClass.getMethod("currentActivityThread").invoke(null);
    Field activitiesField = activityThreadClass.getDeclaredField("mActivities");
    activitiesField.setAccessible(true);

    Map<Object, Object> activities = (Map<Object, Object>) activitiesField.get(activityThread);
    if (activities == null)
        return null;

    for (Object activityRecord : activities.values()) {
        Class activityRecordClass = activityRecord.getClass();
        Field pausedField = activityRecordClass.getDeclaredField("paused");
        pausedField.setAccessible(true);
        if (!pausedField.getBoolean(activityRecord)) {
            Field activityField = activityRecordClass.getDeclaredField("activity");
            activityField.setAccessible(true);
            Activity activity = (Activity) activityField.get(activityRecord);
            return activity;
        }
    }

    return null;
}

इस तरह की विधि का उपयोग ऐप में कहीं भी किया जा सकता है और यह सभी उल्लिखित दृष्टिकोणों की तुलना में बहुत अधिक सुविधाजनक है। इसके अलावा, ऐसा लगता है जैसे यह असुरक्षित नहीं है क्योंकि यह दिखता है। यह किसी भी नए संभावित लीक या अशक्त संकेत का परिचय नहीं देता है।

उपरोक्त कोड स्निपेट में अपवाद हैंडलिंग की कमी है और भोलेपन से माना जाता है कि पहली चलने वाली गतिविधि वह है जिसे हम खोज रहे हैं। आप कुछ अतिरिक्त चेक जोड़ना चाह सकते हैं।

ब्लॉग पोस्ट


2
किटकैट में और ऊपर mActivities HashMap नहीं है, लेकिन ArrayMap, इसलिए आपको इस पंक्ति को बदलने की आवश्यकता है: HashMap गतिविधियाँ = (HashMap) गतिविधियाँField.get (activityThread); इस तरह से देखने के लिए: ArrayMap गतिविधियाँ = (ArrayMap) गतिविधियाँField.get (activityThread);
पेलजैंड्रो

7
@ पाली स्तर दोनों एपीआई स्तरों (18 से ऊपर और नीचे) के समर्थन के लिए Mapइसके बजाय इंटरफ़ेस का उपयोग करना चाहिए HashMapया ArrayMap। मैंने @AZ_ उत्तर संपादित किया है।
यूरी कोलबिन्सिंस्की

2
यह एपीआई संस्करण 16 में समय का 100% काम नहीं करता है , यदि आप जीथब पर कोड पढ़ते हैं तो फ़ंक्शन "currentActivityThread" किटकैट में बदल गया था, इसलिए मैं संस्करण 19ish कहना चाहता हूं , गिटब में रिलीज के लिए एपीआई संस्करण से मिलान करने के लिए कठिन प्रकार ।
लॉकवॉबर

@lockwobr धन्यवाद, समाधान आप के साथ अद्यतन टिप्पणी
:)

2
प्रतिबिंब के माध्यम से आंतरिक एपीआई तक पहुंच समर्थित नहीं है और सभी उपकरणों या भविष्य में काम नहीं कर सकती है।
पे

9

मैंने कोटलिन में फॉलो किया

  1. एप्लिकेशन क्लास बनाएं
  2. निम्नानुसार एप्लिकेशन क्लास संपादित करें

    class FTApplication: MultiDexApplication() {
    override fun attachBaseContext(base: Context?) {
        super.attachBaseContext(base)
        MultiDex.install(this)
    }
    
    init {
        instance = this
    }
    
    val mFTActivityLifecycleCallbacks = FTActivityLifecycleCallbacks()
    
    override fun onCreate() {
        super.onCreate()
    
        registerActivityLifecycleCallbacks(mFTActivityLifecycleCallbacks)
    }
    
    companion object {
        private var instance: FTApplication? = null
    
        fun currentActivity(): Activity? {
    
            return instance!!.mFTActivityLifecycleCallbacks.currentActivity
        }
    }
    
     }
  3. ActivityLifecycleCallbacks वर्ग बनाएँ

    class FTActivityLifecycleCallbacks: Application.ActivityLifecycleCallbacks {
    
    var currentActivity: Activity? = null
    
    override fun onActivityPaused(activity: Activity?) {
        currentActivity = activity
    }
    
    override fun onActivityResumed(activity: Activity?) {
        currentActivity = activity
    }
    
    override fun onActivityStarted(activity: Activity?) {
        currentActivity = activity
    }
    
    override fun onActivityDestroyed(activity: Activity?) {
    }
    
    override fun onActivitySaveInstanceState(activity: Activity?, outState: Bundle?) {
    }
    
    override fun onActivityStopped(activity: Activity?) {
    }
    
    override fun onActivityCreated(activity: Activity?, savedInstanceState: Bundle?) {
        currentActivity = activity
    }
    
    }
  4. अब आप इसे किसी भी वर्ग में निम्न कॉल करके उपयोग कर सकते हैं: FTApplication.currentActivity()


5

getCurrentActivity () भी ReactContextBaseJavaModule में है।
(चूंकि यह सवाल शुरू में पूछा गया था, कई एंड्रॉइड ऐप में रिएक्टनवेटिव घटक भी है - हाइब्रिड ऐप।)

ReactNative में class ReactContext में mCurrentActivity को बनाए रखने के लिए तर्क का पूरा सेट है जो getCurrentActivity () में वापस आ जाता है।

नोट: मेरी इच्छा है कि एंड्रॉइड एप्लिकेशन क्लास में getCurrentActivity () लागू हो।


कुछ मामलों में यह प्रतिक्रिया ReactContextBaseJavaModule से शून्य है, क्या आप जानते हैं कि क्यों?
मोक्सॉर

4

मुझे कोई समाधान नहीं मिला कि हमारी टीम खुश हो जाए इसलिए हमने अपना रोल किया। हम ActivityLifecycleCallbacksवर्तमान गतिविधि का ट्रैक रखने के लिए उपयोग करते हैं और फिर एक सेवा के माध्यम से इसे उजागर करते हैं। अधिक विवरण यहां: https://stackoverflow.com/a/38650587/10793


2

पीछे की संगतता के लिए:

ComponentName cn;
ActivityManager am = (ActivityManager) getApplicationContext().getSystemService(Context.ACTIVITY_SERVICE);
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M) {
    cn = am.getAppTasks().get(0).getTaskInfo().topActivity;
} else {
    //noinspection deprecation
    cn = am.getRunningTasks(1).get(0).topActivity;
}

4
जब तक ComponentName से गतिविधि के वर्तमान उदाहरण तक पहुंचने का कोई रास्ता नहीं है, यह सवाल IMO का जवाब नहीं देता है।
nasch

@ ज्ञानचंद एक वर्ग WeakReferenceसे एक संभाल कर रख सकता है Application- जबकि यह ComponentNameनिर्धारित करना आवश्यक है कि क्या Activityचल रहे कार्य सूची में शीर्ष पर है। और अगर यह पूरी तरह से सवाल का जवाब नहीं देता है, तो स्वीकृत जवाब या तो नहीं है।
मार्टिन ज़ेटलर

मैं सहमत हूं, स्वीकृत उत्तर पूरी तरह से प्रश्न का उत्तर नहीं देता है।
19

1
topActivityकेवल Android Q
Eugen Martynov

1

व्यक्तिगत रूप से मैंने "चेओक यान चेंग" के रूप में किया था, लेकिन मैंने अपनी सभी गतिविधियों का "बैकस्टैक" करने के लिए एक "सूची" का उपयोग किया।

यदि आप जांचना चाहते हैं कि वर्तमान गतिविधि कौन सी है तो आपको सूची में अंतिम गतिविधि वर्ग प्राप्त करना होगा।

एक एप्लिकेशन बनाएं जो "एप्लिकेशन" का विस्तार करता है और यह करें:

public class MyApplication extends Application implements Application.ActivityLifecycleCallbacks,
EndSyncReceiver.IEndSyncCallback {

private List<Class> mActivitiesBackStack;
private EndSyncReceiver mReceiver;
    private Merlin mMerlin;
    private boolean isMerlinBound;
    private boolean isReceiverRegistered;

@Override
    public void onCreate() {
        super.onCreate();
        [....]
RealmHelper.initInstance();
        initMyMerlin();
        bindMerlin();
        initEndSyncReceiver();
        mActivitiesBackStack = new ArrayList<>();
    }

/* START Override ActivityLifecycleCallbacks Methods */
    @Override
    public void onActivityCreated(Activity activity, Bundle bundle) {
        mActivitiesBackStack.add(activity.getClass());
    }

    @Override
    public void onActivityStarted(Activity activity) {
        if(!isMerlinBound){
            bindMerlin();
        }
        if(!isReceiverRegistered){
            registerEndSyncReceiver();
        }
    }

    @Override
    public void onActivityResumed(Activity activity) {

    }

    @Override
    public void onActivityPaused(Activity activity) {

    }

    @Override
    public void onActivityStopped(Activity activity) {
        if(!AppUtils.isAppOnForeground(this)){
            if(isMerlinBound) {
                unbindMerlin();
            }
            if(isReceiverRegistered){
                unregisterReceiver(mReceiver);
            }
            if(RealmHelper.getInstance() != null){
                RealmHelper.getInstance().close();
                RealmHelper.getInstance().logRealmInstanceCount("AppInBackground");
                RealmHelper.setMyInstance(null);
            }
        }
    }

    @Override
    public void onActivitySaveInstanceState(Activity activity, Bundle bundle) {

    }

    @Override
    public void onActivityDestroyed(Activity activity) {
        if(mActivitiesBackStack.contains(activity.getClass())){
            mActivitiesBackStack.remove(activity.getClass());
        }
    }
    /* END Override ActivityLifecycleCallbacks Methods */

/* START Override IEndSyncCallback Methods */
    @Override
    public void onEndSync(Intent intent) {
        Constants.SyncType syncType = null;
        if(intent.hasExtra(Constants.INTENT_DATA_SYNC_TYPE)){
            syncType = (Constants.SyncType) intent.getSerializableExtra(Constants.INTENT_DATA_SYNC_TYPE);
        }
        if(syncType != null){
            checkSyncType(syncType);
        }
    }
    /* END IEndSyncCallback Methods */

private void checkSyncType(Constants.SyncType){
    [...]
    if( mActivitiesBackStack.contains(ActivityClass.class) ){
         doOperation()     }
}

}

मेरे मामले में मैंने "Application.ActivityLifecycleCallbacks" का उपयोग किया:

  • Bind / Unbind मर्लिन इंस्टेंस (ऐप खो जाने या कनेक्शन प्राप्त होने पर ईवेंट प्राप्त करने के लिए उपयोग किया जाता है, उदाहरण के लिए जब आप मोबाइल डेटा बंद करते हैं या जब आप इसे खोलते हैं)। "OnConnectivityChanged" इरादे कार्रवाई अक्षम होने के बाद यह उपयोगी है। मर्लिन के बारे में अधिक जानकारी के लिए देखें: मर्लिन जानकारी लिंक

  • जब एप्लिकेशन बंद हो जाए तो मेरा अंतिम क्षेत्र बंद करें; मैं इसे एक बेसएक्टिविटी विच के अंदर डालूंगा जो अन्य सभी गतिविधियों से बढ़ा है और जिसमें एक निजी रियलमहेलर इंस्टेंस है। REALM के बारे में अधिक जानकारी के लिए देखें: REALM INFO LINK उदाहरण के लिए मेरे पास मेरे "RealmHelper" वर्ग के अंदर एक स्थिर "RealmHelper" उदाहरण है, जो कि मेरे आवेदन "onCreate" के अंदर त्वरित है। मेरे पास एक सिंक्रनाइज़ेशन सेवा है, जिसमें मैं नया "RealmHelper" बनाता हूं क्योंकि Realm "थ्रेड-लिंक्ड" है और एक Realm इंस्टेंस एक अलग थ्रेड के अंदर काम नहीं कर सकता है। तो रियलम डॉक्युमेंटेशन का अनुसरण करने के लिए "आपको सिस्टम रिसोर्स लीक्स से बचने के लिए सभी ओपन रियलिटी इंस्टेंस को बंद करने की आवश्यकता है", इस चीज को पूरा करने के लिए मैंने "Application.ActivityLifecycleCallbacks" का उपयोग किया जैसा कि आप देख सकते हैं।

  • अंत में मेरे पास एक रिसीवर विच होता है जब मैं अपने एप्लिकेशन को सिंक्रनाइज़ करने के लिए समाप्त हो जाता हूं, तो जब सिंक अंत यह "IEndSyncCallback" "onEndSync" विधि को कॉल करेगा, जिसमें मुझे लगता है कि क्या मुझे अपने एक्टिविटीबैकस्टैक लिस्ट के अंदर एक विशिष्ट गतिविधि है क्योंकि मुझे इसकी आवश्यकता है यदि सिंक सिंक ने उन्हें अपडेट किया है, तो डेटा को अपडेट करने के लिए और मुझे ऐप सिंक के बाद दूसरों के ऑपरेशन करने की आवश्यकता हो सकती है।

बस, उम्मीद है कि यह मददगार होगा। फिर मिलते हैं :)


-1

वकास 716 द्वारा जवाब अच्छा है। मैंने कम कोड और रखरखाव की मांग के लिए एक विशिष्ट मामले के लिए एक वैकल्पिक हल बनाया।

मुझे एक विशिष्ट काम मिला जिसमें एक स्थिर विधि द्वारा अग्रभूमि में होने वाली संदिग्ध गतिविधि से एक दृश्य प्राप्त किया गया। आप सभी गतिविधियों के माध्यम से पुनरावृत्ति कर सकते हैं और जांच सकते हैं कि क्या आप मार्टिन के उत्तर से गतिविधि का नाम चाहते हैं या प्राप्त कर सकते हैं

ActivityManager am = (ActivityManager)context.getSystemService(Context.ACTIVITY_SERVICE);
ComponentName cn = am.getRunningTasks(1).get(0).topActivity; 

मैं तब जांचता हूं कि क्या दृश्य अशक्त नहीं है और getContext () के माध्यम से संदर्भ प्राप्त करें।

View v = SuspectedActivity.get_view();

if(v != null)
{
    // an example for using this context for something not 
    // permissible in global application context. 
    v.getContext().startActivity(new Intent("rubberduck.com.activities.SomeOtherActivity"));
}

मैं इसी तरह के मुद्दे की तलाश कर रहा हूँ यहाँ stackoverflow.com/questions/22788289/… हमें "संदिग्धता" कैसे मिलती है? क्या यह देशी एपीआई है?
स्टेला

2
के लिए डॉक्स से BUT getRunningTasks: डेवलपर."Note: this method is only intended for debugging and presenting task management user interfaces. This should never be used for core logic in an application, ..."
android.com/reference/android/app/…

3
ActivityManager.getRunningTasks () के लिए दस्तावेज़ीकरण अब कहता है कि "इस विधि को एपीआई स्तर 21 में पदावनत किया गया था"।
मार्कशीट

-2

मुझे कोई अन्य उत्तर पसंद नहीं है। एक्टिविटी मैनजर का उपयोग वर्तमान गतिविधि को प्राप्त करने के लिए किया जाना नहीं है। सुपर क्लासिंग और ऑनडेस्ट्रॉय पर निर्भर करता है भी नाजुक और सबसे अच्छा डिजाइन नहीं है।

ईमानदारी से, मैं अब तक का सबसे अच्छा काम कर रहा हूं, बस अपने एप्लिकेशन में एक एनम को बनाए रख रहा हूं, जो एक गतिविधि बनने पर सेट हो जाता है।

एक और सिफारिश यदि संभव हो तो कई गतिविधियों का उपयोग करने से दूर रहना चाहिए। यह या तो टुकड़ों का उपयोग करके किया जा सकता है, या मेरी प्राथमिकता में कस्टम दृश्य।


1
एक एनम यह वर्तमान अग्रगामी गतिविधि उदाहरण का पता लगाने में कैसे मदद करता है?
टूलमेकरसैट

"सुपर क्लासिंग और ऑनडेस्ट्रो पर निर्भर करता है भी नाजुक है" वह नाजुक कैसे है?
टूलमेकरसेव

-3

एक सरल समाधान एक एकल प्रबंधक वर्ग बनाना है, जिसमें आप एक या एक से अधिक गतिविधियों के संदर्भ में स्टोर कर सकते हैं, या कुछ और जिसे आप पूरे ऐप तक पहुंच चाहते हैं।

कॉल UberManager.getInstance().setMainActivity( activity );मुख्य गतिविधि के ऑनक्रीट में ।

कॉल UberManager.getInstance().getMainActivity();इसे पुनः प्राप्त करने के लिए अपने ऐप में कहीं भी । (मैं इसका उपयोग गैर यूआई थ्रेड से टोस्ट का उपयोग करने में सक्षम होने के लिए कर रहा हूं।)

सुनिश्चित करें कि UberManager.getInstance().cleanup();जब आपका ऐप नष्ट हो रहा हो तो आप एक कॉल जोड़ें ।

import android.app.Activity;

public class UberManager
{
    private static UberManager instance = new UberManager();

    private Activity mainActivity = null;

    private UberManager()
    {

    }

    public static UberManager getInstance()
    {
        return instance;
    }

    public void setMainActivity( Activity mainActivity )
    {
        this.mainActivity = mainActivity;
    }

    public Activity getMainActivity()
    {
        return mainActivity;
    }

    public void cleanup()
    {
        mainActivity = null;
    }
}

यह घुसपैठ है और सभी गतिविधियों में बदलाव की आवश्यकता है। AZ_ द्वारा जवाब बहुत codebase में अन्य परिवर्तन की आवश्यकता के बिना बेहतर रूप में यह पूरी तरह से स्थानीय है और स्टैंडअलोन है।
मार्कशीट

-7

मुझे 3 साल देर हो गई है, लेकिन मैं किसी भी तरह से इस मामले में जवाब दूंगा जैसे कि मैंने ऐसा किया।

मैंने इसे केवल इसका उपयोग करके हल किया है:

    if (getIntent().toString().contains("MainActivity")) {
        // Do stuff if the current activity is MainActivity
    }

ध्यान दें कि "getIntent () .String ()" में आपके पैकेज का नाम और आपकी गतिविधि के किसी भी इरादे वाले फ़िल्टर जैसे अन्य पाठ का एक समूह शामिल है। तकनीकी रूप से हम वर्तमान इरादे की जाँच कर रहे हैं, गतिविधि की नहीं, बल्कि परिणाम वही है। जैसे कि Log.d ("test", getIntent () .String ()) का उपयोग करें; यदि आप सभी पाठ देखना चाहते हैं। यह सॉल्यूशन थोड़ा हैकी है, लेकिन यह आपके कोड में बहुत क्लीनर है और कार्यक्षमता समान है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.