您的位置:首页 > 移动开发 > Android开发

如何判断android activity是否运行

2016-02-27 16:20 477 查看
android对于我们来说是一个复杂的且拥有多种逻辑类别的系统。这对于我们来说是一件好事但是也给我们带来处理一个相同问题会带来更多的复杂性。接下来我们会检查activity是否在你的应用中存在

 

介绍

我们会需要一个持续运行的服务,这个服务会从远程站点获取信息或者做类似事情来给我们带来一些特殊利益。在当时我这个服务获取到一些信息并传送到activity中。如果这个activity运行在前端那并没有什么问题,然后我们怎么确定activity运行在前端呢?

这个问题有多重决绝方法,所有的方法都有利有弊。我们将展现所有的处理方法并列出利弊

 

ActivityManager

首先我们关注下ActivityManager(AM)。AM维持了一个运行时任务记录和最上层任务记录。也许AM中最后的一个任务就是我们的兴趣所在

 
public boolean isForeground(String PackageName){
// Get the Activity Manager
ActivityManager manager = (ActivityManager) getSystemService(ACTIVITY_SERVICE);

// Get a list of running tasks, we are only interested in the last one,
// the top most so we give a 1 as parameter so we only get the topmost.
List< ActivityManager.RunningTaskInfo > task = manager.getRunningTasks(1);

// Get the info we need for comparison.
ComponentName componentInfo = task.get(0).topActivity;

// Check if it matches our package name.
if(componentInfo.getPackageName().equals(PackageName)) return true;

// If not then our app is not on the foreground.
return false;
}


 

利:你可以直接的得到你需要的信息,但是更准确的说google对于其还有歧义的,google强烈建议你仅在调试模式下使用。

 

利:没有保存任意类型的变量,只是查看了android的任务栈,所以无论在什么原因下没有任何东西会被删除。

 

弊:获取最顶层的应用或许不是最完整的解决方案。因为你的app可能有很多原因造成其不是一个顶端app,但我们依旧会认为他依然在最顶端并按照此推断去处理。

 

弊:google文档明确的指出不要使用这段代码除了在调试或者管理任务接口时,所以这不是一个可靠的方式并且在未来的android版本也将不可靠

 

弊:你必须在manifest配置中增加GET_TASKS的权限,这或许不是那么友好吧

 

 

弊:由于我们没有系统的控制权,所以你将不会知道系统在任何情况下是怎么处理的,所以你只能假设这一切都运行的非常完好,并且在我们的使用者中这一切在任何情况下都没有发生。

 

static variable

从代码层面上,最简单的方法就是使用静态变量,静态变量在现代编码中被使用的非常多且总是备受争议,但是我们依旧在很多地方看到并使用。
 
public class example extends Activity {
static boolean isActive = false;

@Override
protected void onStart() {
super.onStart();
isActive = true;
}

@Override
protected void onStop() {
super.onStop();
isActive = false;
}
}

 利:非常简便的代码
 
利:很难被用户或者android自身回收
 
利:你可以有很高的控制权并很容易的按照你的实现将Activity分类,就如同最上层Activity这么一个分类
 
弊:静态变量等等其他变量是被关联到一个类实例的,这就是意味着只有类加载器加载的类被卸载了这些变量才会被卸载。一般来说只有当应用被杀死后静态变量才会一起被杀死。然后android在一般情况下不会销毁一些老的历史任务。我们需要注意,如果我们申明一个静态Activity或者context,且静态变量存在复杂的引用关系,那么其不会被销毁,更可怕的是可能带来内存泄露问题。所以请确保当你不在需要这些静态变量时,把他们赋值成null,以让垃圾回收机制处理。在我们的例子中并不是一个反面例子,我们只是存储了一个boolean类型的值,这不会带来内存泄露问题,但是你依然需要清楚静态变量会带来什么,这就是为什么网络上市场出现这类讨论的原因。
 
弊:如上的函数并不会一直被调用,所以得不到一个真实的状态。如果一个app崩溃了,其不会调用onStop()函数。你可以通过定义一个默认的异常处理机制来弥补这个问题,并把状态设定成false。可能还有更多的情况我们未控制,但也有其他觉得方法。
 
弊:尽管静态变量在被销毁后,再次初始化可以被赋予他们的默认值,但这也会在某些情况下带来不可预料的情况。例如崩溃
 
shared preferences

和静态变量类似,shared preferences 可以共享其他Activity和service的状态
 
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();

}
}

 利:shared
preferences 不会被android销毁
 

利:shared
preferences 不会被重置成默认值

 

利:
你可以有很高的控制权并很容易的按照你的实现将Activity分类,就如同最上层Activity这么一个分类
 
弊:shared preferences可以被用户手动清除,这种情况你是无法知道的,这会让你的系统出问题。
 
弊:如上的函数并不会一直被调用,所以得不到一个真实的状态。如果一个app崩溃了,其不会调用onStop()函数。你可以通过定义一个默认的异常处理机制来弥补这个问题,并把状态设定成false。可能还有更多的情况我们未控制,但也有其他觉得方法。
 
 

结论
 
我们更喜欢使用shared preferences。其有最可靠的状态信息,
可以减少app被销毁带来的问题,不需要更多的权限,当我们的Activity在最上层是他给我们更多的决定权,去做一些事情。
 
 
异常处理
 
在上述几个章节提到的错误处理问题,你可以通过创建一个默认的异常处理机制来处理,你可以把这段函数放在onCreate()的最前面
 

 
final Thread.UncaughtExceptionHandler defaultHandler = Thread.getDefaultUncaughtExceptionHandler();

Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
@Override
public void uncaughtException(Thread thread, Throwable throwable) {
// fix our issues for static variables
isActive = false;

// fix our issues for sharedpreferences
SharedPreferences sp = getSharedPreferences("OURINFO", MODE_PRIVATE);
Editor ed = sp.edit();
ed.putBoolean("active", false);
ed.commit();

// Handle everthing else
defaultHandler.uncaughtException(thread, throwable);
}
});
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: