小智 203
(注意: API 14中添加了官方API:请参阅此答案/sf/answers/2085051601/)
不要使用上一个(waqas716)的答案.
由于对活动的静态引用,您将遇到内存泄漏问题.有关更多详细信息,请参阅以下链接http://android-developers.blogspot.fr/2009/01/avoiding-memory-leaks.html
为避免这种情况,您应该管理活动参考.在清单文件中添加应用程序的名称:
<application
android:name=".MyApp"
....
</application>
Run Code Online (Sandbox Code Playgroud)
你的申请类:
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;
}
}
Run Code Online (Sandbox Code Playgroud)
创建一个新的活动:
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);
}
}
Run Code Online (Sandbox Code Playgroud)
因此,现在不要为您的活动扩展Activity类,只需扩展MyBaseActivity.现在,您可以从应用程序或活动上下文中获取当前活动:
Activity currentActivity = ((MyApp)context.getApplicationContext()).getCurrentActivity();
Run Code Online (Sandbox Code Playgroud)
Che*_*eng 65
我扩展了@ gezdy的答案.
在每个活动中,Application
我们不需要使用手动编码"注册"自己,而是从14级开始使用以下API,以帮助我们实现类似的目的,减少手动编码.
public void registerActivityLifecycleCallbacks (Application.ActivityLifecycleCallbacks callback)
Run Code Online (Sandbox Code Playgroud)
在Application.ActivityLifecycleCallbacks
,你可以得到哪个Activity
"附加"或"分离"到这个Application
.
但是,此技术仅在API级别14之后可用.
Waq*_*qas 51
更新2:为此添加了官方API,请使用ActivityLifecycleCallbacks.
更新:
正如@gezdy指出的那样,我很感激.对于当前活动也设置对null的引用,而不是仅在每个onResume上更新,在每个Activity的onDestroy上将其设置为null以避免内存泄漏问题.
前一段时间我需要相同的功能,这是我实现这一目标的方法.在您的每个活动中覆盖这些生命周期方法.
@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);
}
Run Code Online (Sandbox Code Playgroud)
现在,在您的广播课程中,您可以访问当前活动以在其上显示警报.
AZ_*_*AZ_ 48
@lockwobr感谢您的更新
这在api版本16中没有100%的时间工作,如果你在github上读取代码,函数"currentActivityThread"在Kitkat中发生了变化,所以我想说版本19ish,有点难以匹配api版本到github中的版本.
能够访问当前Activity
非常方便.使用静态getActivity
方法返回当前活动并没有不必要的问题,这不是很好吗?
这Activity
门课非常有用.它可以访问应用程序的UI线程,视图,资源等等.许多方法需要一个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;
}
Run Code Online (Sandbox Code Playgroud)
这种方法可以在应用程序的任何地方使用,它比所有提到的方法更方便.而且,它看起来并不像它看起来那样不安全.它不会引入任何新的潜在泄漏或空指针.
上面的代码片段没有异常处理,天真地假设第一个正在运行的Activity是我们正在寻找的.您可能想要添加一些额外的检查.
KAl*_*lO2 35
知道ActivityManager管理Activity,所以我们可以从ActivityManager获取信息.我们得到当前前台运行的Activity
ActivityManager am = (ActivityManager)context.getSystemService(Context.ACTIVITY_SERVICE);
ComponentName cn = am.getRunningTasks(1).get(0).topActivity;
Run Code Online (Sandbox Code Playgroud)
更新2018/10/03
getRunningTasks()已弃用.看下面的解决方案.
此方法在API级别21中已弃用.从Build.VERSION_CODES.LOLLIPOP开始,此方法不再可用于第三方应用程序:引入以文档为中心的最新文件意味着它可以将人员信息泄露给调用者.为了向后兼容,它仍将返回其数据的一小部分:至少是调用者自己的任务,以及可能已知不敏感的其他一些任务,如home.
Ras*_*d.Z 15
我在 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
}
}
}
Run Code Online (Sandbox Code Playgroud)创建 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
}
}
Run Code Online (Sandbox Code Playgroud)您现在可以通过调用以下命令在任何类中使用它: FTApplication.currentActivity()
为了向后兼容:
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;
}
Run Code Online (Sandbox Code Playgroud)
getCurrentActivity()也在ReactContextBaseJavaModule中.
(由于这个问题最初被问到,许多Android应用程序也有ReactNative组件 - 混合应用程序.)
ReactNative中的类ReactContext具有整个逻辑集来维护在getCurrentActivity()中返回的mCurrentActivity.
注意:我希望getCurrentActivity()在Android Application类中实现.