অ্যান্ড্রয়েডে কীভাবে বর্তমান অগ্রভাগের ক্রিয়াকলাপ প্রসঙ্গে পাবেন?


171

যখনই আমার সম্প্রচার কার্যকর করা হয় আমি অগ্রভাগের ক্রিয়াকলাপে সতর্কতা প্রদর্শন করতে চাই।


যেখান থেকে আপনি ক্রিয়াকলাপের প্রসঙ্গ পেতে চান এটি আপনার অ্যাপ্লিকেশন কার্যকলাপ বা অন্য অ্যাপ্লিকেশন হবে।
আনকিট

এটি একটি অ্যাপ্লিকেশন কার্যকলাপ। আমি ব্রডকাস্ট্রেসিভার অনরিসিপ () ফাংশনে কোডিং সতর্কতা করেছি।
দীপালি

একটি অ্যাপ্লিকেশন কার্যকলাপ! এটি কি আপনার অ্যাপ ?? এবং আপনি কেন এটি চান, কোনও কারণেই এর বিকল্প থাকতে পারে
অ্যাঙ্কিত

আমি আমার অগ্রভাগের ক্রিয়াকলাপে সতর্কতা দেখাতে চাই context প্রসঙ্গ ছাড়াই অগ্রভাগের ক্রিয়াকলাপে সতর্কতা দেখানোর তাদের অন্য কোনও উপায়।
দীপালি

1
কেবলমাত্র প্যারাম হিসাবে অনবদ্য প্রাপ্তিতে, আপনি
প্রসঙ্গটি

উত্তর:


39

জেনে ActivityManager পরিচালনা করে ভ্রমণ , তাই আমরা থেকে তথ্য অর্জন করতে ActivityManager । এর মাধ্যমে আমরা বর্তমান ফোরগ্রাউন্ডটি ক্রিয়াকলাপটি চালাচ্ছি

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

আপডেট করা হবে 2018/10/03
getRunningTasks () অবমুক্ত করা হয়েছে। নীচের সমাধান দেখুন।

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


16
getRunningTasks এর SDK সাহায্য থেকে মার্টিনকে এমনটি ভাবেন না "দ্রষ্টব্য: এই পদ্ধতিটি কেবলমাত্র ডিবাগিং এবং টাস্ক ম্যানেজমেন্ট ব্যবহারকারী ইন্টারফেস উপস্থাপনের উদ্দেশ্যে তৈরি। এটি কোনও অ্যাপ্লিকেশনটিতে মূল যুক্তির জন্য কখনও ব্যবহার করা উচিত নয়"
রুহল্ডে

3
স্পষ্টতই এটি কেবল অ্যান্ড্রয়েড 5 / ললিপপে চলমান কাজগুলির সীমিত উপসেটটিকে সমর্থন করে।
স্যাম

7
ActivityManager.getRunningTasks () এর জন্য ডকুমেন্টেশন বলছে "এই পদ্ধতিটি API স্তরের 21 স্তরে অবচিত করা হয়েছিল"।
মার্কশিপ

210

