अगर गतिविधि अग्रभूमि में या दृश्यमान पृष्ठभूमि में है तो कैसे जांचें?


104

मेरे पास टाइमर पर एक स्प्लैश स्क्रीन है। मेरी समस्या यह है कि इससे पहले कि मैं finish()अपनी गतिविधि की जाँच करूँ कि अगली गतिविधि शुरू हो गई है क्योंकि एक सिस्टम डायलॉग बॉक्स पॉप-अप और मैं केवल चाहता हूँ finish(); एक बार उपयोगकर्ता ने संवाद बॉक्स से एक विकल्प चुना है?

मुझे पता है कि आपकी गतिविधि अग्रभूमि में है या नहीं यह देखने के तरीके पर कई सवाल हैं, लेकिन मुझे नहीं पता कि क्या यह गतिविधि के शीर्ष पर भी संवाद बॉक्स के लिए अनुमति देता है।

यहाँ समस्या है, लाल मेरी गतिविधि है जो पृष्ठभूमि में है जबकि संवाद अग्रभूमि में है:

लाल मेरी गतिविधि है जो पृष्ठभूमि में है जबकि संवाद अग्रभूमि में है

संपादित करें: मैंने केवल उपयोग नहीं करने की कोशिश की है, finish()लेकिन फिर मेरी गतिविधि अनुप्रयोगों के ढेर में वापस जा सकती है जिससे मैं बचने की कोशिश कर रहा हूं।


प्रासंगिक हो सकता है: stackoverflow.com/questions/4414171/…
jarmod

स्पष्ट करने के लिए, आप एक इरादे चयनकर्ता को लॉन्च करना चाहते हैं और उपयोगकर्ता द्वारा किसी एक विकल्प को टैप करने के बाद अपने ऐप के समाप्त होने तक प्रतीक्षा करें ()? ऐसा लगता है कि आपको Intent.createChooser () और startActivityForResult () की आवश्यकता है, जिसके बाद परिणाम प्राप्त होता है।
alanv


ProcessLifecycleOwner सबसे नया समाधान है
SR

जवाबों:


189

यह वही है जो सही समाधान के रूप में अनुशंसित है :

सही समाधान (क्रेडिट दान, कॉमन्सवेयर और नेइटइंस्टीन पर जाते हैं) अपने आवेदन की दृश्यता को ट्रैक करें। स्टोर "दृश्यता" की स्थिति किसी अन्य वर्ग में। अच्छे विकल्प अनुप्रयोग या सेवा के अपने कार्यान्वयन हैं (यदि आप सेवा से गतिविधि की दृश्यता की जांच करना चाहते हैं तो इस समाधान के कुछ रूपांतर भी हैं)।

उदाहरण लागू करें कस्टम अनुप्रयोग वर्ग (नोट isActivityVanish () स्थिर विधि):

public class MyApplication extends Application {

  public static boolean isActivityVisible() {
    return activityVisible;
  }  

  public static void activityResumed() {
    activityVisible = true;
  }

  public static void activityPaused() {
    activityVisible = false;
  }

  private static boolean activityVisible;
}

AndroidManifest.xml में अपना आवेदन वर्ग पंजीकृत करें:

<application
    android:name="your.app.package.MyApplication"
    android:icon="@drawable/icon"
    android:label="@string/app_name" >

प्रोजेक्ट में प्रत्येक गतिविधि पर onPause और onResume जोड़ें (यदि आप चाहें तो अपनी गतिविधियों के लिए एक सामान्य पूर्वज बना सकते हैं, लेकिन यदि आपकी गतिविधि पहले से ही MapActivity / ListActivity आदि से विस्तारित है, तो आपको अभी भी हाथ से निम्नलिखित लिखना होगा) :

@Override
protected void onResume() {
  super.onResume();
  MyApplication.activityResumed();
}

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

