Singleton object recreates

I ran into the problem that I created the Controller class, it is singleton, but its object is recreated when I access different actions of the same application,

Main_Activity - my starting activity

 public class Main_Activity extends Activity{ private Controller simpleController; protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); simpleController = Controller.getInstance(this); } } 

This is my Controller it is singleton, in it I set the alarm, which is 10 seconds, and my MyMainLocalReciever receives this signal and notifies it with a notification.

 public class Controller { private MediaPlayer mp; public Context context; private static Controller instance; public static Controller getInstance(Context context) { if (instance == null) { instance = new Controller(context); } return instance; } private Controller(Context context) { Log.d("TAG", "Creating Controller object"); mp = null; this.context = context; setAlarm(10); } public void setAlarm(int position) { Intent intent = new Intent(context, MyMainLocalReciever.class); intent.putExtra("alarm_id", "" + position); PendingIntent sender = PendingIntent.getBroadcast(context, position, intent, PendingIntent.FLAG_UPDATE_CURRENT); // Get the AlarmManager service AlarmManager am = (AlarmManager) context .getSystemService(Activity.ALARM_SERVICE); am.cancel(sender); am.set(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + (position*1000), sender); } } 

This is my MyMainLocalReciever receiver MyMainLocalReciever it notifies, and I bind an intent that triggers an action called NotificationDialog

 public class MyMainLocalReciever extends BroadcastReceiver { private NotificationManager notificationManager; private int alarmId = 0; @Override public void onReceive(Context context, Intent intent) { if (notificationManager == null) { notificationManager = (NotificationManager) context .getSystemService(Context.NOTIFICATION_SERVICE); } Bundle bundle = intent.getExtras(); String alarm_Id = bundle.getString("alarm_id"); try { alarmId = Integer.parseInt(alarm_Id); } catch (Exception e) { Log.d("Exception", "exception in converting"); } Controller myC = Controller.getInstance(context); if ((myC.getMp() != null)) { myC.getMp().stop(); myC.setMp(null); } if (myC.getMp() == null) { myC.setMp(MediaPlayer.create(context , R.id.mpFile)); myC.getMp().start(); } NotificationCompat.Builder builder = new NotificationCompat.Builder(context) .setTicker("Its Ticker") .setSmallIcon(R.drawable.ic_launcher) .setContentTitle("Its Title") .setContentText("Its Context") .setAutoCancel(true) .setContentIntent( PendingIntent.getActivity(context, 0, new Intent(context, NotificationDialog.class) .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK), 0)); notificationManager.notify("interstitial_tag", alarmId, builder.getNotification()); } } 

So far (before NotificationDialog ) the code works fine. The MediaPlayer object, which is in the Controller class, works fine too, but when I access my singleton Controller here, in NotificationDialog , it creates a new Controller object, it should not do this, it should save the Controller object, which is singleton.

 public class NotificationDialog extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.notification_dialog); } public void onViewContent(View v) { //this method is invoked when I click on a button binded in xml file Controller myC = Controller.getInstance(getApplicationContext()); if (myC.getMp() != null) { myC.getMp().stop(); myC.setMp(null); } finish(); } 

}

Please help me with this, I will be grateful for your help. Relations

EDIT: Here is my manifest

 <application android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" > <activity android:name=".Main_Activity" android:label="@string/app_name" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <activity android:name="test.SettingsActivity" android:label="@string/app_name" /> <activity android:name="test.NotificationDialog" android:label="@string/app_name" /> <service android:name="test.MyService" > </service> <receiver android:name="test.MyMainLocalReciever" android:process=":remote" /> </application> 
+4
source share
3 answers

Your process kills Android when it is inactive in the background. Android will kill your process if there are no active components (Activities, Services, etc.) or when it needs memory (even if you have active components).

When a user uses your notification, Android creates a new process for you. That's why Singleton is gone and needs to be recreated.

EDIT:

After you published your manifest, I immediately saw the problem. It is he:

 <receiver android:name="test.MyMainLocalReciever" android:process=":remote" /> 

Your process is not killed. Your BroadcastReceiver is running in another separate process. In this process, singleton is not configured yet.

Remove android:process=":remote" from the <receiver> in the manifest.

+6
source

Please read Initialization as requested by the owner of the idiom . This is a very understandable and simple article about the correct singleton in the Java programming language.

+1
source

Since Singleton will be a static object used by many actions, you do not need to pass Context to the constructor. Passing it on to the methods he needs will be the best option.

 public class Controller { private static volatile Controller instance = null; private Controller () { } public static Controller getInstance() { if (instance == null) { synchronized (Controller .class) if (instance == null) { instance = new Controller(); } } return instance; } public void setAlarm(Context context, int position) { // do stuff } } 
0
source

All Articles