কার্যকলাপটি অগ্রভাগে বা দৃশ্যমান পটভূমিতে রয়েছে কিনা তা কীভাবে পরীক্ষা করবেন?


104

আমার একটি টাইমারটিতে স্প্ল্যাশ স্ক্রিন রয়েছে। আমার সমস্যাটি হ'ল finish()আমার ক্রিয়াকলাপের আগে আমার পরীক্ষা করে নেওয়া দরকার যে পরবর্তী ক্রিয়াকলাপটি শুরু হয়েছে কারণ একটি সিস্টেম ডায়ালগ বক্স পপ-আপ করে এবং আমি কেবল এটিই করতে চাই finish(); একবার ডায়লগ বাক্স থেকে ব্যবহারকারী কোনও বিকল্প নির্বাচন করেছেন?

আমি জানি যে কীভাবে আপনার ক্রিয়াকলাপটি অগ্রভাগে রয়েছে তা দেখার জন্য অনেক প্রশ্ন রয়েছে তবে আমি জানি না যে এটি ক্রিয়াকলাপের শীর্ষেও কথোপকথনের বাক্সগুলিতে অনুমতি দেয় কিনা।

এখানে সমস্যাটি হ'ল, লালটি আমার ক্রিয়াকলাপটি যা পটভূমিতে রয়েছে যখন ডায়লগটি অগ্রভাগে রয়েছে:

ডায়লগটি পূর্বগ্রাউন্ডে থাকাকালীন লাল আমার ক্রিয়াকলাপটি যা ব্যাকগ্রাউন্ডে রয়েছে

সম্পাদনা: আমি কেবল ব্যবহার না করে চেষ্টা করেছি finish()কিন্তু তারপরে আমার ক্রিয়াকলাপটি আমি এড়াতে চাইছি এমন অ্যাপ্লিকেশনগুলির স্তুপে ফিরে যেতে পারে।


প্রাসঙ্গিক হতে পারে: stackoverflow.com/questions/4414171/...
jarmod

স্পষ্ট করার জন্য, আপনি কোনও উদ্দেশ্য চয়নকারী চালু করতে এবং আপনার অ্যাপ্লিকেশনটি শেষ করার জন্য অপেক্ষা করতে চান () ব্যবহারকারীর পছন্দগুলির মধ্যে একটি টেপ না করা পর্যন্ত? দেখে মনে হচ্ছে আপনার ফলাফল পাওয়ার পরে আপনার ইন্টেন্ট.ক্রিয়েটচুসার () এবং স্টার্টঅ্যাক্টিভিটি ফর রিসাল্ট () ফিনিশ () এর পরে () প্রাপ্ত হবে।
অ্যালানভ


উত্তর:


189

এটিই সঠিক সমাধান হিসাবে প্রস্তাবিত :

সঠিক সমাধান (ক্রেডিটগুলি ড্যান, কমন্সওয়্যার এবং নেটিআইএনটিস্টিনিতে যায়) Activity.onPause, Activity.onResume পদ্ধতিগুলি ব্যবহার করে নিজেই আপনার অ্যাপ্লিকেশনটির দৃশ্যমানতা ট্র্যাক করুন। অন্য কিছু শ্রেণিতে "দৃশ্যমানতা" স্থিতি সঞ্চয় করুন। ভাল পছন্দগুলি হ'ল অ্যাপ্লিকেশন বা কোনও পরিষেবার নিজস্ব প্রয়োগকরণ (যদি আপনি পরিষেবা থেকে ক্রিয়াকলাপের দৃশ্যমানতা পরীক্ষা করতে চান তবে এই সমাধানের কয়েকটি ভিন্নতাও রয়েছে)।

উদাহরণ কাস্টম অ্যাপ্লিকেশন শ্রেণি প্রয়োগ করুন (ক্রিয়াকলাপটি দৃশ্যমান () স্থির পদ্ধতিটি নোট করুন):

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;
}

আপনার অ্যাপ্লিকেশন ক্লাসটি AndroidManLive.xML এ নিবন্ধ করুন:

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