अपनी finish()विधि में, आप isActivityVisible()यह जांचने के लिए उपयोग करना चाहते हैं कि गतिविधि दिखाई दे रही है या नहीं। वहां आप यह भी देख सकते हैं कि उपयोगकर्ता ने कोई विकल्प चुना है या नहीं। जब दोनों शर्तें पूरी हों तो जारी रखें।

स्रोत में दो गलत समाधानों का भी उल्लेख है ... इसलिए ऐसा करने से बचें।

स्रोत: stackoverflow


फिनिश और स्टार्ट एक्टिविटी के बीच एक छोटा सा क्षण है और मुझे कुछ देरी और काउंटर जोड़ने की जरूरत है
sagus_helgy

28
यह मज़बूती से काम नहीं करता है। आपके पास निम्न स्थिति हो सकती है: फिर से शुरू करें बी को रोकें ए। अब एक्टिविटी अदृश्य है, जबकि आवेदन दिखाई दे रहा है। शायद आप एक दृश्यता काउंटर का उपयोग करते हैं: onCume में दिखाई देने वाला ++ और onCause में दृश्यमान मुठभेड़।
जोरिस वीमर

4
जोरिस वीमर से सहमत हैं कि यह एक मूर्खतापूर्ण समाधान नहीं है। एक परिदृश्य है अगर उपयोगकर्ता अधिसूचना पैनल नीचे खींच लिया, तो न तो onPause, onStopऔर न ही onResumeघटना कहा जाता है। तो आप क्या करते हैं अगर इन घटनाओं में से कोई भी निकाल रहे हैं ?!

1
वास्तव में, कोई भी अन्य उत्तर 100% भी काम नहीं करता है।

2
यदि ऐप में एक से अधिक गतिविधि हैं तो यह योजना काम नहीं करेगी। काउंटरों के साथ कम से कम
ruX

70

अगर एपीआई स्तर 14 या उससे ऊपर का लक्ष्यीकरण कर रहा है, तो कोई भी android.app.Application.ActivityLifecycleCallbacks का उपयोग कर सकता है

public class MyApplication extends Application implements ActivityLifecycleCallbacks {
    private static boolean isInterestingActivityVisible;

    @Override
    public void onCreate() {
        super.onCreate();

        // Register to be notified of activity state changes
        registerActivityLifecycleCallbacks(this);
        ....
    }

    public boolean isInterestingActivityVisible() {
        return isInterestingActivityVisible;
    }

    @Override
    public void onActivityResumed(Activity activity) {
        if (activity instanceof MyInterestingActivity) {
             isInterestingActivityVisible = true;
        }
    }

    @Override
    public void onActivityStopped(Activity activity) {
        if (activity instanceof MyInterestingActivity) {
             isInterestingActivityVisible = false;
        }
    }

    // Other state change callback stubs
    ....
}

18
आप इसे नियमित गतिविधि जीवनचक्र कॉलबैक (onResume (), onStop ()) में भी कर सकते हैं मैं भी कहूंगा।
डैनियल विल्सन

5
@DanielWilson मुझे लगता है कि यह ऐसा बिंदु बनाने के लिए नहीं है जहां कुछ पहले से मौजूद हो। IMHO यह स्वीकृत उत्तर होना चाहिए।
जेफरी ब्लाटमैन

26

UPD : राज्य में अपडेट किया गया Lifecycle.State.RESUMED। इसके लिए @htafoya को धन्यवाद ।

नई सहायता लाइब्रेरी 28+या AndroidX की सहायता से 2019 में आप बस उपयोग कर सकते हैं:

val isActivityInForeground = activity.lifecycle.currentState.isAtLeast(Lifecycle.State.RESUMED)

हुड के नीचे क्या हुआ, यह समझने के लिए आप डॉक्यूमेंटेशन में अधिक पढ़ सकते हैं ।


2
वास्तव में नहीं, शायद यह जगह activity.lifecycle.currentState.isAtLeast(Lifecycle.State.RESUMED) या STARTED बेहतर है । INITIALIZEDगारंटी नहीं है कि यह अग्रभूमि में है।
htafoya

11