( দ্রষ্টব্য: এপিআই 14 এ একটি অফিসিয়াল এপিআই যুক্ত করা হয়েছে: এই উত্তরটি দেখুন https://stackoverflow.com/a/29786451/119733 )

পূর্ববর্তী উত্তর (waqas716) ব্যবহার করবেন না।

ক্রিয়াকলাপের স্থির রেফারেন্সের কারণে আপনার মেমরি ফুটো সমস্যা হবে। আরও তথ্যের জন্য নিম্নলিখিত লিঙ্কটি দেখুন:

এটি এড়াতে আপনার ক্রিয়াকলাপের রেফারেন্সগুলি পরিচালনা করা উচিত। ম্যানিফেস্ট ফাইলটিতে অ্যাপ্লিকেশনটির নাম যুক্ত করুন:

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

সুতরাং, এখন আপনার ক্রিয়াকলাপগুলির জন্য ক্রিয়াকলাপের ক্লাস প্রসারিত করার পরিবর্তে, কেবলমাত্র আমারবেসঅ্যাক্টিভিটি প্রসারিত করুন। এখন, আপনি অ্যাপ্লিকেশন বা এর মতো ক্রিয়াকলাপ প্রসঙ্গে আপনার বর্তমান ক্রিয়াকলাপটি পেতে পারেন:

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

9
আপনি কেবল WeakReferences ব্যবহার করতে পারেন এবং কম কোড সহ একই ফলাফল অর্জন করতে পারেন।
নাচো কলোমা

5
@ নাচো আমি কখনই WeakReferencesঅ্যান্ড্রয়েডে জিসি ব্যবহারের তাগিদ দেব না জিসি সেগুলি দ্রুত সংগ্রহ করে তারপরে আপনি ভাবেন।
rekire

4
@ ম্যাক্সিমকোরোবভ হ্যাঁ আপনি যদি অনক্রিট () থেকে ফিনিস () কল করেন তবে এটি সম্ভব, যদি আপনি নিজের ক্রিয়াকলাপটি কেবল অন্য কার্যকলাপ চালু করতে ব্যবহার করেন এবং এটি বন্ধ করে দেন। এই দৃশ্যে এটি পজ () এবং অনস্টো () এড়িয়ে যায়। নীচের নোটটি দেখুন: বিকাশকারী
অ্যান্ড্রয়েড / ট্রেনিং / বেসিক্স / সক্রিয়তা -জীবনচক্র //

2
@ রেকায়ার @ নাচোকোলোমা ব্যবহারের WeakReferenceপরামর্শ দেওয়া হচ্ছে না ক্যাচিংয়ের জন্য, এটি ক্যাশিং নয়, এটি mCurrentActivityকেবলমাত্র জীবিত থাকাকালীন একটি রেফারেন্স থাকবে তাই শীর্ষে WeakReferenceথাকা অবস্থায় কখনই সংগ্রহ করা হবে না Activity। তবে @ ন্যাচো কোলকোমা যা বলেছে তা ভুল কারণ কারণ WeakReferenceভেরিয়েবলটি সাফ না হলে এখনও পুনরায় চালু করা (জীবিত / শীর্ষে নয়) ক্রিয়াকলাপটি উল্লেখ করা যেতে পারে!
TWiStErRob

14
অ্যান্ড্রয়েড এপিআই স্তর 14 থেকে শুরু করে এটি ব্যবহার করা সম্ভব হওয়া উচিত Application .ActivityLifecycleCallbacks, যা আরও কেন্দ্রীয় হবে এবং আপনার সমস্ত ক্রিয়াকলাপে আপনাকে কোনও পরিচালনা কোড যুক্ত করতে হবে না। এছাড়াও বিকাশকারী.অ্যান্ড্রয়েড.
com

68

আমি @ গেজেডি এর উত্তরের উপরে প্রসারিত করব।

প্রতিটি ক্রিয়াকলাপে, Applicationম্যানুয়াল কোডিংয়ের সাথে নিজেকে "রেজিস্ট্রেশন" করার পরিবর্তে, নিম্ন ম্যানুয়াল কোডিংয়ের সাথে অনুরূপ উদ্দেশ্য অর্জনে আমাদের সহায়তা করতে আমরা 14 তম স্তর থেকে নিম্নলিখিত API ব্যবহার করতে পারি।

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

যাইহোক, এই কৌশলটি কেবলমাত্র API স্তর 14 থেকে উপলব্ধ।


1
অন্য সমস্ত উত্তর দিয়ে কি হয়েছে? স্পষ্টতই এটি এই উদ্দেশ্যে ডিজাইন করা হয়েছে API। ধন্যবাদ, চেওক ইয়ান চেং
মাইকেল বুশে

2
@ মিশেলবুশে - ২০১২ সালে, যখন অন্যান্য উত্তরগুলি লেখা হয়েছিল, এপিআই স্তরের ১৪ এর উপর নির্ভর করে প্রতিটি ডিভাইসে নির্ভর করার কিছু ছিল না, তবে এই যে এপিআই সম্প্রতি প্রকাশিত হয়েছিল (অক্টোবর ২০১১)।
টুলমেকারস্টেভ

4
এই পদ্ধতিটি কীভাবে ব্যবহার করবেন সে সম্পর্কে একটি উত্তর পেয়েছে : stackoverflow.com/a/11082332/199364 সুবিধাটি হ'ল ক্রিয়াকলাপগুলি নিজেই করার দরকার নেই ; কোডটি আপনার কাস্টম কলব্যাক ক্লাসে রয়েছে। আপনি কেবল একটি ক্লাস তৈরি করেন implements Application.ActivityLifecycleCallbacksএবং এটি প্রয়োগের পদ্ধতি যুক্ত করুন। তারপরে সেই শ্রেণীর 'কনস্ট্রাক্টর (বা অনক্রিয়েট বা দীক্ষা বা অন্য পদ্ধতি যা দৃষ্টান্ত সক্রিয় / প্রস্তুত হয়ে উঠলে চালিত হয়), getApplication().registerActivityLifecycleCallbacks(this);সর্বশেষ লাইন হিসাবে রেখে দিন।
টুলমেকারস্টেভ

আমি মনে করি আপনার উত্তরটি সবচেয়ে ভাল
বুড়ুলংটু

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

56

আপডেট 2 : এটির জন্য একটি অফিসিয়াল এপিআই যুক্ত হয়েছে, দয়া করে পরিবর্তে অ্যাক্টিভিটিফাইসাইকেলক্যালব্যাকগুলি ব্যবহার করুন।

হালনাগাদ:

@ গেজেডি দ্বারা চিহ্নিত হিসাবে, এবং আমি এর জন্য কৃতজ্ঞ। বর্তমান ক্রিয়াকলাপের জন্য নালকেও রেফারেন্স সেট করুন , মেমরি ফাঁস সমস্যাটি এড়াতে কেবলমাত্র প্রতিটি অনর আপডেটের পরিবর্তে প্রতিটি ক্রিয়াকলাপের অনডাস্ট্রয়ে এটিকে বাতিল করে দিন।

কিছুক্ষণ আগে আমার একই কার্যকারিতাটির প্রয়োজন ছিল এবং আমি কীভাবে এটি অর্জন করেছি তার পদ্ধতি এখানে। আপনার প্রতিটি ক্রিয়াকলাপে এই জীবনচক্র পদ্ধতিগুলিকে ওভাররাইড করে।

@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
এই উত্তরটি সত্যিকার অর্থেই আরও বেশি ভোট, সহজ সমাধান পাওয়া উচিত, তবে শক্তিশালী যখন আপনার ক্লাস থাকে যাতে ক্রিয়াকলাপগুলি চালিত করার প্রয়োজন হয় তবে তারা নিজেরাই ক্রিয়াকলাপ নয়।
রাইভিয়ানস্টায়রন

এটি আপনার ক্রিয়াকলাপের অবজেক্টের কেবল স্থির রেফারেন্স। আপনি যেখানেই এটি তৈরি করতে পারেন :)। এটা কোন ব্যাপার না।
ওয়াকাস