প্রকল্পের প্রতিটি ক্রিয়াকলাপে অনপেজ এবং অনসূচনা যুক্ত করুন (আপনি যদি চান তবে আপনার ক্রিয়াকলাপগুলির জন্য একটি সাধারণ পূর্বপুরুষ তৈরি করতে পারেন, তবে যদি আপনার ক্রিয়াকলাপটি ইতিমধ্যে ম্যাপঅ্যাক্টিভিটি / তালিকাঅ্যাক্টিভিটি ইত্যাদি থেকে প্রসারিত হয় তবে আপনাকে এখনও হাতে লিখে নিম্নলিখিত লেখার প্রয়োজন আছে) :

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

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

আপনার finish()পদ্ধতিতে, আপনি isActivityVisible()কার্যকলাপটি দৃশ্যমান কিনা তা পরীক্ষা করতে আপনি ব্যবহার করতে চান । সেখানেও আপনি ব্যবহারকারী কোনও বিকল্প নির্বাচন করেছেন কিনা তাও পরীক্ষা করতে পারেন। উভয় শর্ত পূরণ হলে চালিয়ে যান।

উত্সটি দুটি ভুল সমাধানেরও উল্লেখ করেছে ... সুতরাং এটি করা থেকে বিরত থাকুন।

সূত্র: স্ট্যাকওভারফ্লো


সমাপ্তি এবং ক্রিয়াকলাপ শুরু করার মধ্যে একটি মুহুর্ত রয়েছে এবং আমার কিছুটা বিলম্ব এবং পাল্টা যুক্ত হওয়া দরকার
sagus_helgy

28
এটি নির্ভরযোগ্যভাবে কাজ করে না। আপনার নিম্নোক্ত পরিস্থিতি থাকতে পারে: পুনরায় জীবন শুরু করুন বি বিরতি দিন। এখন ক্রিয়াকলাপ দৃশ্যমান হলেও অ্যাপ্লিকেশনটি দৃশ্যমান false সম্ভবত আপনি একটি ভিজিবিলিটি কাউন্টার ব্যবহার করেছেন: দৃশ্যমানকাউন্টার ++ অন রিসুম এবং দৃশ্যমান কাউন্টার - অনপজেতে ause
জোরিস ওয়েইমার

4
তার সঙ্গে একমত হয়েছেন Joris Weimar স্বাগতম যে এই হল না একটি অব্যর্থ সমাধান। এক দৃশ্যকল্প হলে ব্যবহারকারী বিজ্ঞপ্তি প্যানেল নিচে টানা, তারপর তন্ন তন্ন onPause, onStopকিংবা onResumeঘটনা বলা হয়। তাহলে এই ইভেন্টগুলির কোনওটিই যদি বরখাস্ত না করা হয় তবে আপনি কি করবেন ?!

1
প্রকৃতপক্ষে, অন্য উত্তরগুলির কোনওটিই 100% কাজ করে না।

2
যদি অ্যাপের একাধিক কার্যকলাপ থাকে তবে এই স্কিমটি কাজ করবে না। কমপক্ষে কাউন্টারগুলির সাথে প্রতিস্থাপন করুন
রুশ

70

যদি 14 বা ততোধিক স্তরের এপিআই স্তরের লক্ষ্যবস্তু করা হয়, তবে কেউ অ্যান্ড্রয়েড.অ্যাপ ব্যবহার করতে পারেন App অ্যাপ্লিকেশন Lঅ্যাক্টিভিটি লাইফসাইকেলক্যালব্যাকস

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
আমি কেবল এটি বলতে চাই আপনি নিয়মিত ক্রিয়াকলাপের লাইফসাইকেল কলব্যাকস (অনারেসিউম (), অনস্টপ ()) এ করতে পারেন।
ড্যানিয়েল উইলসন

5
@ ড্যানিয়েলসিলসন আমি মনে করি যে বিষয়টি ইতিমধ্যে বিদ্যমান এমন কিছু করার জন্য একটি সিস্টেম তৈরি করা নয়। আইএমএইচও এটি গ্রহণযোগ্য উত্তর হওয়া উচিত।
জেফ্রি ব্লাটম্যান

26

