每当我的广播被执行时,我希望向前台活动显示警报。
不要使用之前的回答(waqas716)。
您可能会遇到内存泄漏问题,这是由于对活动的静态引用引起的。有关更多详细信息,请参见以下链接http://android-developers.blogspot.fr/2009/01/avoiding-memory-leaks.html
为了避免这种情况,您应该管理活动引用。 将应用程序名称添加到清单文件中:
<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类来创建您的活动,只需要扩展MyBaseActivity即可。现在,您可以像这样从应用程序或Activity上下文中获取当前活动:
Activity currentActivity = ((MyApp)context.getApplicationContext()).getCurrentActivity();
Application.ActivityLifecycleCallbacks
,这将更加集中化,您不需要在所有活动中添加任何管理代码。另请参见http://developer.android.com/reference/android/app/Application.html#registerActivityLifecycleCallbacks(android.app.Application.ActivityLifecycleCallbacks)。 - Filou我在@gezdy的答案基础上进行了拓展。
在每个活动中,我们可以利用以下API(从14级开始)来帮助我们实现类似的目的,而无需手动编码将其自身“注册”到Application
中。
public void registerActivityLifecycleCallbacks (Application.ActivityLifecycleCallbacks callback)
在 Application.ActivityLifecycleCallbacks
中,你可以获取哪个 Activity
被 "附加" 或 "解除附加" 到这个 Application
上。
然而,此技术仅适用于 API 级别 14 及以上。
Application.ActivityLifecycleCallbacks
接口的类,添加实现该接口所需的方法即可。然后在那个类的构造函数(或 onCreate 或 init 或其他在实例变为活动/准备就绪状态时运行的方法)中,将 getApplication().registerActivityLifecycleCallbacks(this);
作为最后一行放入即可。 - ToolmakerSteve更新 3: 现已添加了官方API, 请使用 ActivityLifecycleCallbacks 替代。
Application
仅创建一次,永远不会像静态变量一样被垃圾回收。 - zaplclearReferences()
中的条件为 (this.equals(currActivity))
。 - naXa stands with Ukraine了解到 ActivityManager 管理着 Activity,因此我们可以从 ActivityManager 获取信息。我们通过以下方式获取当前正在运行的前台 Activity:
ActivityManager am = (ActivityManager)context.getSystemService(Context.ACTIVITY_SERVICE);
ComponentName cn = am.getRunningTasks(1).get(0).topActivity;
更新于2018/10/03:
getRunningTasks() 方法已被弃用,请参考以下解决方案。
该方法在API 21级别中已被弃用。从Build.VERSION_CODES.LOLLIPOP版本开始,第三方应用程序将无法使用此方法:由于文档为中心的最近文档的引入,它可能会向调用者泄露个人信息。为了向后兼容,它仍将返回其数据的一小部分:至少是调用者自己的任务,以及可能是一些其他任务(例如Home等),它们被认为不是敏感信息。
我使用 Kotlin 进行了以下操作
按照以下方式编辑应用程序类:
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
}
}
}
创建ActivityLifecycleCallbacks类。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
}
}
现在您可以通过调用以下代码在任何类中使用它:FTApplication.currentActivity()
getCurrentActivity() 也在 ReactContextBaseJavaModule 中。
(自从最初提出这个问题以来,许多 Android 应用程序也具有 ReactNative 组件 - 混合应用程序。)
ReactNative 中的 ReactContext 类拥有维护 mCurrentActivity 的整套逻辑,该逻辑在 getCurrentActivity() 中返回。
注意:我希望 getCurrentActivity() 在 Android 应用程序类中实现。
为了向后兼容:
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;
}
Application
类中保留并获取 WeakReference
句柄,而 ComponentName
则需要确定所需的 Activity
是否在正在运行的任务列表的顶部。如果这不能完全回答问题,那么被接受的答案也不是。 - Martin ZeitlertopActivity
仅在 Android Q 及以上版本可用。 - Eugen Martynov我们没有找到一种让团队满意的解决方案,所以我们自己开发了一个。我们使用 ActivityLifecycleCallbacks
来跟踪当前活动,并通过服务公开它。更多详细信息请参见此处:https://dev59.com/tm865IYBdhLWcg3wUs7z#38650587
public class ActivityManager implements Application.ActivityLifecycleCallbacks {
private Activity activity;
public ActivityManager(App myApplication) {
myApplication.registerActivityLifecycleCallbacks(this);
}
public Activity getActivity(){
return activity;
}
@Override
public void onActivityCreated(@NonNull Activity activity, @Nullable Bundle bundle) {
this. activity = activity;
}
@Override
public void onActivityStarted(@NonNull Activity activity) {
this. activity = activity;
}
@Override
public void onActivityResumed(@NonNull Activity activity) {
this. activity = activity;
}
@Override
public void onActivityPaused(@NonNull Activity activity) {
}
@Override
public void onActivityStopped(@NonNull Activity activity) {
}
@Override
public void onActivitySaveInstanceState(@NonNull Activity activity, @NonNull Bundle bundle) {
}
@Override
public void onActivityDestroyed(@NonNull Activity activity) {
}
}
然后在你的应用程序中初始化它(kotlin)
class App : Application() {
override fun onCreate() {
appOpenManager = AppOpenManager(this);
}
companion object {
lateinit var appOpenManager: AppOpenManager
}
}
android.app.Application
并实现ActivityLifecycleCallbacks
接口的类。在Application.onCreate()
中,注册回调函数。public class App extends Application implements ActivityLifecycleCallbacks
@Override
public void onCreate() {
super.onCreate();
registerActivityLifecycleCallbacks(this);
}
<application
android:name=".App"
public interface ActivityLifecycleCallbacks {
void onActivityCreated(Activity activity, Bundle savedInstanceState);
void onActivityStarted(Activity activity);
void onActivityResumed(Activity activity);
void onActivityPaused(Activity activity);
void onActivityStopped(Activity activity);
void onActivitySaveInstanceState(Activity activity, Bundle outState);
void onActivityDestroyed(Activity activity);
}
因此,当您的任何活动(您创建或通过库包含的活动)经历上述任何一个生命周期方法时,这些回调将被调用。 当应用程序在前台时,至少会有一个处于启动状态的活动,并且当应用程序在后台时,不会有任何活动处于启动状态。 在“App”类中声明以下2个变量。
private int activityReferences = 0;
private boolean isActivityChangingConfigurations = false;
activityReferences会记录处于started状态的Activity数量。isActivityChangingConfigurations是一个标志,用于指示当前Activity是否正在进行配置更改,例如方向切换。 使用以下代码,您可以检测应用程序是否进入前台。
@Override
public void onActivityStarted(Activity activity) {
if (++activityReferences == 1 && !isActivityChangingConfigurations) {
// App enters foreground
}
}
activity.getBaseContext()
这是如何检测应用程序是否进入后台的方法。
Override
public void onActivityStopped(Activity activity) {
isActivityChangingConfigurations = activity.isChangingConfigurations();
if (--activityReferences == 0 && !isActivityChangingConfigurations) {
// App enters background
}
}
现在您可以访问当前前台活动的名称和上下文。
getApplicationContext
不会返回一个活动,因此在此用途中无法工作。 - ToolmakerSteve