এটি আপনার আগের উত্তরের সমতুল্য বিটিডব্লিউ। Applicationশুধুমাত্র একবারেই তৈরি হয় এবং কখনই কোনও আবর্জনা স্থির পরিবর্তনশীলের মতো সংগ্রহ করা যায় না।
Zapl

1
শ্রেণিবদ্ধ ক্রিয়াকলাপে সমস্যা হবে। আপনি যখন কোনও শিশু ক্রিয়াকলাপ থেকে পিতামাতার কাছে ফিরে আসেন: (1) বাচ্চার অনপেজ নামে পরিচিত; (২) পিতামাতার অন-রিসুম; (3) শিশুর অনডাস্ট্রয় ==> বর্তমান ক্রিয়াকলাপটি শূন্য হবে। আপনার পদ্ধতিটি ক্লিয়ার রেফারেন্সে উদাহরণ হিসাবে জিজেডির মতো কিছু চেক করা উচিত।
আর্টস

4
@ waqas716 আমি শর্ত প্রক্রিয়া সহজ করার সুপারিশ করছি clearReferences()করার (this.equals(currActivity))
নেক্সা

51

@lockwobr আপডেটের জন্য ধন্যবাদ

এটি এপিআই সংস্করণ 16 এ 100% সময়ের সাথে কাজ করে না, আপনি যদি গিথুব-তে কোডটি পড়ে "কারেন্ট অ্যাক্টিভিটিথ্রেড" ফাংশনটি কিটকেটে পরিবর্তন করতেন, তাই আমি সংস্করণ ১৯-ই বলতে চাই, গিথুব-এ প্রকাশের সাথে এপিআই সংস্করণটি মেলে একরকম কঠিন ।