गतिविधि :: hasWindowFocus () आपको वह बूलियन देता है जिसकी आपको आवश्यकता है।

public class ActivityForegroundChecker extends TimerTask
{
    private static final long FOREGROUND_CHECK_PERIOD = 5000;
    private static final long FIRST_DELAY             = 3000;

    private Activity m_activity;
    private Timer    m_timer;

    public ActivityForegroundChecker (Activity p_activity)
    {
        m_activity = p_activity;
    }

    @Override
    public void run()
    {
        if (m_activity.hasWindowFocus() == true) {
            // Activity is on foreground
            return;
        }
        // Activity is on background.
    }

    public void start ()
    {
        if (m_timer != null) {
            return;
        }
        m_timer = new Timer();
        m_timer.schedule(this, FIRST_DELAY, FOREGROUND_CHECK_PERIOD);
    }

    public void stop ()
    {
        if (m_timer == null) {
            return;
        }
        m_timer.cancel();
        m_timer.purge();
        m_timer = null;
    }
}

यहां आप जहां भी हैं, वहां से अपने एक्टिविटीज की विजिबिलिटी चेक करने के लिए एक उदाहरण क्लास है।

याद रखें कि यदि आप एक संवाद दिखाते हैं , तो परिणाम गलत होगा क्योंकि संवाद में मुख्य फोकस होगा। इसके अलावा अन्य यह वास्तव में आसान है और सुझाए गए समाधानों से अधिक विश्वसनीय है।


1
@Burak Day के उत्तर में संशोधन के लिए धन्यवाद, यह वास्तव में अब एक उत्तर है
Nick

यह काम नहीं करता है, मैं क्लास में बूलियन प्रॉपर्टी का उपयोग करना चाहूंगा, OnResume में सही, और ऑनपॉज में झूठी सेट ();
चैंडलर

@Chandler इस कोड के साथ आपके पास क्या सटीक मुद्दा है? भी कौन सा संस्करण?
बुरक डे

@ चाइल्डलर भी, अगर आपके पास गतिविधि जीवन चक्र विधियों तक पहुंच नहीं है तो क्या होगा। विचार करें कि आप किसी पुस्तकालय से गतिविधि की दृश्यता की जाँच कर रहे हैं।
बुरक डे

इस जवाब की असली समस्या यह है कि यह काम नहीं करता है, गतिविधि ।hasWowowFocus सच है गारंटी नहीं दे सकता गतिविधि onResume और onPause राज्य के बीच है। मैं इसके बजाय एक बूल isResumed संपत्ति को उस गतिविधि में जोड़ने की सलाह दूंगा, मैन्युअल रूप से मूल्य निर्धारित करें और एक विधि प्राप्त करें।
चांडलर

10

यही बीच क्या अंतर है onPauseऔर onStopमें वर्णित के रूप गतिविधि की घटनाओं गतिविधि वर्ग प्रलेखन

अगर मैं आपको सही तरीके से समझता हूं, तो आप क्या करना चाहते हैं, इसे समाप्त करने के लिए finish()अपनी गतिविधि से कॉल करें onStopगतिविधि जीवनचक्र डेमो ऐप की संलग्न छवि देखें । जब एक्टिविटी ए से एक्टिविटी बी लॉन्च की जाती है तो यह कैसा दिखता है। ईवेंट्स का क्रम नीचे से ऊपर तक होता है ताकि आप देख सकें कि एक्टिविटी ए onStopको कॉल करने के बाद एक्टिविटी ए onResumeकहा जाता है।

गतिविधि जीवनचक्र डेमो

यदि कोई संवाद दिखाया जाता है तो आपकी गतिविधि को पृष्ठभूमि में मंद कर दिया onPauseजाता है और उसे केवल कॉल किया जाता है।


7

दो संभावित समाधान:

1) गतिविधि जीवनचक्र कॉलबैक

एक का प्रयोग करें आवेदन कि औजार ActivityLifecycleCallbacks और आप आवेदन में घटनाओं जीवन चक्र गतिविधियों को ट्रैक करने में उपयोग करें। ध्यान दें कि एक्टिविटी लाइफ़साइकलकॉल Android Api> = 14. के लिए हैं। पिछले Android Api के लिए, आपको इसे अपनी सभी गतिविधियों के अंदर स्वयं लागू करना होगा;;

जब आप गतिविधियों को साझा / संग्रहीत करने की आवश्यकता हो तो एप्लिकेशन का उपयोग करें ।

2) चल रहे प्रक्रिया informations के लिए जाँच करें

आप इस क्लास रनिंगप्रोसेसइनफो के साथ एक रनिंग प्रोसेस की स्थिति देख सकते हैं

गतिविधि प्रबंधक के साथ चल रही प्रक्रिया सूची प्राप्त करें ।RunningRunningAppProcesses () और वांछित चल रहेAppAppProcessInfo के लिए जाँच करने के लिए परिणाम सूची को फ़िल्टर करें और इसके "महत्व" की जाँच करें



3

यह निर्धारित करने के लिए कि क्या यह पृष्ठभूमि से जागृत है, पृष्ठभूमि से रुकने और फिर से शुरू होने के बीच के समय के अंतराल का उपयोग करें

कस्टम अनुप्रयोग में

private static boolean isInBackground;
private static boolean isAwakeFromBackground;
private static final int backgroundAllowance = 10000;

public static void activityPaused() {
    isInBackground = true;
    final Handler handler = new Handler();
    handler.postDelayed(new Runnable() {
        @Override
        public void run() {
            if (isInBackground) {
                isAwakeFromBackground = true;
            }
        }
    }, backgroundAllowance);
    Log.v("activity status", "activityPaused");
}

public static void activityResumed() {
    isInBackground = false;
    if(isAwakeFromBackground){
        // do something when awake from background
        Log.v("activity status", "isAwakeFromBackground");
    }
    isAwakeFromBackground = false;
    Log.v("activity status", "activityResumed");
}

बेसएक्टिविटी क्लास में

@Override
protected void onResume() {
  super.onResume();
  MyApplication.activityResumed();
}

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

3

मुझे लगता है कि मेरे पास बेहतर समाधान है। क्योंकि आप केवल MyApplication.activityResumed () में निर्माण कर सकते हैं; हर गतिविधि के लिए एक विस्तार द्वारा

सबसे पहले आपको बनाना होगा (जैसे CyberneticTwerkGuruOrc)

public class MyApplication extends Application {

  public static boolean isActivityVisible() {
    return activityVisible;
  }  

  public static void activityResumed() {
    activityVisible = true;
  }

  public static void activityPaused() {
    activityVisible = false;
  }

  private static boolean activityVisible;
}

इसके बाद, आपको AndroidManifest.xml पर एप्लिकेशन क्लास जोड़ना होगा

<application
    android:name="your.app.package.MyApplication"
    android:icon="@drawable/icon"
    android:label="@string/app_name" >

उसके बाद, क्लास एक्टिविटीबेस बनाएं

public class ActivityBase extends Activity {

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

    @Override
    protected void onResume() {
        super.onResume();
        MyApplication.activityResumed();
    }
}

अंत में, जब आप नई गतिविधि क्रेट करते हैं, तो आप इसे गतिविधि के बजाय एक्टिविटीबेस द्वारा बढ़ा सकते हैं।

