1.项目中的需求是:一个活动结束,服务器通知用户,需要弹出一个提示框问用户,是否要将活动延迟30分钟,图片例如:
这个需求是用户不管在那个app只要手机主界面就需要提示。所以我想到了,用service中来弹出dialog。但是用new Dialog show()的话,会抛异常。然后通过看源码。发现,dialog可以是可是设置成系统的alert的。
关键代码:
mDialog.getWindow().setType( (WindowManager.LayoutParams.TYPE_SYSTEM_ALERT));然后我们需要添加权限
<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); } }
/** * @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