全手机弹出的dialog和观察者设计模式

转载请注明出处:
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

有需要的可以联系

发布了71 篇原创文章 · 获赞 15 · 访问量 10万+

猜你喜欢

转载自blog.csdn.net/pangzaifei/article/details/43155997
今日推荐