public class Main extends ActivityBase {
    @Override
    protected void onResume() {
        super.onResume();
    }

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

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

यदि आप अपने ऐप की दृश्यता की जांच करना चाहते हैं, तो आप बस कॉल कर सकते हैं

MyApplication.isActivityVisible()

क्या होगा अगर मुझे AppCombatActivity का विस्तार करने के लिए मेरी गतिविधियों की आवश्यकता है?
विंकलेर्र

2

यह Application.ActivityLifecycleCallbacks का उपयोग करके एक कुशल तरीके से इसे प्राप्त कर सकता है

उदाहरण के लिए, एक्टिविटी क्लास नाम लेने की सुविधा देता है क्योंकि प्रोफाइलएक्टिविटी यह बताती है कि यह अग्रभूमि या पृष्ठभूमि में है

पहले हमें Application Class का विस्तार करके अपना आवेदन वर्ग बनाना होगा

जो लागू होता है

Application.ActivityLifecycleCallbacks

निम्न प्रकार से मेरा एप्लिकेशन वर्ग बनें

आवेदन वर्ग

public class AppController extends Application implements Application.ActivityLifecycleCallbacks {


private boolean activityInForeground;

@Override
public void onCreate() {
    super.onCreate();

//register ActivityLifecycleCallbacks  

    registerActivityLifecycleCallbacks(this);

}



public static boolean isActivityVisible() {
    return activityVisible;
}

public static void activityResumed() {
    activityVisible = true;
}

public static void activityPaused() {
    activityVisible = false;
}

private static boolean activityVisible;

@Override
public void onActivityCreated(Activity activity, Bundle savedInstanceState) {

}

@Override
public void onActivityStarted(Activity activity) {

}

@Override
public void onActivityResumed(Activity activity) {
    //Here you can add all Activity class you need to check whether its on screen or not

    activityInForeground = activity instanceof ProfileActivity;
}

@Override
public void onActivityPaused(Activity activity) {

}

@Override
public void onActivityStopped(Activity activity) {

}

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

}

@Override
public void onActivityDestroyed(Activity activity) {

}

public boolean isActivityInForeground() {
    return activityInForeground;
}
}

उपरोक्त वर्ग में एक ओवरराइड मेथर्ड onActivityResumed of ActivityLifecycleCallbacks है

 @Override
public void onActivityResumed(Activity activity) {
    //Here you can add all Activity class you need to check whether its on screen or not

    activityInForeground = activity instanceof ProfileActivity;
}

जहां सभी गतिविधि उदाहरण जो वर्तमान में स्क्रीन पर प्रदर्शित होता है, पाया जा सकता है, बस यह जांचें कि आपकी गतिविधि स्क्रीन पर है या नहीं उपरोक्त विधि द्वारा।

अपना आवेदन वर्ग मेनिफ़ेस्ट में दर्ज करें। xml

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

मौसम की गतिविधि की जाँच करने के लिए फ़ोरग्राउंड या पृष्ठभूमि उपरोक्त समाधान के अनुसार उन स्थानों पर निम्न विधि को कॉल करें जिन्हें आपको जाँचने की आवश्यकता है

AppController applicationControl = (AppController) getApplicationContext();
    if(applicationControl.isActivityInForeground()){
     Log.d("TAG","Activity is in foreground")
    }
    else
    {
      Log.d("TAG","Activity is in background")
    }

1

यदि आप जानना चाहते हैं कि स्क्रीन पर आपके ऐप की कोई गतिविधि दिखाई दे रही है या नहीं, तो आप कुछ इस तरह कर सकते हैं:

public class MyAppActivityCallbacks implements Application.ActivityLifecycleCallbacks {
private Set<Class<Activity>> visibleActivities = new HashSet<>();

@Override
public void onActivityResumed(Activity activity) {
    visibleActivities.add((Class<Activity>) activity.getClass());
}

@Override
public void onActivityStopped(Activity activity) {
     visibleActivities.remove(activity.getClass());
}

public boolean isAnyActivityVisible() {
    return !visibleActivities.isEmpty();
}

@Override
public void onActivityCreated(Activity activity, Bundle savedInstanceState) {}

@Override
public void onActivityStarted(Activity activity) {}

@Override
public void onActivityPaused(Activity activity) {}

@Override
public void onActivityDestroyed(Activity activity) {}

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

बस इस वर्ग का एक सिंगलटन बनाएं और इसे अपने एप्लिकेशन इंस्टेंस में नीचे की तरह सेट करें:

class App extends Application{
     @Override
     public void onCreate() {
         registerActivityLifecycleCallbacks(myAppActivityCallbacks);
     }
}

तब आप हर जगह अपने MyAppActivityCallbacks उदाहरण के isAnyActivityV अदृश्य () विधि का उपयोग कर सकते हैं!


0

क्या आपने कॉल को समाप्त करने की कोशिश नहीं की, और प्रकट में "android: noHistory =" true "डाल दिया? यह गतिविधि को स्टैक पर जाने से रोक देगा।


0

मेरा कहना है कि आपका वर्कफ़्लो एक मानक Android तरीके से नहीं है। Android में, आपको finish()अपनी गतिविधि की आवश्यकता नहीं है यदि आप आशय से एक और गतिविधि खोलना चाहते हैं। उपयोगकर्ता की सुविधा के लिए, एंड्रॉइड उपयोगकर्ता को आपके ऐप में खोली गई गतिविधि से वापस जाने के लिए 'बैक' कुंजी का उपयोग करने की अनुमति देता है।

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


मैं वास्तव में नहीं जानता कि यह क्यों डाउन किया गया है। कम से कम एक कारण के रूप में एक टिप्पणी दें जो मुझे चाहिए।
ओवेन झाओ

3
"buu यह एंड्रॉइड नहीं है" जिस तरह से उत्तर थकाऊ हैं और पहले स्थान पर रखे गए प्रश्न का उत्तर नहीं देते हैं। इसके अलावा, समाप्त करने के लिए वैध कारण हैं (); - उदाहरण के लिए यह बोधगम्य है कि एक बार कार्रवाई होने के बाद यह वापस जा रहा है जो भी उद्देश्य से काम करता है। दूसरे शब्दों में, क्या आपको लगता है कि वे मज़े के लिए वहाँ () खत्म करते हैं? यह स्टैक पर रहना बिल्कुल वही है जो प्रश्न पूछने वाला बचना चाहता था
लस्सी किन्नुनेन

0

यदि आप रुके हुए हैं या फिर से शुरू किए गए हैं तो एक झंडे को बचाएं। यदि आप फिर से शुरू कर रहे हैं इसका मतलब है कि आप अग्रभूमि में हैं

boolean  isResumed = false;

@Override
public void onPause() {
  super.onPause();    
  isResumed = false;
}

@Override
public void onResume() {
  super.onResume();    
  isResumed = true;
}

private void finishIfForeground() {
  if (isResumed) {
    finish();
  }
}

0

एक संभव समाधान हो सकता है कि सिस्टम-डायलॉग दिखाते समय एक ध्वज सेट किया जाए और फिर गतिविधि जीवन-चक्र की ऑनटॉप विधि में, ध्वज की जांच करें, यदि सही हो, तो गतिविधि को समाप्त करें।

उदाहरण के लिए, यदि सिस्टम डायलॉग को कुछ बटनक्लिप द्वारा ट्रिगर किया जाता है, तो ऑनक्लिक श्रोता की तरह हो सकता है

private OnClickListener btnClickListener = new OnClickListener() {

    @Override
    public void onClick(View v) {           
        Intent intent = new Intent();
        intent.setAction(Intent.ACTION_SEND);
        intent.setType("text/plain");
        CheckActivity.this.startActivity(Intent.createChooser(intent, "Complete action using"));
        checkFlag = true;  //flag used to check

    }
};

और गतिविधि के दौरान:

@Override
protected void onStop() {
    if(checkFlag){
        finish();
    }
    super.onStop();
}

0

इसके लिए प्रसारण का उपयोग क्यों नहीं किया गया? दूसरी गतिविधि (जो की जरूरत है) इस तरह एक स्थानीय प्रसारण भेज सकते हैं:

//put this in onCreate(..) or any other lifecycle method that suits you best
//notice the string sent to the intent, it will be used to register a receiver!
Intent result = new Intent("broadcast identifier");
result.putString("some message");//this is optional
LocalBroadcastManager.getInstance(getApplicationContext()).sendBroadcast(result);

फिर छप गतिविधि के भीतर एक साधारण रिसीवर लिखें:

//this goes on the class level (like a class/instance variable, not in a method) of your splash activity:
private BroadcastReceiver receiver = new BroadcastReceiver() {
    @Override
    public void onReceive(Context context, Intent intent) {
        //kill activity here!!!
        //mission accomplished!
    }
};

और अपनी दूसरी गतिविधि से प्रसारण सुनने के लिए LocalBroadcastManager के साथ अपना नया रिसीवर पंजीकृत करें:

//notice the string sent to the intent filter, this is where you tell the BroadcastManager which broadcasts you want to listen to!
LocalBroadcastManager.getInstance(getApplicationContext()).registerReceiver(receiver, new IntentFilter("broadcast identifier"));

ध्यान दें कि आप "प्रसारण पहचानकर्ता" स्ट्रिंग के लिए एक निरंतर या एक स्ट्रिंग संसाधन का उपयोग कर सकते हैं।


बेहतर सुरक्षा विज्ञापन दक्षता के लिए LocalBroadcastManagerयहां उपयोग करें
अलेक्जेंडर फार्बर

0

यदि आप अपने finish()ऐप के स्टैक (कार्य) में शुरू करने के लिए नए ऐप से बचने के लिए उपयोग करते हैं, तो आप नए एप्लिकेशन को शुरू करते Intent.FLAG_ACTIVITY_NEW_TASKसमय, ध्वज का उपयोग कर सकते हैं और बिल्कुल भी कॉल न करें finish()प्रलेखन के अनुसार , यह "लॉन्चर" शैली के व्यवहार को लागू करने के लिए इस्तेमाल किया जाने वाला झंडा है।

// just add this line before you start an activity
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);

