มีวิธีง่ายๆในการพิจารณาว่ากิจกรรมบางอย่างมีการใช้งานอยู่หรือไม่? ฉันต้องการทำบางสิ่งขึ้นอยู่กับกิจกรรมที่ใช้งานอยู่ เช่น:
if(activityrunning == activity1)
//do this
else if (activityrunning == activity2)
//do something else
มีวิธีง่ายๆในการพิจารณาว่ากิจกรรมบางอย่างมีการใช้งานอยู่หรือไม่? ฉันต้องการทำบางสิ่งขึ้นอยู่กับกิจกรรมที่ใช้งานอยู่ เช่น:
if(activityrunning == activity1)
//do this
else if (activityrunning == activity2)
//do something else
คำตอบ:
คุณสามารถใช้static
ตัวแปรภายในกิจกรรม
class MyActivity extends Activity {
static boolean active = false;
@Override
public void onStart() {
super.onStart();
active = true;
}
@Override
public void onStop() {
super.onStop();
active = false;
}
}
gotcha เพียงอย่างเดียวคือถ้าคุณใช้มันในสองกิจกรรมที่เชื่อมโยงกับแต่ละอื่น ๆ แล้วonStop
ในครั้งแรกที่บางครั้งเรียกว่าonStart
ในครั้งที่สอง ดังนั้นทั้งสองอาจเป็นจริงสั้น ๆ
ขึ้นอยู่กับสิ่งที่คุณพยายามทำ (อัพเดตกิจกรรมปัจจุบันจากบริการ?) คุณสามารถลงทะเบียนฟังแบบคงที่ในบริการในonStart
วิธีกิจกรรมของคุณจากนั้นผู้ฟังที่ถูกต้องจะสามารถใช้งานได้เมื่อบริการของคุณต้องการอัปเดต UI
MyActivity
ด้วยMyChildactivity
และต้องการตรวจสอบว่าเด็กมีการใช้งาน?
ฉันรู้ว่าปัญหานี้ค่อนข้างเก่า แต่ฉันคิดว่ามันยังคุ้มค่าที่จะแบ่งปันโซลูชันของฉันเพราะมันอาจเป็นประโยชน์กับผู้อื่น
โซลูชันนี้ไม่พร้อมใช้งานก่อนที่ส่วนประกอบสถาปัตยกรรมของ Android จะวางจำหน่าย
กิจกรรมสามารถมองเห็นได้อย่างน้อยบางส่วน
getLifecycle().getCurrentState().isAtLeast(STARTED)
กิจกรรมอยู่เบื้องหน้า
getLifecycle().getCurrentState().isAtLeast(RESUMED)
ฉันคิดว่าชัดเจนกว่านี้:
public boolean isRunning(Context ctx) {
ActivityManager activityManager = (ActivityManager) ctx.getSystemService(Context.ACTIVITY_SERVICE);
List<RunningTaskInfo> tasks = activityManager.getRunningTasks(Integer.MAX_VALUE);
for (RunningTaskInfo task : tasks) {
if (ctx.getPackageName().equalsIgnoreCase(task.baseActivity.getPackageName()))
return true;
}
return false;
}
ตัวเลือกโดยไม่ใช้ตัวแปรที่คุ้นเคยคือ:
activity.getWindow().getDecorView().getRootView().isShown()
โดยที่ activity คือ fe: this หรือ getActivity ()
ค่าที่ส่งคืนโดยนิพจน์นี้จะเปลี่ยนแปลงใน onStart () / onStop () ซึ่งเป็นเหตุการณ์ที่เริ่ม / หยุดแสดงโครงร่างของกิจกรรมบนโทรศัพท์
Activity#getWindow().getDecorView().isShown()
?
ฉันใช้ MyActivity.class และเมธอด getCanonicalName และได้รับคำตอบ
protected Boolean isActivityRunning(Class activityClass)
{
ActivityManager activityManager = (ActivityManager) getBaseContext().getSystemService(Context.ACTIVITY_SERVICE);
List<ActivityManager.RunningTaskInfo> tasks = activityManager.getRunningTasks(Integer.MAX_VALUE);
for (ActivityManager.RunningTaskInfo task : tasks) {
if (activityClass.getCanonicalName().equalsIgnoreCase(task.baseActivity.getClassName()))
return true;
}
return false;
}
getRunningTasks()
เนื่องจากเลิกใช้แล้ว: androidxref.com/9.0.0_r3/xref/frameworks/base/core/java/android/…
วิธีที่ดีกว่าการใช้ตัวแปรแบบสแตติกและการติดตาม OOP
Shared Preferences
สามารถใช้เพื่อแชร์ตัวแปรกับผู้อื่นactivities
และบริการจากที่หนึ่งapplication
public class example extends Activity {
@Override
protected void onStart() {
super.onStart();
// Store our shared preference
SharedPreferences sp = getSharedPreferences("OURINFO", MODE_PRIVATE);
Editor ed = sp.edit();
ed.putBoolean("active", true);
ed.commit();
}
@Override
protected void onStop() {
super.onStop();
// Store our shared preference
SharedPreferences sp = getSharedPreferences("OURINFO", MODE_PRIVATE);
Editor ed = sp.edit();
ed.putBoolean("active", false);
ed.commit();
}
}
ใช้การตั้งค่าที่ใช้ร่วมกัน มีข้อมูลสถานะที่เชื่อถือได้มากที่สุดลดปัญหาการสลับ / ทำลายแอปพลิเคชันน้อยลงช่วยให้เราขออนุญาตอีกครั้งและช่วยให้เราควบคุมได้มากขึ้นในการตัดสินใจว่ากิจกรรมของเราเป็นจริงที่สุด ดูรายละเอียดที่นี่ อับดุลที่นี่ด้วย
onStop()
นี่คือรหัสสำหรับตรวจสอบว่ามีบริการใดกำลังทำงานอยู่หรือไม่ ฉันค่อนข้างแน่ใจว่ามันสามารถทำงานกับกิจกรรมได้ตราบใดที่คุณเปลี่ยน getRunningServices ด้วย getRunningAppProcesses () หรือ getRunningTasks () ดูที่นี่http://developer.android.com/reference/android/app/ActivityManager.html#getRunningAppProcesses ()
เปลี่ยนค่าคงที่แพ็กเกจและค่าคงที่ BACKGROUND_SERVICE_CLASS ตามลำดับ
public static boolean isServiceRunning(Context context) {
Log.i(TAG, "Checking if service is running");
ActivityManager activityManager = (ActivityManager)context.getSystemService(Context.ACTIVITY_SERVICE);
List<RunningServiceInfo> services = activityManager.getRunningServices(Integer.MAX_VALUE);
boolean isServiceFound = false;
for (int i = 0; i < services.size(); i++) {
if (Constants.PACKAGE.equals(services.get(i).service.getPackageName())){
if (Constants.BACKGROUND_SERVICE_CLASS.equals(services.get(i).service.getClassName())){
isServiceFound = true;
}
}
}
Log.i(TAG, "Service was" + (isServiceFound ? "" : " not") + " running");
return isServiceFound;
}
มีวิธีที่ง่ายกว่าทุกอย่างที่กล่าวมาข้างต้นและวิธีการนี้ไม่ต้องการใช้android.permission.GET_TASKS
ในรายการหรือมีปัญหาเรื่องสภาพการแข่งขันหรือการรั่วไหลของหน่วยความจำที่ชี้ให้เห็นในคำตอบที่ยอมรับ
สร้างตัวแปร STATIC ในกิจกรรมหลัก คงที่ช่วยให้กิจกรรมอื่น ๆ ที่จะรับข้อมูลจากกิจกรรมอื่น onPause()
ตั้งค่าตัวแปรนี้เป็นเท็จ , onResume
และonCreate()
ตั้งค่าตัวแปรนี้จริง
private static boolean mainActivityIsOpen;
กำหนด getters และ setters ของตัวแปรนี้
public static boolean mainActivityIsOpen() {
return mainActivityIsOpen;
}
public static void mainActivityIsOpen(boolean mainActivityIsOpen) {
DayView.mainActivityIsOpen = mainActivityIsOpen;
}
และจากกิจกรรมหรือบริการอื่น
if (MainActivity.mainActivityIsOpen() == false)
{
//do something
}
else if(MainActivity.mainActivityIsOpen() == true)
{//or just else. . . ( or else if, does't matter)
//do something
}
if(!activity.isFinishing() && !activity.isDestroyed())
จากเอกสารอย่างเป็นทางการ:
ตรวจสอบเพื่อดูว่ากิจกรรมนี้อยู่ในขั้นตอนการตกแต่งหรือไม่เพราะคุณเรียกว่าเสร็จสิ้น () ที่มันหรือคนอื่นขอให้เสร็จ สิ่งนี้มักใช้ใน onPause () เพื่อตรวจสอบว่ากิจกรรมนั้นหยุดชั่วคราวหรือเสร็จสิ้นแล้ว
ผลตอบแทนจริงถ้าโทร onDestroy () ขั้นสุดท้ายได้รับการทำในกิจกรรมดังนั้นกรณีนี้ตอนนี้จะตาย
ขอบคุณ kkudi! ฉันสามารถปรับคำตอบของคุณเพื่อทำงานสำหรับกิจกรรม ... นี่คือสิ่งที่ทำงานในแอปของฉัน ..
public boolean isServiceRunning() {
ActivityManager activityManager = (ActivityManager)Monitor.this.getSystemService (Context.ACTIVITY_SERVICE);
List<RunningTaskInfo> services = activityManager.getRunningTasks(Integer.MAX_VALUE);
isServiceFound = false;
for (int i = 0; i < services.size(); i++) {
if (services.get(i).topActivity.toString().equalsIgnoreCase("ComponentInfo{com.lyo.AutoMessage/com.lyo.AutoMessage.TextLogList}")) {
isServiceFound = true;
}
}
return isServiceFound;
}
ตัวอย่างนี้จะให้จริงหรือเท็จหาก topActivity ตรงกับสิ่งที่ผู้ใช้กำลังทำ ดังนั้นหากกิจกรรมที่คุณกำลังตรวจสอบไม่ปรากฏขึ้น (เช่น onPause) คุณจะไม่ได้รับการจับคู่ นอกจากนี้ในการทำเช่นนี้คุณจะต้องเพิ่มการอนุญาตให้กับรายการของคุณ ..
<uses-permission android:name="android.permission.GET_TASKS"/>
ฉันหวังว่านี่จะเป็นประโยชน์!
ฉันคิดว่าคำตอบที่ได้รับการยอมรับเป็นวิธีที่น่ากลัวในการจัดการกับสิ่งนี้
ฉันไม่ทราบว่ากรณีการใช้คืออะไร แต่โปรดพิจารณาวิธีการป้องกันในชั้นฐาน
@protected
void doSomething() {
}
และแทนที่ในคลาสที่ได้รับ
เมื่อเกิดเหตุการณ์ขึ้นให้เรียกเมธอดนี้ในคลาสฐาน คลาส 'active' ที่ถูกต้องจะจัดการกับมันแล้ว Paused()
ชั้นเองก็จะสามารถตรวจสอบว่ามันไม่ได้เป็น
ยังดีกว่าใช้รถบัสเหตุการณ์เช่นGreenRobot ของ , จัตุรัสแต่ที่หนึ่งจะเลิกและแนะนำให้ใช้RxJava
ฉันใช้เช็คif (!a.isFinishing())
และดูเหมือนว่าจะทำสิ่งที่ฉันต้องการ a
เป็นตัวอย่างกิจกรรม สิ่งนี้ไม่ถูกต้องหรือ ทำไมไม่มีใครลองสิ่งนี้
เกี่ยวกับอะไร activity.isFinishing()
ActivityLifecycleCallbacks เป็นวิธีที่ยอดเยี่ยมในการติดตามกิจกรรมทั้งหมดในแอพ:
public class BaseActivityLifecycleCallbacks implements Application.ActivityLifecycleCallbacks {
private ActivityState homeState, contentState;
@Override
public void onActivityCreated(Activity activity, Bundle bundle) {
if (activity instanceof HomeActivityv2) {
homeState = ActivityState.CREATED;
} else if (activity instanceof ContentDisplayActivity) {
contentState = ActivityState.CREATED;
}
}
@Override
public void onActivityStarted(Activity activity) {
if (activity instanceof HomeActivityv2) {
homeState = ActivityState.STARTED;
} else if (activity instanceof ContentDisplayActivity) {
contentState = ActivityState.STARTED;
}
}
@Override
public void onActivityResumed(Activity activity) {
if (activity instanceof HomeActivityv2) {
homeState = ActivityState.RESUMED;
} else if (activity instanceof ContentDisplayActivity) {
contentState = ActivityState.RESUMED;
}
}
@Override
public void onActivityPaused(Activity activity) {
if (activity instanceof HomeActivityv2) {
homeState = ActivityState.PAUSED;
} else if (activity instanceof ContentDisplayActivity) {
contentState = ActivityState.PAUSED;
}
}
@Override
public void onActivityStopped(Activity activity) {
if (activity instanceof HomeActivityv2) {
homeState = ActivityState.STOPPED;
} else if (activity instanceof ContentDisplayActivity) {
contentState = ActivityState.STOPPED;
}
}
@Override
public void onActivitySaveInstanceState(Activity activity, Bundle bundle) {
}
@Override
public void onActivityDestroyed(Activity activity) {
if (activity instanceof HomeActivityv2) {
homeState = ActivityState.DESTROYED;
} else if (activity instanceof ContentDisplayActivity) {
contentState = ActivityState.DESTROYED;
}
}
public ActivityState getHomeState() {
return homeState;
}
public ActivityState getContentState() {
return contentState;
}
}
ActivityState:
public enum ActivityState {
CREATED, STARTED, RESUMED, PAUSED, STOPPED, DESTROYED;
}
ขยายคลาสแอปพลิเคชันและให้การอ้างอิงในไฟล์ Android Manifest:
import android.app.Application;
public final class BaseApplication extends Application {
private BaseActivityLifecycleCallbacks baseALC;
@Override
public void onCreate() {
super.onCreate();
baseALC = new BaseActivityLifecycleCallbacks();
this.registerActivityLifecycleCallbacks(baseALC);
}
public BaseActivityLifecycleCallbacks getBaseALC() {
return baseALC;
}
}
ทำเครื่องหมายที่ใดก็ได้จากกิจกรรมเพื่อดูสถานะของกิจกรรมอื่น ๆ :
private void checkAndLaunchHomeScreen() {
Application application = getApplication();
if (application instanceof BaseApplication) {
BaseApplication baseApplication = (BaseApplication) application;
if (baseApplication.getBaseALC().getHomeState() == null || baseApplication.getBaseALC().getHomeState() == ActivityState.DESTROYED) {
//Do anything you want
}
}
}
https://developer.android.com/reference/android/app/Application.ActivityLifecycleCallbacks.html
ไม่แน่ใจว่ามันเป็นวิธีที่ "เหมาะสม" ในการ "ทำสิ่งต่าง ๆ "
หากไม่มีวิธี API ในการแก้ไขคำถาม (หรือ a) มากกว่าที่คุณคิดเล็ก ๆ น้อย ๆ บางทีคุณอาจทำอะไรผิดพลาดและอ่านเอกสารเพิ่มเติมแทนเป็นต้น
(เพราะฉันเข้าใจว่าตัวแปรแบบคงที่เป็นวิธีที่ผิดปกติใน Android มันสามารถใช้งานได้ แต่จะมีบางกรณีที่ไม่สามารถใช้งานได้ (ตัวอย่างเช่นในการผลิตบนอุปกรณ์กว่าล้านเครื่อง))
ในกรณีของคุณฉันขอแนะนำให้คิดว่าทำไมคุณต้องรู้ว่ากิจกรรมอื่นยังมีชีวิตอยู่หรือไม่ .. คุณสามารถเริ่มต้นกิจกรรมอื่นเพื่อให้ได้ผลลัพธ์ หรือคุณสามารถสืบทอดคลาสเพื่อรับฟังก์ชั่นของมันเป็นต้น
ขอแสดงความนับถืออย่างสูง.
หากคุณมีความสนใจในสถานะวงจรชีวิตของอินสแตนซ์เฉพาะของกิจกรรมวิธีการแก้ปัญหาของ siliconeagle มีลักษณะที่ถูกต้องยกเว้นว่าตัวแปร "ใช้งาน" ใหม่ควรเป็นตัวแปรอินสแตนซ์แทนที่จะเป็นแบบคงที่
ใช้การออกอากาศที่สั่งซื้อ ดูhttp://android-developers.blogspot.nl/2011/01/processing-ordered-broadcasts.html
ในกิจกรรมของคุณลงทะเบียนผู้รับใน onStart ยกเลิกการลงทะเบียนใน onStop ตอนนี้เมื่อตัวอย่างบริการจำเป็นต้องจัดการบางสิ่งบางอย่างที่กิจกรรมอาจทำได้ดีกว่าให้ส่งการออกอากาศที่สั่งซื้อจากบริการ (โดยมีตัวจัดการเริ่มต้นในบริการนั้น) ตอนนี้คุณสามารถตอบสนองในกิจกรรมเมื่อมันทำงาน บริการสามารถตรวจสอบข้อมูลผลลัพธ์เพื่อดูว่าการออกอากาศได้รับการจัดการและไม่ดำเนินการตามความเหมาะสมหรือไม่
นอกเหนือจากคำตอบที่ยอมรับแล้วหากคุณมีกิจกรรมหลายอินสแตนซ์คุณสามารถใช้ตัวนับแทน:
class MyActivity extends Activity {
static int activeInstances = 0;
static boolean isActive() {
return (activeInstance > 0)
}
@Override
public void onStart() {
super.onStart();
activeInstances++;
}
@Override
public void onStop() {
super.onStop();
activeInstances--;
}
}
คุณเคยลอง ..
if (getActivity() instanceof NameOfYourActivity){
//Do something
}
พบวิธีแก้ปัญหาง่ายๆด้วยรหัสต่อไปนี้
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if ((getIntent().getFlags() & Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT) != 0) {
// Activity is being brought to front and not being created again,
// Thus finishing this activity will bring the last viewed activity to foreground
finish();
}
}
ใช้ตัวแปร isActivity เพื่อตรวจสอบว่ากิจกรรมยังมีชีวิตอยู่หรือไม่
private boolean activityState = true;
@Override
protected void onDestroy() {
super.onDestroy();
activityState = false;
}
จากนั้นตรวจสอบ
if(activityState){
//add your code
}
หากคุณต้องการตรวจสอบว่ากิจกรรมอยู่ในกองหลังหรือไม่ให้ทำตามขั้นตอนต่อไป 1. ประกาศ ArrayList ในคลาสแอปพลิเคชันของคุณ [คลาสแอปพลิเคชันถูกกำหนดในไฟล์ mainfest ของคุณในแท็กแอปพลิเคชัน]
private ArrayList<Class> runningActivities = new ArrayList<>();
และเพิ่มวิธีการสาธารณะต่อไปนี้เพื่อเข้าถึงและแก้ไขรายการนี้
public void addActivityToRunningActivityies (Class cls) {
if (!runningActivities.contains(cls)) runningActivities.add(cls);
}
public void removeActivityFromRunningActivities (Class cls) {
if (runningActivities.contains(cls)) runningActivities.remove(cls);
}
public boolean isActivityInBackStack (Class cls) {
return runningActivities.contains(cls);
}
ใน BaseActivity ของคุณที่กิจกรรมทั้งหมดขยายให้แทนที่เมธอด onCreate และ onDestroy เพื่อให้คุณสามารถเพิ่มและลบกิจกรรมจาก back stack ดังต่อไปนี้
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
((MyApplicationClass)getApplication()).addActivityToRunningActivityies
(this.getClass());
}
@Override
protected void onDestroy() {
super.onDestroy();
((MyApplicationClass)getApplication()).removeActivityFromRunningActivities
(this.getClass());
}
ในที่สุดหากคุณต้องการตรวจสอบว่ากิจกรรมอยู่ในกองหลังหรือไม่เพียงแค่เรียกใช้ฟังก์ชันนี้ isActivityInBackStack
เช่นฉันต้องการตรวจสอบ HomeActivityis ใน back stack หรือไม่:
if (((MyApplicationClass)
getApplication()).isActivityInBackStack(HomeActivity.class)) {
// Activity is in the back stack
} else {
// Activity is not in the back stack
}
public static boolean isActivityActive(Activity activity) {
return !activity.isFinishing() &&
(SDK_INT < JELLY_BEAN_MR1 || !activity.isDestroyed());
}
ใช้ได้ผลถ้าคุณไม่มีกิจกรรมเดียวกันในเบื้องหน้า หากคุณเปิดจากการแจ้งเตือนไม่ทำงานฉันได้ทำการปรับแต่งแล้วมาพร้อมกับสิ่งนี้:
public static boolean ativo = false;
public static int counter = 0;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
...
counter++;
}
@Override
protected void onStart() {
super.onStart();
ativo = true;
}
@Override
protected void onStop() {
super.onStop();
if (counter==1) ativo = false;
}
@Override
protected void onDestroy() {
counter--;
super.onDestroy();
}
ที่เหมาะกับฉันด้วยกิจกรรมหลายอย่างที่เปิดในเวลาเดียวกัน