স্রোতে অ্যাক্সেস Activityথাকা খুব সহজ। getActivityঅযৌক্তিক প্রশ্ন না করে কোনও স্থির পদ্ধতি বর্তমান ক্রিয়াকলাপ ফিরিয়ে দেওয়া কি সুন্দর হবে না ?

Activityবর্গ খুবই দরকারী। এটি অ্যাপ্লিকেশনটির ইউআই থ্রেড, দর্শন, সংস্থান এবং আরও অনেক কিছুতে অ্যাক্সেস দেয়। বিভিন্ন পদ্ধতিতে একটি প্রয়োজন Context, তবে পয়েন্টারটি কীভাবে পাবেন? এখানে কিছু উপায় রয়েছে:

  • ওভাররাইডেড লাইফসাইकल পদ্ধতি ব্যবহার করে অ্যাপ্লিকেশনের স্থিতি অনুসরণ করা। আপনার বর্তমান ক্রিয়াকলাপটি একটি স্থিতিশীল ভেরিয়েবলে সঞ্চয় করতে হবে এবং আপনাকে সমস্ত ক্রিয়াকলাপের কোডটিতে অ্যাক্সেস দরকার।
  • ইনস্ট্রুমেন্টেশন ব্যবহার করে অ্যাপ্লিকেশনের স্থিতি অনুসরণ করা। ম্যানিফেস্টে ইনস্ট্রুমেন্টেশন ঘোষণা করুন, এটি প্রয়োগ করুন এবং ক্রিয়াকলাপের পরিবর্তনগুলি ট্র্যাক করতে এর পদ্ধতিগুলি ব্যবহার করুন। আপনার ক্রিয়াকলাপে ব্যবহৃত পদ্ধতি এবং ক্লাসগুলিতে একটি ক্রিয়াকলাপের নির্দেশক পাস করা। কোড ইঞ্জেকশন লাইব্রেরির একটি ব্যবহার করে পয়েন্টারটি ইনজেকশন করা হচ্ছে। এই সমস্ত পদ্ধতির পরিবর্তে অসুবিধে হয় ; ভাগ্যক্রমে, বর্তমান ক্রিয়াকলাপটি পাওয়ার আরও অনেক সহজ উপায় রয়েছে।
  • দেখে মনে হচ্ছে যে উপরে উল্লিখিত সমস্যাগুলি ছাড়াই সিস্টেমটির সমস্ত ক্রিয়াকলাপে অ্যাক্সেস দরকার। সুতরাং, সম্ভবত কেবল স্থিতিকাল কল ব্যবহার করে ক্রিয়াকলাপ পাওয়ার কোনও উপায় রয়েছে। আমি গ্রেপকোড.কম এ অ্যান্ড্রয়েড উত্সগুলি খনন করতে অনেক সময় ব্যয় করেছি এবং আমি যা সন্ধান করছি তা পেয়েছি। একটি ক্লাস বলা হয় 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