0

ए के अंदर इन विधियों का उपयोग करें Activity

isDestroyed()

Api 17
रिटर्न्स में जोड़ा गया है यदि एक्टिविटी पर अंतिम onDestroy () कॉल किया गया है, तो यह उदाहरण अब मृत है।

isFinishing()

Api 1 में जोड़ा गया है
यह देखने के लिए कि क्या यह गतिविधि समाप्त होने की प्रक्रिया में है, या तो क्योंकि आपने इस पर फिनिश () कहा है या किसी और ने अनुरोध किया है कि यह समाप्त हो गया है। यह अक्सर onPause () में यह निर्धारित करने के लिए उपयोग किया जाता है कि गतिविधि बस रुक रही है या पूरी तरह से खत्म हो रही है।


से मेमोरी लीक प्रलेखन

AsyncTaskहोस्ट Activity(या Fragment) के लिए एक मजबूत संदर्भ कैप्चर करना एक सामान्य गलती है :

class MyActivity extends Activity {
  private AsyncTask<Void, Void, Void> myTask = new AsyncTask<Void, Void, Void>() {
    // Don't do this! Inner classes implicitly keep a pointer to their
    // parent, which in this case is the Activity!
  }
}

यह एक समस्या है क्योंकि AsyncTaskमाता-पिता को आसानी से समझा जा सकता है Activity, उदाहरण के लिए यदि कार्य चल रहा है तो कॉन्फ़िगरेशन परिवर्तन होता है।

ऐसा करने का सही तरीका यह है कि आप अपने कार्य को एक staticवर्ग बना लें , जो अभिभावक को पकड़ नहीं पाता है, और मेजबान को कमजोर संदर्भ देता है Activity:

class MyActivity extends Activity {
  static class MyTask extends AsyncTask<Void, Void, Void> {
    // Weak references will still allow the Activity to be garbage-collected
    private final WeakReference<MyActivity> weakActivity;

    MyTask(MyActivity myActivity) {
      this.weakActivity = new WeakReference<>(myActivity);
    }

    @Override
    public Void doInBackground(Void... params) {
      // do async stuff here
    }

