0

I am developing an online mp3 player, and at the beginning I decided not to use Service - because there are a lot of data to pass around: it gets very complicated using AIDL. Instead I let the Player as a global singleton. The app is almost done, everything works fine (music plays even when the screen is turned off) - but sometimes the whole process got killed !

So I tried to "trick" the OS by start a local dummy Service (say: DummyService) whenever the music gets started, and stop DummyService whenever the music stops. But that doesn't help much, the process still gets killed fairly often :(.

IMHO if my application process has a "running" Service - it will get a better chance not to get killed by the android OS. And the DummyService is not much different from a Service that hosts a MediaPlayer - because the MediaPlayer is also not playing on the UI thread (default thread when a Service get called ).

So the question is: Are there any differences between my player (global static Player + DummyService) and a player which is wrapped by a service (e.g: MusicDroid here http://www.helloandroid.com/tutorials/musicdroid-audio-player-part-ii )

Thank you for your attentions, Pham Hung Son

hungson175
  • 4,373
  • 6
  • 22
  • 21

3 Answers3

1

Your problem is gonna be the Singleton implementation. You can read a lot of debate wheter it is suited for DalvikVM or not. This is an example why it is not. The Dalvik GC gonna eat your Singleton, you need another kind of implementation.

0

using your answer as a hint, I've searched over again, and found some good stuff on the internet, it's here (about Singleton-Activity-Service lifecycle):

http://www.2linessoftware.com/2010/08/03/singletons-and-services-and-shutdowns-oh-my/

and good related answers here:

Singletons vs. Application Context in Android?

I've been playing around with Singleton, and find out, that the answers are not quite correct. I tried to create singleton S in an activity A, and then goto activity B (before leaving A, I called A.finish() , and call System.gc() in B.onCreate() ) - but the S.finalize() is not called !

Here are the codes:

public class FirstAct extends Activity implements OnClickListener {

    public static final String TAG = "Test_Service";
    private View btChange;

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        System.gc();
        setContentView(R.layout.first_lay);
        btChange = findViewById(R.id.btChange);
        btChange.setOnClickListener(this);
        SomeSingleton.getInstance();
    }

    @Override
    public void onClick(View v) {
        Intent i = new Intent(this,SecAct.class);
        startActivity(i);
        this.finish();
    }

    @Override
    protected void onDestroy() {
        Log.i(TAG,"First activity is destroyed !");     
        super.onDestroy();
        System.gc();
    }

}

Second activity:

public class SecAct extends Activity implements OnClickListener {

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        System.gc();
        setContentView(R.layout.first_lay);
        ((TextView) findViewById(R.id.tvLabel)).setText("Second activity");
        findViewById(R.id.btChange).setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
        Intent i = new Intent(this,FirstAct.class);
        this.startActivity(i);
        this.finish();
    }


    @Override
    protected void onDestroy() {
        Log.i(FirstAct.TAG,"Second activity is destroyed !");
        super.onDestroy();
        System.gc();
    }

}

The Singleton:

public class SomeSingleton {
    private static volatile SomeSingleton instance = null;
    private static int count = 0;
    private SomeSingleton() {
        count++;
        Log.i(FirstAct.TAG, "Created, instance: #" + count);
    }

    public static SomeSingleton getInstance() {
        if ( instance == null ) {
            instance = new SomeSingleton();
        }
        return instance;
    }

    @Override
    protected void finalize() throws Throwable {
        Log.i(FirstAct.TAG, "Finalized! ");
        super.finalize();
    }

    public void kill() {
        instance = null;
    }
}
Community
  • 1
  • 1
hungson175
  • 4,373
  • 6
  • 22
  • 21
0

This is a late answer but I'm battling a similar issue.

Have you tried initializing your MP3Singleton from inside the DummyService? According to the links you posted in your answer, if you initialize the Singleton from inside the lifecycle of the service, the singleton will remain in memory for the duration of the service.

Clocker
  • 1,316
  • 2
  • 19
  • 29