转载请注明出处:
http://blog.csdn.net/pangzaifei/article/details/43155997
1.项目中的需求是:一个活动结束,服务器通知用户,需要弹出一个提示框问用户,是否要将活动延迟30分钟,图片例如:
这个需求是用户不管在那个app只要手机主界面就需要提示。所以我想到了,用service中来弹出dialog。但是用new Dialog show()的话,会抛异常。然后通过看源码。发现,dialog可以是可是设置成系统的alert的。
关键代码:
mDialog.getWindow().setType(
(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT));
然后我们需要添加权限
文章出处:https://blog.csdn.net/pangzaifei/article/details/70213731
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
这两步完成,我们就可以在service里面弹dialog了。
2.下面就说一下观察者模式。需求是如果活动结束了就需要弹出对话框让用户来点,那么通知系统让它弹出对话框呢,这个时候就需要观察者了。
解释下什么是观察者和被观察者。观察者是observable被观察者是observer。这俩怎么区别呢。
当某一个我们需要被观察的对象继承自Observable类时,就表示该类可以被很多观察者(实现了Observer)观察,其实意思就是说这个对象也就是被观察者“上电视了”,电视前的你也就是观察者可以看,(对象发生变化)电视里被观察者做了别的动作,那么电视前的所有人看到的也就变了,在同一时间改变所有观众看到的画面。
举个栗子:
ChinaJoy有很多漂亮妹子,那我们去看凤姐吧,既然我们要看凤姐。那么她就是被观察者了,就是上面说的observable.,我们看的这些人就是观察着,observer了
凤姐有个规矩你必须留下你的qq才能看她,(因为她给各位observer发福利,往下看),你就addObserver()将自己的信息给凤姐。
展会结束了,凤姐想赚点外快,因为你之前addObserver()了,所以你的qq他就有了。。他就给你发送福利照片。调用setChanged()和notifyObservers()来通知你。当被观察者调用了这两个方法。那么观察者们就可以看到羞羞的福利了。你只需要implements Observer,然后重载 update(Observable observable, Object data)方法,其中data就是凤姐传达给你的信息。
那么代码怎么实现呢:
1.先要有个被观察者(凤姐)。只需要继承Observable即可
/**
* @desc:被观察者
* @author: pangzf
* @date: 2015年1月26日 下午5:54:06
*/
public class MyObservable extends Observable{
public void showDialog(Context context){
//改变数据
setChanged();
//通知
notifyObservers(context);
}
}
2.创建观察者(观众)。只需要实现Observer然后重载update就行
/**
* @desc:观察者
* @author: pangzf
* @date: 2015年1月26日 下午5:54:18
*/
public class MyService extends Service implements Observer {
private Dialog mDialog;
private ScheduledExecutorService mScheduledExecutorService;
private Handler mHandler = new Handler() {
public void dispatchMessage(android.os.Message msg) {
if (mDialog != null && !mDialog.isShowing()) {
mDialog.show();
}
};
};
@Override
public IBinder onBind(Intent arg0) {
return null;
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
//下面的代码如果开放,就可以测试全局弹dialog功能。是每5秒弹一次。
/* if (mDialog == null) {
mDialog = new Dialog(getApplicationContext());
mDialog.setContentView(R.layout.show_dialog);
// 加入系统服务
mDialog.getWindow().setType(
(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT));
mScheduledExecutorService = Executors
.newSingleThreadScheduledExecutor();
mScheduledExecutorService.scheduleAtFixedRate(new Runnable() {
@Override
public void run() {
// 5秒显示一次对话框
mHandler.sendEmptyMessage(0);
}
}, 5, 5, TimeUnit.SECONDS);
}*/
return super.onStartCommand(intent, flags, startId);
}
@Override
public void update(Observable observable, Object data) {
Log.e("fff", "接收到数据");
if (mDialog == null) {
mDialog = new Dialog((Context) data);
mDialog.setContentView(R.layout.show_dialog);
// 加入系统服务
mDialog.getWindow().setType(
(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT));
}
if (mDialog != null && !mDialog.isShowing()) {
mDialog.show();
}
}
}
3.给被观察这添加观察者。(观众给凤姐留qq号)
mObservable = new MyObservable();
mObservable.addObserver(new MyService());
4.被观察者数据更新了,通知广大观察者。(凤姐给观众发福利)
//showDialog()是自己写的方法,里面调用了被观察者的 setChanged() 改变数据的方法;和notifyObservers(context) 通知的方法;这两个方法调用后,观察者就可以收到信息了
mObservable.showDialog(getApplicationContext());
5.在update中拿到数据.(观众收到福利)
@Override
public void update(Observable observable, Object data) {
Log.e("fff", "接收到数据");
if (mDialog == null) {
mDialog = new Dialog((Context) data);
mDialog.setContentView(R.layout.show_dialog);
// 加入系统服务
mDialog.getWindow().setType(
(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT));
}
if (mDialog != null && !mDialog.isShowing()) {
mDialog.show();
}
}
效果图:
源码地址:
http://download.csdn.net/detail/pangzaifei/8398619
个人项目txtreader:已经发布google play,http://blog.csdn.net/pangzaifei/article/details/52756777
有需要的可以联系