2

For some reason my android ContentObserver is being registered multiple times. The ContentObserver is defined as an inner class in my main Activity. It is then instantiated and registered in my onCreate() method.

I think that onCreate() is being called multiple times, as well as my main Activity in general being instantiated multiple times. To prevent this, I've tried adding a launchMode to my Android Manifest, but it doesn't seem to have worked:

<activity android:name=".MainActivity"
    android:label="@string/app_name"
    android:launchMode="singleInstance">

I've also tried unregistering Oberservers before registering in my onCreate, but I think because it's a new instance of my main Activity, it doesn't do anything.

public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    this.contentResolver = this.getApplicationContext().getContentResolver();
    this.myObserver = new MyObserver(this.contentResolver);

    this.contentResolver.unregisterContentObserver(this.myObserver);
    this.contentResolver.registerContentObserver(MainActivity.myObserveUri, true, this.myObserver);
}

private class MyObserver extends ContentObserver {
    public MyObserver(ContentResolver contentResolver) {
        super(null);
        //My Code
    }
}

Any ideas for how I can prevent this from happening? I also have a runnable and a handler created in my main Activity that I have set to run periodically, which is experiencing the same problem. Ideally, a fix would solve that problem as well. I'm pretty sure the underlying issue is that my main Activity is being instantiated more than once, but since launchMode didn't fix it I'm not sure where to turn next.

Any help is greatly appreciated. Thanks

2 Answers 2

1

You need to grasp the underlying issue, which is the Android Activity lifecycle Then you could tackle some of this with Singletons if needed (which I doubt).

2
  • The observer is meant to run indefinitely, and I never call finish() on my main Activity. Does that mean that the only way new activities are being created are if the system temporarily destroys the old one? If so, I think I could unregister my ContentObserver in onDestroy() and then it will be re-registered in onCreate() shortly after. Would this work? I think I would prefer to keep my initial observer, and stop additional ones from being created.
    – Colin
    Commented Apr 22, 2011 at 20:17
  • Very broad topic... onDestroy()/onCreate() come about for a variety of reasons -- landscape to portrait move (if your app/views allow it), OS memory reclamation... You really need to know the underlying framework.
    – Dan
    Commented Apr 22, 2011 at 20:21
1

Use this:

import android.database.ContentObserver;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;

public class MyActivity extends AppCompatActivity {

    public static final Uri CONTENT_OBSERVER_URI = Uri.parse("content://example/system");
    private MyContentObserver myContentObserver;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        myContentObserver = new MyContentObserver(new Handler());
    }

    @Override
    protected void onResume() {
        super.onResume();
        getContentResolver().registerContentObserver(
                CONTENT_OBSERVER_URI, true, myContentObserver);
    }

    @Override
    protected void onPause() {
        super.onPause();
        getContentResolver().unregisterContentObserver(myContentObserver);
    }

    private class MyContentObserver extends ContentObserver {
        MyContentObserver(Handler handler) {
            super(handler);
        }

        @Override
        public void onChange(boolean selfChange) {
            super.onChange(selfChange);
            Log.d("MY_APP", "A content URI was changed");
        }
    }
}
2
  • 1
    Registering on onCreate is not necessary as it is already being done on onResume. Commented Dec 12, 2014 at 3:51
  • 1
    @Farhan, Tiago: I've clarified the code to register the Content Observer once when the Activity is active (onResume), and unregister it when the Activity is inactive (onPause)
    – Mr-IDE
    Commented Oct 23, 2019 at 14:39

Not the answer you're looking for? Browse other questions tagged or ask your own question.