是否有任何简单的方法来确定某项活动是否有效? 我想根据哪些活动是活跃的来做某些事情。 例如:
if(activityrunning == activity1)
//do this
else if (activityrunning == activity2)
//do something else
答案 0 :(得分:209)
您可以在活动中使用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;
}
}
唯一的问题是,如果你在两个相互链接的活动中使用它,那么第一个onStop
有时会在第二个onStart
之后调用。所以两者都可能是短暂的。
取决于您要执行的操作(从服务更新当前活动?)。您可以在活动onStart
方法中在服务中注册静态侦听器,然后当您的服务想要更新UI时,正确的侦听器将可用。
答案 1 :(得分:39)
我认为更清楚:
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;
}
答案 2 :(得分:23)
比使用静态变量并遵循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();
}
}
使用共享偏好设置。它具有最可靠的状态信息,较少的应用程序切换/销毁问题,节省了我们请求另一个权限,它让我们有更多的控制权来决定我们的活动何时实际上是最顶层的。见details here abd here also
答案 3 :(得分:20)
我使用了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;
}
答案 4 :(得分:20)
不使用任何辅助变量的选项是:
activity.getWindow().getDecorView().getRootView().isShown()
其中activity是f.e。:this或getActivity()。
此表达式返回的值在onStart()/ onStop()中更改,这些事件是启动/停止显示手机上活动布局的事件。
答案 5 :(得分:9)
这是用于检查特定服务是否正在运行的代码。只要您使用getRunningAppProcesses()或getRunningTasks()更改getRunningServices,我相当确定它也可以用于活动。看看http://developer.android.com/reference/android/app/ActivityManager.html#getRunningAppProcesses()
相应地更改Constants.PACKAGE和Constants.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;
}
答案 6 :(得分:6)
谢谢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与用户正在进行的操作匹配,则此示例将为您提供true或false。因此,如果您正在检查的活动没有显示(即是onPause),那么您将无法获得匹配。此外,要执行此操作,您需要向清单添加权限..
<uses-permission android:name="android.permission.GET_TASKS"/>
我希望这有用!
答案 7 :(得分:4)
我意识到这个问题已经很久了,但是我认为仍然值得分享我的解决方案,因为它可能对其他人有用。
此解决方案在发布Android体系结构组件之前不可用。
活动至少部分可见
getLifecycle().getCurrentState().isAtLeast(STARTED)
活动处于前台
getLifecycle().getCurrentState().isAtLeast(RESUMED)
答案 8 :(得分:4)
我认为接受的答案是处理这个问题的可怕方法。
我不知道用例是什么,但请考虑基类中的受保护方法
@protected
void doSomething() {
}
并在派生类中覆盖它。
当事件发生时,只需在基类中调用此方法即可。正确的“主动”类将处理它。然后,类本身可以检查它是否不是Paused()
。
更好的是,使用GreenRobot's,Square's等事件总线,但不推荐使用该事件总线并建议使用RxJava
答案 9 :(得分:3)
有一种比上述方法更容易的方法,这种方法不需要在清单中使用android.permission.GET_TASKS
,或者在接受的答案中指出竞争条件或内存泄漏的问题。
在主Activity中创建一个STATIC变量。 Static允许其他活动从另一个活动接收数据。 onPause()
设置此变量 false ,onResume
和onCreate()
设置此变量 true 。
private static boolean mainActivityIsOpen;
分配此变量的getter和setter。
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
}
答案 10 :(得分:2)
if(!activity.isFinishing() && !activity.isDestroyed())
答案 11 :(得分:2)
activity.isFinishing()
答案 12 :(得分:2)
ActivityLifecycleCallbacks是跟踪App中所有活动的好方法:
public enum ActivityState {
CREATED, STARTED, RESUMED, PAUSED, STOPPED, DESTROYED;
}
ActivityState:
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;
}
}
扩展Application类并在Android Manifest文件中提供它的引用:
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
}
}
}
从活动中的任何地方Ckeck获取其他活动的状态:
parent.children.where('id > ?', start_row)
https://developer.android.com/reference/android/app/Application.ActivityLifecycleCallbacks.html
答案 13 :(得分:1)
如果要检查活动是否在后排堆栈中,请遵循以下步骤。 1.在Application类中声明一个ArrayList [Application类在您的mainfest文件中的application标签中定义]
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方法,以便您可以按以下方式从后向堆栈中添加和删除活动。
@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。
例如:我想检查HomeActivity是否在后面的堆栈中:
if (((MyApplicationClass)
getApplication()).isActivityInBackStack(HomeActivity.class)) {
// Activity is in the back stack
} else {
// Activity is not in the back stack
}
答案 14 :(得分:1)
您尝试过吗。
if (getActivity() instanceof NameOfYourActivity){
//Do something
}
答案 15 :(得分:1)
我使用了支票if (!a.isFinishing())
,它似乎做了我需要的。 a
是活动实例。这是不正确的?为什么没有人试试这个?
答案 16 :(得分:1)
除了the accepted answer之外,如果您有多个活动实例,则可以使用计数器:
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--;
}
}
答案 17 :(得分:1)
使用有序广播。见http://android-developers.blogspot.nl/2011/01/processing-ordered-broadcasts.html
在您的活动中,在onStart中注册接收器,在onStop中注销。现在,例如,当服务需要处理活动可能做得更好的事情时,从服务发送有序广播(在服务本身中使用默认处理程序)。您现在可以在活动运行时进行响应。该服务可以检查结果数据以查看是否处理了广播,如果没有采取适当的措施。
答案 18 :(得分:1)
如果您对活动的特定实例的生命周期状态感兴趣,那么siliconagle的解决方案看起来是正确的,除了新的“活动”变量应该是实例变量,而不是静态。
答案 19 :(得分:1)
不确定这是“做事”的“正确”方式
如果没有API方法来解决(或)问题而不是你应该想一点,也许你做错了什么并阅读更多文档等等。
(据我所知,静态变量在android中是一种常见的错误方式。因为它可以起作用,但肯定会出现无法工作的情况[例如,在生产中,在百万台设备上]。)
在你的情况下,我建议认为为什么你需要知道另一个活动是否还活着吗?你可以为结果启动另一个活动来获得它的功能。或者你可以派出类来获得它的功能等等
最诚挚的问候。
答案 20 :(得分:0)
我使用task.topActivity代替task.baseActivity,它对我来说很好用。
protected Boolean isNotificationActivityRunning() {
ActivityManager activityManager = (ActivityManager) getBaseContext().getSystemService(Context.ACTIVITY_SERVICE);
List<ActivityManager.RunningTaskInfo> tasks = activityManager.getRunningTasks(Integer.MAX_VALUE);
for (ActivityManager.RunningTaskInfo task : tasks) {
if (task.topActivity.getClassName().equals(NotificationsActivity.class.getCanonicalName()))
return true;
}
return false;
}
答案 21 :(得分:0)
public static boolean isActivityActive(Activity activity) {
return !activity.isFinishing() &&
(SDK_INT < JELLY_BEAN_MR1 || !activity.isDestroyed());
}
答案 22 :(得分:0)
我知道这个问题很老,答案很多,带有各种优点和缺点。我对此的看法是,为什么不推出自己的IPC实现。
class IPC {
companion object {
private val appContext : Context by lazy { /*genericApplicationContext*/ }
fun initIPC(process: String){
var file : File? = null
file = File(appContext.cacheDir.absolutePath + "/$process")
var output : OutputStream? = null
try {
output = FileOutputStream(file!!)
output.write(0)
} finally {
output?.close()
}
}
fun destroyIPC(process: String){
var file : File? = null
file = File(appContext.cacheDir.absolutePath + "/$process")
file.delete()
}
fun checkForIPC(process: String) : Boolean {
var file : File? = null
file = File(appContext.cacheDir.absolutePath + "/$process")
if(file.exists()) return true
return false
}
}
}
这允许您在启动活动之前创建文件,然后在关闭启动的活动时关闭“进程/文件”。这使您可以在后台线程或当前活动中签入您的“流程活动”是否在后台,以查看文件是否仍处于打开状态以表明该活动仍在运行。就我而言,我是连续调用一个外部API,但需要对调用进行速率限制,因此请使用该方法来确保一次只有一个活动在活着地调用API。
答案 23 :(得分:0)
使用isActivity变量检查活动是否有效。
private boolean activityState = true;
@Override
protected void onDestroy() {
super.onDestroy();
activityState = false;
}
然后检查
if(activityState){
//add your code
}
答案 24 :(得分:0)
使用以下代码找到一个简单的解决方法
@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();
}
}
答案 25 :(得分:-1)
如果您在前台没有相同的活动,则可以进行此工作。 如果您从通知中打开不起作用,我会进行一些调整并附带以下内容:
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();
}
这对我来说很有效,同时可以进行多个活动。