Singleton objeto está recreando
Estoy frente a un problema, que he creado un Controller
clase es singleton pero su objeto es recrear cuando accedo en diferentes actividades de la misma aplicación,
Main_Activity es mi actividad de lanzamiento
- Java Singleton + clase interna mal entendida
- Ciclo de vida de singleton basado en enum en Android
- Sincronizar el PoolingClientConnectionManager o no
- Acceso al objeto GoogleApiClient en Todas las actividades
- ¿Cuál es la diferencia entre "nuevo A ()" y "A.newInstance ()"?
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); } }
Este es mi Controller
es singleton, en él estoy fijando la alarma que es de 10sec de ahora y mi MyMainLocalReciever
recibe esa alarma y notifica usando la notificación.
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); } }
Este es mi receptor MyMainLocalReciever
notificar y estoy MyMainLocalReciever
una intención que inicia una actividad llamada 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()); } }
Hasta ahora (antes de NotificationDialog
) el código está funcionando perfecto MediaPlayer
objeto que está en la clase Controller
está funcionando bien, pero cuando accedo a mi Controller
singleton aquí en NotificationDialog
, está creando un nuevo objeto de controlador, no debe hacer eso, debe retener Controller
objeto de Controller
que es 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(); }
}
Por favor, ayúdame sobre esto, agradeceré tu ayuda. Saludos
EDIT: Aquí está mi Manifiesto
<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>
- Métodos estáticos o singleton, ¿cuál elegir?
- Singletons vs. Contexto de la aplicación en Android?
- Usando Gson para deserializar a Json en un singleton
- Android Singleton con un contexto global
- Ampliación de la clase de aplicación y buenas prácticas
- Servicio de Android Creación de una nueva instancia de clase Singleton
- Singletons vs. Contexto de la aplicación en Android?
- Fragmento no UI vs Singleton
Android procesa su proceso cuando está inactivo en segundo plano. Android destruirá su proceso si no hay componentes activos (actividades, servicios, etc.) o cuando necesita la memoria (incluso si tiene componentes activos).
Cuando el usuario utiliza su notificación, Android crea un nuevo proceso para usted. Es por eso que el Singleton se ha ido y necesita ser recreado.
EDITAR:
Después de publicar su manifiesto vi inmediatamente el problema. Eso es todo:
<receiver android:name="test.MyMainLocalReciever" android:process=":remote" />
Su proceso no se está matando. Su BroadcastReceiver se está ejecutando en otro proceso separado. En ese proceso, el singleton aún no se ha configurado.
Eliminar android:process=":remote"
de la etiqueta <receiver>
en el manifiesto.
Por favor lea sobre el idioma del titular de Inicialización a pedido . Es un artículo muy claro y sencillo sobre Singleton en el lenguaje de programación Java.
Como Singleton será un objeto estático utilizado por muchas Actividades, no tendrá que pasar el Contexto al constructor. Pasando a los métodos que lo necesitan, es una mejor opción.
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 } }
- Cómo colocar un objeto delante de la cámara siempre
- ¿Incompatibilidades de la capa de servicio MonoTouch / MonoDroid?