কিটকেট এবং উপরের এমএটিভিটিগুলিতে হ্যাশম্যাপ নয়, তবে অ্যারেম্যাপ নয়, সুতরাং আপনার এই লাইনটি পরিবর্তন করতে হবে: হ্যাশম্যাপ ক্রিয়াকলাপগুলি = (হ্যাশম্যাপ) ক্রিয়াকলাপফিল্ড বিট (ক্রিয়াকলাপ ট্র্যাড); দেখতে এটির মতো: অ্যারেম্যাপ ক্রিয়াকলাপগুলি = (অ্যারেম্যাপ) ক্রিয়াকলাপফিল্ড.জেট (অ্যাক্টিভিটিথ্রেড);
পালেজান্দ্রো

7
উভয় এপিআই স্তরের সমর্থনের জন্য পলেজান্দ্রো (১৮ এর উপরে এবং নীচে) এর Mapপরিবর্তে HashMapবা এর ইন্টারফেস ব্যবহার করা উচিত ArrayMap। আমি @ এজেড_ উত্তর সম্পাদনা করেছি।
ইউরি কোলবাসিনস্কি

2
এটি এপিআই সংস্করণ 16 এ 100% সময়ের সাথে কাজ করে না , আপনি যদি গিথুব-তে কোডটি পড়ে "কারেন্ট অ্যাক্টিভিটিথ্রেড" ফাংশনটি কিটকেটে পরিবর্তন করতেন, তাই আমি সংস্করণ ১৯-ই বলতে চাই , গিথুব-এ প্রকাশের সাথে এপিআই সংস্করণটি মেলে একরকম কঠিন ।
লকউব্রব

@ লকউইউব ধন্যবাদ, আপনার মন্তব্যের সাথে সমাধানটি আপডেট হয়েছে:)
এজেড_

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. অ্যাক্টিভিটিএফাইসাইকেলক্যালব্যাক্স ক্লাস তৈরি করুন

    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 এও রয়েছে।
(যেহেতু এই প্রশ্নটি প্রাথমিকভাবে জিজ্ঞাসা করা হয়েছিল, তাই অনেকগুলি অ্যান্ড্রয়েড অ্যাপ্লিকেশনটিতেও রিঅ্যাক্টনেটিভ উপাদান রয়েছে - হাইব্রিড অ্যাপ))

রিঅ্যাক্টনেটিভে রিঅ্যাক্ট কনটেক্সট ক্লাসে এমকোয়েন্টারএকটিভিটি বজায় রাখার জন্য লজিকের পুরো সেট রয়েছে যা getCenterActivity () এ ফিরে আসে।

দ্রষ্টব্য: আমি আশা করি getCenterActivity () অ্যান্ড্রয়েড অ্যাপ্লিকেশন শ্রেণিতে প্রয়োগ করা হয়েছে।


কিছু ক্ষেত্রে 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
কম্পোনেন্টনাম থেকে ক্রিয়াকলাপের বর্তমান দৃষ্টান্তে যাওয়ার উপায় না থাকলে আইএমও প্রশ্নের উত্তর দেয় না।
nasch

@ ন্যাশচেকে WeakReferenceএকটি Applicationক্লাসের কাছ থেকে একটি হ্যান্ডেল রাখতে এবং পেতে পারে - তবে চলমান কার্য তালিকার শীর্ষে ComponentNameকাঙ্ক্ষিত কিনা তা নির্ধারণ করার জন্য প্রয়োজনীয় আবশ্যক Activity। এবং যদি এটি প্রশ্নের পুরোপুরি উত্তর না দেয় তবে গৃহীত উত্তরটিও দেয় না।
মার্টিন জিটলার

আমি সম্মত, গৃহীত উত্তর পুরোপুরি প্রশ্নের উত্তর দেয় না।
nasch

1
topActivityশুধুমাত্র অ্যান্ড্রয়েড কিউ থেকে পাওয়া যায়
ইউজেন মার্টিনভ

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

}