ইউপিডি : স্টেটে আপডেট হয়েছে Lifecycle.State.RESUMED। তার জন্য @ htafoya ধন্যবাদ ।

2019 সালে নতুন সমর্থন লাইব্রেরি 28+বা অ্যান্ড্রয়েডএক্সের সাহায্যে আপনি সহজেই ব্যবহার করতে পারেন:

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

হুডের নীচে কী ঘটেছিল তা বুঝতে আপনি ডকুমেন্টেশনটিতে আরও পড়তে পারেন ।


2
আসলেই নয়, সম্ভবত এটি স্থাপন করা activity.lifecycle.currentState.isAtLeast(Lifecycle.State.RESUMED) বা শুরু করা ভাল । INITIALIZEDএটি অগ্রভাগে গ্যারান্টি দেয় না।
htafoya

11

ক্রিয়াকলাপ :: হ্যাঁস উইন্ডোফোকাস () আপনাকে আপনার প্রয়োজনীয় বুলিয়ান প্রদান করে।

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
@ বারাক ডে উত্তরটি সংশোধন করার জন্য আপনাকে ধন্যবাদ, এটি এখনই আসলে একটি উত্তর
নিক

এটি কাজ করে না, আমি বরং ক্লাসে একটি বুলিয়ান সম্পত্তি ব্যবহার করব, এটি অনারুমিউমে সত্য হিসাবে সেট হবে এবং অনপজ () এ মিথ্যাতে সেট হবে;
চ্যান্ডলার

@ চেন্ডার এই কোডটি নিয়ে আপনার সঠিক সমস্যাটি কী? এছাড়াও কোন সংস্করণ?
বুড়াক দিন

@ চ্যাণ্ডলার এছাড়াও, যদি আপনার ক্রিয়াকলাপের জীবনচক্র পদ্ধতিতে অ্যাক্সেস না থাকে তবে কী হবে। বিবেচনা করুন আপনি কেবল একটি লাইব্রেরি থেকে ক্রিয়াকলাপের দৃশ্যমানতা পরীক্ষা করছেন Consider
বুড়াক দিন

এই উত্তরের আসল সমস্যাটি এটি কাজ করে না, ক্রিয়াকলাপ hasঅস উইন্ডোফোকাসটি এই কাজটি অন-রিসুম এবং অনপস স্থিতির মধ্যে থাকা গ্যারান্টি দিতে পারে না। আমি বরং ক্রিয়াকলাপে একটি বোল ইসরুমিন করা সম্পত্তি যুক্ত করার পরামর্শ দিন, ম্যানুয়ালি মান সেট করুন এবং একটি গেট পদ্ধতি যুক্ত করুন।
শ্যান্ডলার

10

ক্রিয়াকলাপের ক্লাস ডকুমেন্টেশনে বর্ণিত ক্রিয়াকলাপের ইভেন্ট onPauseএবং onStopইভেন্টের মধ্যে ঠিক এটিই পার্থক্য ।

যদি আমি আপনাকে সঠিকভাবে বুঝতে পারি তবে আপনি যা করতে চান তা হ'ল এটি বন্ধ করার জন্য finish()আপনার কার্যকলাপ থেকে কল onStopক্রিয়াকলাপ জীবনচক্র ডেমো অ্যাপ্লিকেশনটির সংযুক্ত চিত্রটি দেখুন । ক্রিয়াকলটি বি থেকে ক্রিয়াকলাপ এ থেকে আরম্ভ করার সময় এটির মতো দেখতে কেমন হয় ইভেন্টগুলির ক্রম নীচ থেকে উপরে থাকে যাতে আপনি দেখতে পান যে onStopক্রিয়াকলটি বি এর onResumeআগেই ডাকা হওয়ার পরে ক্রিয়াকলটি এ বলা হয়েছিল।

ক্রিয়াকলাপ জীবনচক্রের ডেমো

যদি কোনও ডায়ালগ দেখানো হয় তবে আপনার ক্রিয়াকলাপটি পটভূমিতে ম্লান হয়ে গেছে এবং কেবল onPauseতাকে বলা হয়।


7

