我遇到了一个问题,我创建了一个类Controller
它是单例,但当我访问同一个应用程序的不同活动时,它的对象正在重新创建,
Main_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);
}
}
这是我的Controller
它是单身,在其中我设置了从现在开始10秒的警报,我的MyMainLocalReciever
收到该警报并通知使用通知。
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);
}
}
这是我的接收者MyMainLocalReciever
它通知我绑定了一个意图,它启动了一个名为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());
}
}
直到现在(在NotificationDialog
之前)代码正在运行MediaPlayer
类中的完美Controller
对象也正常工作,但是当我在这里访问我的单身Controller
时NotificationDialog
,它正在创建Controller的新对象,它不应该这样做,它应该保留Controller
单例对象。
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();
}
}
请帮助我,我将非常感谢你的帮助。 此致
修改 这是我的清单
<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>
答案 0 :(得分:6)
在后台处于空闲状态时,您的进程会被Android杀死。如果没有活动组件(活动,服务等)或需要内存(即使您有活动组件),Android将终止您的进程。
当用户使用您的通知时,Android会为您创建一个新流程。这就是为什么Singleton不见了,需要重新创建。
修改强>
发布清单后,我立即看到了问题。就是这样:
<receiver
android:name="test.MyMainLocalReciever"
android:process=":remote" />
你的过程没有被杀死。您的BroadcastReceiver正在另一个单独的进程中运行。在这个过程中,尚未建立单身人士。
从清单中的android:process=":remote"
标记中删除<receiver>
。
答案 1 :(得分:1)
请阅读Initialization-on-demand holder idiom。这是关于Java编程语言中正确的Singleton的非常简单明了的文章。
答案 2 :(得分:0)
由于Singleton将是许多活动使用的静态对象,因此您不必将Context传递给构造函数。将它传递给需要它的方法是一个更好的选择。
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
}
}