আমার ক্ষেত্রে আমি "অ্যাপ্লিকেশন.অ্যাক্টিভিটি লাইফসাইকেলক্যালব্যাকস" এতে ব্যবহার করেছি:

  • বাঁধাই / আনবাইন্ড মেরিলিন ইনস্ট্যান্স (অ্যাপ্লিকেশনটি হারাতে বা সংযোগ পাওয়ার সময় ইভেন্ট পেতে ব্যবহৃত হত, উদাহরণস্বরূপ যখন আপনি মোবাইল ডেটা বন্ধ করেন বা কখন এটি খুলবেন)। "OnConnectivityChanged" অভিপ্রায় ক্রিয়া অক্ষম করার পরে এটি কার্যকর। মেরিলিন সম্পর্কে আরও তথ্যের জন্য দেখুন: মেরিলিন ইনফো LINK

  • অ্যাপ্লিকেশনটি বন্ধ হয়ে গেলে আমার সর্বশেষ রাজ্য দৃষ্টান্তটি বন্ধ করুন; আমি এটি বেসঅ্যাক্টিভিটির মধ্যে শুরু করব যা অন্যান্য সমস্ত ক্রিয়াকলাপ থেকে প্রসারিত এবং এতে একটি ব্যক্তিগত রিয়েলহেল্পার ইনস্ট্যান্স রয়েছে। রিয়েলম সম্পর্কিত আরও তথ্যের জন্য দেখুন: রিয়েল ইনফো লিংক উদাহরণস্বরূপ আমার "রিয়েলহেল্পার" শ্রেণীর অভ্যন্তরে আমার একটি স্থিতিশীল "রিয়েলহেল্পার" উদাহরণ রয়েছে যা আমার অ্যাপ্লিকেশন "অনক্রিট" এর ভিতরে ইনস্ট্যান্ট করা আছে ated আমার একটি সিঙ্ক্রোনাইজেশন পরিষেবা রয়েছে যা আমি নতুন "রিয়েলহেল্পার" তৈরি করি কারণ রিয়েলম "থ্রেড-লিংকড" এবং একটি রিয়েল ইনস্ট্যান্স কোনও আলাদা থ্রেডের ভিতরে কাজ করতে পারে না। সুতরাং রিয়েলমের ডকুমেন্টেশন অনুসরণ করতে "সিস্টেম রিসোর্সেস লিক এড়ানোর জন্য আপনাকে সমস্ত খোলার ক্ষেত্র বন্ধ করতে হবে", এই জিনিসটি সম্পাদন করতে আমি "অ্যাপ্লিকেশন.অ্যাক্টিভিটি লাইফিসাইকেলক্যালব্যাকস" ব্যবহার করেছি যেমন আপনি দেখতে পাচ্ছেন।

  • অবশেষে আমার কাছে আমার রিসিভার উইচ ট্রিগার হয়েছে যখন আমি আমার অ্যাপ্লিকেশনটি সিঙ্ক্রোনাইজ করা শেষ করব, তারপরে সিঙ্কটি শেষ হয়ে গেলে এটি "আইইন্ডসিঙ্কক্যালব্যাক" "অন এন্ডসিঙ্ক" পদ্ধতিতে কল করবে যেখানে আমি আমার ক্রিয়াকলাপব্যাকস্ট্যাক তালিকার ভিতরে একটি নির্দিষ্ট ক্রিয়াকলাপ আছে বলে আমার মনে হচ্ছে কারণ আমার প্রয়োজন সিঙ্কটি যদি তাদের আপডেট করে এবং ভিউটি ডেটা আপডেট করার জন্য অ্যাপ্লিকেশন সিঙ্ক হওয়ার পরে আমার অন্যের কাজ করতে পারে।

এগুলি সব, আশা করি এটি সহায়ক। তোমাকে দেখে :)


-1

উত্তর দ্বারা Waqas716 ভাল। আমি কম কোড এবং রক্ষণাবেক্ষণের দাবিতে একটি নির্দিষ্ট কেসের জন্য একটি কার্যনির্বাহ তৈরি করেছি।