দুটি সম্ভাব্য সমাধান:

1) ক্রিয়াকলাপ লাইফসাইকেল কলব্যাকস

এমন একটি অ্যাপ্লিকেশন ব্যবহার করুন যা অ্যাক্টিভিটি লাইফাইসাইকেলব্যাকগুলি প্রয়োগ করে এবং এটি আপনার অ্যাপ্লিকেশনটিতে ক্রিয়াকলাপগুলি লাইফসাইকেলের ইভেন্টগুলি ট্র্যাক করতে ব্যবহার করে। নোট করুন যে অ্যাক্টিভিটিলিফাইসাইকেলব্যাকগুলি অ্যান্ড্রয়েড এপিআই> = 14 এর জন্য। পূর্ববর্তী অ্যান্ড্রয়েড এপিআইয়ের জন্য, আপনার নিজের সমস্ত ক্রিয়াকলাপের মধ্যে এটি নিজেই প্রয়োগ করতে হবে ;-)

আপনার যখন ক্রিয়াকলাপের ক্রিয়াকলাপ শেয়ার / স্টোর করতে হয় তখন অ্যাপ্লিকেশনটি ব্যবহার করুন ।

2) প্রক্রিয়া তথ্য চলমান জন্য পরীক্ষা করুন

আপনি এই শ্রেণিটি রানিং অ্যাপপ্রসেসআইএনফো দিয়ে চলমান প্রক্রিয়াটির স্থিতি পরীক্ষা করতে পারেন

ActivityManager.getRunningAppProcesses () এর সাথে চলমান প্রক্রিয়া তালিকাটি আনুন এবং কাঙ্ক্ষিত রানিং অ্যাপপ্রসেসআইএনফো-র পরীক্ষা এবং এর "গুরুত্ব" পরীক্ষা করতে ফলাফল তালিকা ফিল্টার করুন



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

আমি মনে করি আমার আরও ভাল সমাধান আছে। কারণ আপনি কেবল মাই অ্যাপ্লিকেশন.অ্যাকটিভিটিজেড () চালু করতে পারেন); প্রতিটি ক্রিয়াকলাপ এক এক করে বাড়ানো।

প্রথমত আপনাকে তৈরি করতে হবে (সাইবারনেটিকটিয়ারকগুরুআরসি এর মত)

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;
}

এর পরে, আপনাকে অ্যান্ড্রয়েড ম্যানিফেস্ট.এক্সএমএলে অ্যাপ্লিকেশন ক্লাস যুক্ত করতে হবে

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

অ্যাপকম্ব্যাটঅ্যাক্টিভিটি বাড়ানোর জন্য যদি আমার ক্রিয়াকলাপগুলির প্রয়োজন হয় তবে কী হবে?
উইঙ্কলারr

2

এটি অ্যাপ্লিকেশন.অ্যাক্টিভিটি লাইফেসাইকেলক্যালব্যাকস ব্যবহার করে একটি কার্যকর উপায়ে এটি অর্জন করতে পারে

উদাহরণস্বরূপ ক্রিয়াকলাপ শ্রেণীর নামটিকে প্রোফাইলএক্টিভিটি হিসাবে গ্রহণ করতে দেয় এটি অগ্রভাগ বা ব্যাকগ্রাউন্ডে রয়েছে কিনা তা খুঁজে পেতে দেয়

প্রথমে আমাদের অ্যাপ্লিকেশন ক্লাসটি অ্যাপ্লিকেশন ক্লাস প্রসারিত করে তৈরি করতে হবে

যা বাস্তবায়ন করে

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;
}
}

উপরের শ্রেণিতে অ্যাক্টিভিটি লাইফেসাইকেলক্যালব্যাকস চালু করা কার্যকলাপের পুনরায় শুরু করা হয়েছে একটি ওভাররাইড মেথর্ড রয়েছে

 @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;
}

যেখানে বর্তমানে স্ক্রিনে প্রদর্শিত সমস্ত ক্রিয়াকলাপ উদাহরণ পাওয়া যাবে, কেবলমাত্র আপনার ক্রিয়াকলাপটি স্ক্রিনে রয়েছে কিনা তা উপরের পদ্ধতির দ্বারা পরীক্ষা করে দেখুন।

