android - 与 Activity 生命周期相关的监听器行为

标签 android callback listener sharedpreferences android-lifecycle

我有一个带有私有(private) OnSharedPreferenceChangeListener 的 Activity ,监听器的工作是在 Activity 的 onCreate() 方法上定义的。监听器已注册到应用程序的 sharedPreferences。

更改本身是由服务触发的,以响应收到的短信 Intent 。

当Activity本身死亡时,监听器会收到回调吗?有没有不会的情况?

监听器定义(大致):

private OnSharedPreferenceChangeListener _sharedPreferenceListener;

public void onCreate(Bundle bundle){
...
_prefs = PreferenceManager.getDefaultSharedPreferences(this);
_prefs.registerOnSharedPreferenceChangeListener(_sharedPreferenceListener);
...
_sharedPreferenceListener = new SharedPreferences.OnSharedPreferenceChangeListener(){ /*doing some work here*/};
...
}

请忽略此处的逻辑是否正确,假设代码有效,我主要关心的是监听器如何对 Activity 生命周期中的变化使用react。

谢谢,

最佳答案

实际上,由于监听器对 Activity 一无所知(因此您可以在任何地方使用它,而不仅仅是在 Activity 中),无论您在哪里使用它,您都会收到通知。

此外,由于您无法确定它对 context 做了什么,因此在这种情况下您应该使用应用程序上下文(这样您就不会发生内存泄漏,尽管我怀疑它需要引用 Activity )。

当然,如果监听器本身被弱引用引用,并且 Activity 在任何其他类上没有任何对自身的引用,那么监听器也可以被 GC 处理。您可以在 Android(或至少 API 19)的代码中看到,在类“android.app.SharedPreferencesImpl”(示例链接 here)中,您有一个 WeakHashMap 监听器,所以这可能意味着托管监听器的 Activity 可以进行 GC 处理,因此监听器将停止被调用。 Android相关代码如下:

private final WeakHashMap<OnSharedPreferenceChangeListener, Object> mListeners =
        new WeakHashMap<OnSharedPreferenceChangeListener, Object>();

...
public void registerOnSharedPreferenceChangeListener(OnSharedPreferenceChangeListener listener) {
    synchronized(this) {
        mListeners.put(listener, mContent);
    }
}

因此,正如我所写的,如果您希望继续收听此事件,最好只放置应用程序上下文。

或者,如果您确实希望停止收听此事件,只需在 Activity 被销毁时取消注册即可。

为了证明这一点,您只需运行您的应用...

这是我的证明应用程序:

主 Activity .java

public class MainActivity extends Activity {

    @Override
    protected void onCreate(final Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        final SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
        preferences.registerOnSharedPreferenceChangeListener(new SharedPreferences.OnSharedPreferenceChangeListener() {

            @Override
            public void onSharedPreferenceChanged(final SharedPreferences sharedPreferences, final String key) {
                android.util.Log.d("AppLog", "changed!");
            }
        });
        new Handler().postDelayed(new Runnable() {

            @Override
            public void run() {
                startActivity(new Intent(MainActivity.this, Activity2.class));
            }
        }, 1000);
        finish();
    }

}

Activity2.java

public class Activity2 extends Activity {

    @Override
    protected void onCreate(final Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_activity2);
        //if you call here System.gc(); , you have a good chance that the listener won't be called
        new Handler().postDelayed(new Runnable() {

            @Override
            public void run() {
                //this may or may not cause the listener to write to the log
                final SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(Activity2.this);
                preferences.edit().putBoolean("test", true).commit();
            }

        }, 1000);

    }

}

关于android - 与 Activity 生命周期相关的监听器行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20860137/

相关文章:

java - Android 上下文菜单项文本未显示

javascript - 仅当窗口宽度调整大小时才调用 jquery 函数

php - 从服务器设置图像后如何刷新 ImageView 在我的情况下,它不更新 ImageView

java - 找不到以下类: Names of layouts

javascript - 直接调用方法和使用 '.call' 方法的区别? JS

c++ - Qt : qt cannot send events to objects owned by a different thread - Why

javascript - 由于异步函数,函数过早返回值

android - 带有 ImageButton 和 TextField 的 RelativeLayout 上的 setOnClickListener

java - 将 mouseListener 添加到我的 java 对象中

HTML5 Swiffy 动画完成时的 JavaScript 监听器?