    @Override
    public void onPostExecute(Void result) {
      // Re-acquire a strong reference to the activity, and verify
      // that it still exists and is active.
      MyActivity activity = weakActivity.get();
      if (activity == null
          || activity.isFinishing()
          || activity.isDestroyed()) {
        // activity is no longer valid, don't do anything!
        return;
      }

      // The activity is still valid, do main-thread stuff here
    }
  }
}

0

यहाँ Applicationकक्षा का उपयोग करके एक समाधान दिया गया है ।

public class AppSingleton extends Application implements Application.ActivityLifecycleCallbacks {

private WeakReference<Context> foregroundActivity;


@Override
public void onActivityResumed(Activity activity) {
    foregroundActivity=new WeakReference<Context>(activity);
}

@Override
public void onActivityPaused(Activity activity) {
    String class_name_activity=activity.getClass().getCanonicalName();
    if (foregroundActivity != null && 
            foregroundActivity.get().getClass().getCanonicalName().equals(class_name_activity)) {
        foregroundActivity = null;
    }
}

//............................

public boolean isOnForeground(@NonNull Context activity_cntxt) {
    return isOnForeground(activity_cntxt.getClass().getCanonicalName());
}

public boolean isOnForeground(@NonNull String activity_canonical_name) {
    if (foregroundActivity != null && foregroundActivity.get() != null) {
        return foregroundActivity.get().getClass().getCanonicalName().equals(activity_canonical_name);
    }
    return false;
}
}

आप बस इसे इस प्रकार उपयोग कर सकते हैं,

((AppSingleton)context.getApplicationContext()).isOnForeground(context_activity);

यदि आपके पास आवश्यक गतिविधि का संदर्भ है या गतिविधि के विहित नाम का उपयोग करके, आप यह पता लगा सकते हैं कि यह अग्रभूमि में है या नहीं। यह समाधान मूर्खतापूर्ण नहीं हो सकता है। इसलिए आपकी टिप्पणियों का वास्तव में स्वागत है।


0

मुझे नहीं पता कि किसी ने साझाकरण के बारे में बात क्यों नहीं की, गतिविधि ए के लिए, इस तरह एक साझाकरण सेट करना (उदाहरण के लिए ऑनपॉज़ ()):

SharedPreferences pref = context.getSharedPreferences(SHARED_PREF, 0);
SharedPreferences.Editor editor = pref.edit();
editor.putBoolean("is_activity_paused_a", true);
editor.commit();

मुझे लगता है कि यह गतिविधियों को ट्रैक करने का विश्वसनीय तरीका है।


0

Activity.onWindowFocusChanged(boolean hasFocus)यहाँ उपयोगी होगा ? यही कारण है, के साथ साथ एक वर्ग स्तर के झंडा, की तरह कुछ isFocusedहै किonWindowFocusChanged सेट आपकी गतिविधि के किसी भी बिंदु पर यह बताने का एक आसान तरीका होगा वह केंद्रित है या नहीं। डॉक्स पढ़ने से, ऐसा लगता है कि यह किसी भी स्थिति में "झूठे" को ठीक से सेट करेगा जहां गतिविधि सीधे भौतिक "अग्रभूमि" में नहीं है, जैसे कि एक संवाद प्रदर्शित किया जा रहा है या अधिसूचना ट्रे नीचे खींची गई है।

उदाहरण:

boolean isFocused;
@Override
void onWindowFocusChanged (boolean hasFocus) {
    super.onWindowFocusChanged(hasFocus);
    isFocused = hasFocus;
}

void someMethod() {
    if (isFocused) {
        // The activity is the foremost object on the screen
    } else {
        // The activity is obscured or otherwise not visible
    }
}

0

यदि आप EventBus का उपयोग कर रहे हैं , तो इसे एक विधि के रूप में कहा जाता है, hasSubscriberForEventजिसका उपयोग यह जांचने के लिए किया जा सकता है कि क्या कोई Activityफ़ोकस है।


-3

मैं जैसे करता था,

यदि गतिविधि अग्रभूमि में नहीं है

getIntent ()

अशक्त हो जाएगा। : = पी

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