ম্যানিফেস্ট.এক্সএমএলে আপনার অ্যাপ্লিকেশন ক্লাসটি নিবন্ধ করুন

<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 উদাহরণের সর্বত্র isAnyActivityVisible () পদ্ধতিটি ব্যবহার করতে পারেন!


0

আপনি কি কল্পনা শেষ না করার এবং "অ্যান্ড্রয়েড: noHistory =" সত্য "ম্যানিফেস্টে রাখার চেষ্টা করেছেন? এটি কার্যকলাপটিকে স্ট্যাকে যেতে বাধা দেবে।


0

আমাকে বলতে হবে আপনার ওয়ার্কফ্লো মানক অ্যান্ড্রয়েড উপায়ে নয়। অ্যান্ড্রয়েডে, আপনি finish()যদি ইন্টেন্ট থেকে অন্য ক্রিয়াকলাপ খুলতে চান তবে আপনার ক্রিয়াকলাপের দরকার নেই । ব্যবহারকারীর সুবিধার্থে, অ্যান্ড্রয়েড ব্যবহারকারীরা আপনার অ্যাপ্লিকেশনটিতে যে ক্রিয়াকলাপটি খোলেন তার থেকে ফিরে যেতে 'ব্যাক' কীটি ব্যবহার করতে দেয়।

সুতরাং কেবলমাত্র সিস্টেমটিকে আপনার ক্রিয়াকলাপ বন্ধ করুন এবং যখন আপনার ক্রিয়াকলাপটি ফিরে ডাকা হবে তখন প্রয়োজনীয় কিছু সংরক্ষণ করতে দিন।


আমি কেন জানি না কেন এটি হতাশ। কমপক্ষে কারণ হিসাবে একটি মন্তব্য দিন যা আমি চাই।
ওভেন ঝাও

3
"বুও এটি অ্যান্ড্রয়েড নয়" উপায় উত্তর ক্লান্তিকর এবং প্রথম স্থানে উত্থিত প্রশ্নের উত্তর দেয় না। তদ্ব্যতীত, () সমাপ্ত করার জন্য বৈধ কারণ রয়েছে; - উদাহরণস্বরূপ এটি অনুমেয় যে এই পদক্ষেপটি একবার পদক্ষেপ গ্রহণের পরে ফিরে যাওয়া কোনও উদ্দেশ্যই কার্যকর করে না। অন্য কথায়, আপনি কি মনে করেন যে তারা মজা করার জন্য সেখানে () শেষ করেছেন? এটি স্ট্যাকের মধ্যে থাকা ঠিক প্রশ্ন প্রশ্নকারী এড়াতে চেয়েছিল
লাসি কিনুনেনেন

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!
    }
};

এবং আপনার দ্বিতীয় ক্রিয়াকলাপ থেকে সম্প্রচার শুনতে আপনার নতুন রিসিভার লোকালড্রোডকাস্টম্যানেজারের সাথে নিবন্ধ করুন:

//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()

এপিআই 17-এ যুক্ত হয়েছে
যদি ক্রিয়াকলাপের উপর চূড়ান্ত অনডেট্রয়ে () কল করা থাকে, তবে এই উদাহরণটি এখন মারা গেছে।

isFinishing()

এপিআই 1-এ যুক্ত হয়েছে
এই ক্রিয়াকলাপটি সমাপ্তির প্রক্রিয়াধীন কিনা তা পরীক্ষা করে দেখুন, আপনি এটির উপর ফিনিস () বলেছিলেন বা অন্য কেউ এটি শেষ করার জন্য অনুরোধ করেছেন বলেই। কার্যকলাপটি কেবল বিরতি দেওয়া হয় বা সম্পূর্ণ সমাপ্ত হয় কিনা তা নির্ধারণ করতে এটি প্রায়শই অনপেজ () এ ব্যবহৃত হয়।


থেকে মেমরি তথ্য ফাঁসের ডকুমেন্টেশন

একটি সাধারণ ভুল 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
    }
}


আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.