আমি স্থির পদ্ধতিতে আমার অগ্রভাগে থাকা সন্দেহজনক ক্রিয়াকলাপ থেকে একটি দৃষ্টিভঙ্গি এনে একটি নির্দিষ্ট কাজ পেয়েছি। আপনি সমস্ত ক্রিয়াকলাপের মাধ্যমে পুনরাবৃত্তি করতে পারেন এবং মার্টিনের কাছ থেকে ক্রিয়াকলাপের নাম চান কিনা তা পরীক্ষা করতে পারেন উত্তর

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
কিন্তু ডক্স থেকে 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, ..." মধ্যে developer.android.com/reference/android/app/...
ToolmakerSteve

3
ActivityManager.getRunningTasks () এর জন্য ডকুমেন্টেশন এখন বলছে "এই পদ্ধতিটি API স্তরের 21 স্তরে অবনমিত হয়েছিল"।
মার্কশেপ

-2

আমি অন্য কোনও উত্তর পছন্দ করি না। অ্যাক্টিভিটি ম্যানেজারটি বর্তমান ক্রিয়াকলাপটি পাওয়ার জন্য ব্যবহার করা হয় না। সুপার ক্লাসিং এবং অনডাস্ট্রয়ের উপর নির্ভর করে এটিও ভঙ্গুর এবং সেরা নকশা নয়।

সত্য, আমি এখন পর্যন্ত যে সেরাটি নিয়ে এসেছি তা হ'ল আমার অ্যাপ্লিকেশনটিতে একটি এনাম বজায় রাখা, যা কোনও ক্রিয়াকলাপ তৈরি হওয়ার পরে সেট হয়ে যায়।

অন্য একটি সুপারিশ হ'ল সম্ভব হলে একাধিক ক্রিয়াকলাপ ব্যবহার করা থেকে বিরত থাকুন। এটি খণ্ডগুলি ব্যবহার করে বা আমার পছন্দ অনুসারে কাস্টম দর্শন দিয়ে করা যেতে পারে।


1
একটি এনাম? কীভাবে এটি বর্তমান পূর্বের ক্রিয়াকলাপের উদাহরণ সনাক্ত করতে সহায়তা করে?
টুলমেকারস্টেভ

"সুপার ক্লাসিং এবং ডিস্ট্রয়ের উপর নির্ভর করে এটিও ভঙ্গুর" কীভাবে এটি ভঙ্গুর?
টুলমেকারস্টেভ

-3

একটি সহজ সমাধান হ'ল একটি সিঙ্গলটন ম্যানেজার শ্রেণি তৈরি করা, যাতে আপনি এক বা একাধিক ক্রিয়াকলাপের জন্য রেফারেন্স সঞ্চয় করতে পারেন, বা অ্যাপ্লিকেশন জুড়ে আপনি যে কোনও কিছুতে অ্যাক্সেস চান।

কল UberManager.getInstance().setMainActivity( activity );মূল ক্রিয়াকলাপের অনক্রিটে ।

UberManager.getInstance().getMainActivity();এটি পুনরুদ্ধার করতে আপনার অ্যাপের যে কোনও জায়গায় কল করুন। (আমি অ ইউআই থ্রেড থেকে টোস্ট ব্যবহার করতে সক্ষম হতে এটি ব্যবহার করছি using)

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_ দ্বারা উত্তর অনেক কোডবেস অন্যান্য পরিবর্তন ছাড়াই ভাল হিসাবে এটি সম্পূর্ণই স্থানীয় হওয়ার স্বতন্ত্র হয়।
মার্কশিপ

-7

আমি 3 বছর দেরির মতো কিন্তু আমি এর মতো যদি কেউ এটির সন্ধান করে তবে আমি এর জবাব দেব।

আমি কেবল এটি ব্যবহার করে এটি সমাধান করেছি:

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

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

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