定时获取来自服务器的消息

定时获取来自服务器的消息

功能描述:

  界面中有一个消息功能,点击消息可以查看消息列表。
定时向服务器发送请求接口获取最新消息,并将消息数量以角标得形式显示到消息功能上,
从而用户可以直观得了解到接收了几条消息。

思路

step 1:开一个服务,定时发送请求到服务器,获取消息
    知识点:定时发送:observable.interval();
            网络请求:okhttp;
            后台运行:service;

step 2:得到消息实体后,通知界面更新(activity或者fragment)

    
step 3:显示消息数量的角标到对应控件
    知识点:badgeview;

实现

1,在后台不停跑的service-MonitorService

public class MonitorService extends Service {
    public MonitorService() {
    }

    @Override
    public IBinder onBind(Intent intent) {
        // TODO: Return the communication channel to the service.
        return binder;
    }

    @Override
    public void onCreate() {
        LogUtil.d("onCreate");
        super.onCreate();
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        LogUtil.d("onStartCommand");
        return super.onStartCommand(intent, flags, startId);
    }

    @Override
    public void onDestroy() {
        LogUtil.d("onDestroy");
        super.onDestroy();
    }

    private MonitorBinder binder = new MonitorBinder();
    public class MonitorBinder extends Binder{

        /**
         * 每隔几秒向服务器发送请求,获取最新消息数量
         * @param  intervalSecond 时间间隔,单位秒
         */
        public Observable<String> getNewMessage(int intervalSecond){
            // 默认5秒
            if (intervalSecond<1) intervalSecond = 5;
            return io.reactivex.Observable
                    .interval(intervalSecond, TimeUnit.SECONDS)
                    .flatMap(new Function<Long, ObservableSource<String>>() {
                        @Override
                        public ObservableSource<String> apply(Long aLong) throws Exception {
                            return io.reactivex.Observable                    .create(new ObservableOnSubscribe<String>() {
                                @Override
                                public void subscribe(final ObservableEmitter<String> emitter) throws Exception {
                                    LogUtil.e("------subscribe-------");
                                    MessageModel model = new MessageModel();
                                    model.loadData(  "", new MessageModel.OnMessageRequestListener() {
                                        @Override
                                        public void onFailed(IOException e) {
                                            emitter.onNext("");
                                        }

                                        @Override
                                        public void onSuccess(String json) {
                                            emitter.onNext(json);
                                        }
                                    });
                                }
                            });
                        }
                    });
        }

    }
}

2,网络请求需要的Module

public class MessageModel {

    private static final OkHttpClient OK_HTTP_CLIENT = new OkHttpClient();

    public void loadData(String url, final OnMessageRequestListener listener){
        LogUtil.e(url);
        Request request = new Request.Builder()
                .url(url)
                .build();
        Call call = OK_HTTP_CLIENT.newCall(request);
        call.enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                listener.onFailed(e);
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                listener.onSuccess(response.body().string());
            }
        });

    }

    public interface OnMessageRequestListener{
        void onFailed(IOException e);
        void onSuccess(String json);
    }
}

3,设置角标的view

public class BadgeView extends TextView {
    private boolean mHideOnNull;

    public BadgeView(Context context) {
        this(context, (AttributeSet)null);
    }

    public BadgeView(Context context, AttributeSet attrs) {
        this(context, attrs, 16842884);
    }

    public BadgeView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        this.mHideOnNull = true;
        this.init();
    }

    private void init() {
        if (!(this.getLayoutParams() instanceof LayoutParams)) {
            LayoutParams layoutParams = new LayoutParams(-2, -2, 53);
            this.setLayoutParams(layoutParams);
        }

        this.setTextColor(-1);
        this.setTypeface(Typeface.DEFAULT_BOLD);
        this.setTextSize(2, 11.0F);
        this.setPadding(this.dip2Px(5.0F), this.dip2Px(1.0F), this.dip2Px(5.0F), this.dip2Px(1.0F));
        this.setBackground(9, Color.parseColor("#d3321b"));
        this.setGravity(17);
        this.setHideOnNull(true);
        this.setBadgeCount(0);
    }

    public void setBackground(int dipRadius, int badgeColor) {
        int radius = this.dip2Px((float)dipRadius);
        float[] radiusArray = new float[]{(float)radius, (float)radius, (float)radius, (float)radius, (float)radius, (float)radius, (float)radius, (float)radius};
        RoundRectShape roundRect = new RoundRectShape(radiusArray, (RectF)null, (float[])null);
        ShapeDrawable bgDrawable = new ShapeDrawable(roundRect);
        bgDrawable.getPaint().setColor(badgeColor);
        this.setBackgroundDrawable(bgDrawable);
    }

    public boolean isHideOnNull() {
        return this.mHideOnNull;
    }

    public void setHideOnNull(boolean hideOnNull) {
        this.mHideOnNull = hideOnNull;
        this.setText(this.getText());
    }

    public void setText(CharSequence text, BufferType type) {
        if (!this.isHideOnNull() || text != null && !text.toString().equalsIgnoreCase("0")) {
            this.setVisibility(0);
        } else {
            this.setVisibility(8);
        }

        super.setText(text, type);
    }

    public void setBadgeCount(int count) {
        this.setText(String.valueOf(count));
    }

    public Integer getBadgeCount() {
        if (this.getText() == null) {
            return null;
        } else {
            String text = this.getText().toString();

            try {
                return Integer.parseInt(text);
            } catch (NumberFormatException var3) {
                return null;
            }
        }
    }

    public void setBadgeGravity(int gravity) {
        LayoutParams params = (LayoutParams)this.getLayoutParams();
        params.gravity = gravity;
        this.setLayoutParams(params);
    }

    public int getBadgeGravity() {
        LayoutParams params = (LayoutParams)this.getLayoutParams();
        return params.gravity;
    }

    public void setBadgeMargin(int dipMargin) {
        this.setBadgeMargin(dipMargin, dipMargin, dipMargin, dipMargin);
    }

    public void setBadgeMargin(int leftDipMargin, int topDipMargin, int rightDipMargin, int bottomDipMargin) {
        LayoutParams params = (LayoutParams)this.getLayoutParams();
        params.leftMargin = this.dip2Px((float)leftDipMargin);
        params.topMargin = this.dip2Px((float)topDipMargin);
        params.rightMargin = this.dip2Px((float)rightDipMargin);
        params.bottomMargin = this.dip2Px((float)bottomDipMargin);
        this.setLayoutParams(params);
    }

    public int[] getBadgeMargin() {
        LayoutParams params = (LayoutParams)this.getLayoutParams();
        return new int[]{params.leftMargin, params.topMargin, params.rightMargin, params.bottomMargin};
    }

    public void incrementBadgeCount(int increment) {
        Integer count = this.getBadgeCount();
        if (count == null) {
            this.setBadgeCount(increment);
        } else {
            this.setBadgeCount(increment + count);
        }

    }

    public void decrementBadgeCount(int decrement) {
        this.incrementBadgeCount(-decrement);
    }

    public void setTargetView(TabWidget target, int tabIndex) {
        View tabView = target.getChildTabViewAt(tabIndex);
        this.setTargetView(tabView);
    }

    public void setTargetView(View target) {
        if (this.getParent() != null) {
            ((ViewGroup)this.getParent()).removeView(this);
        }

        if (target != null) {
            if (target.getParent() instanceof FrameLayout) {
                ((FrameLayout)target.getParent()).addView(this);
            } else if (target.getParent() instanceof ViewGroup) {
                ViewGroup parentContainer = (ViewGroup)target.getParent();
                int groupIndex = parentContainer.indexOfChild(target);
                parentContainer.removeView(target);
                FrameLayout badgeContainer = new FrameLayout(this.getContext());
                android.view.ViewGroup.LayoutParams parentlayoutParams = target.getLayoutParams();
                badgeContainer.setLayoutParams(parentlayoutParams);
                target.setLayoutParams(new android.view.ViewGroup.LayoutParams(-1, -1));
                parentContainer.addView(badgeContainer, groupIndex, parentlayoutParams);
                badgeContainer.addView(target);
                badgeContainer.addView(this);
            } else if (target.getParent() == null) {
                Log.e(this.getClass().getSimpleName(), "ParentView is needed");
            }

        }
    }

    private int dip2Px(float dip) {
        return (int)(dip * this.getContext().getResources().getDisplayMetrics().density + 0.5F);
    }
}

4,activity中实现

public class MainActivity extends AppCompatActivity {

   
    private MonitorService.MonitorBinder binder;
    private ServiceConnection serviceConnection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            Log.e("test","------onServiceConnected-------");
            binder = (MonitorService.MonitorBinder) service;
            // 假设json 不为空。为:有消息。
            disposable = binder.getNewMessage(6)
                    .subscribeOn(Schedulers.io())
                    .observeOn(AndroidSchedulers.mainThread())
                    .subscribe(json -> {
                        if (!TextUtils.isEmpty(json)) {
                            Log.e("test","------subscribe  success-------");
                            // 假设json 不为空。为:有消息。
                            View view = findViewById(R.id.tv_menu);
                            BadgeView badgeView = new BadgeView(MainActivity.this);
                            badgeView.setTargetView(view);
                            badgeView.setBadgeCount(1);
                        }
                    });
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {

        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initToolbar();
        bindService(new Intent(this,MonitorService.class),serviceConnection,BIND_AUTO_CREATE);
 

    }


    @Override
    protected void onDestroy() {
        super.onDestroy();
        if(disposable!=null&&!disposable.isDisposed()){
            disposable.dispose();
        }
        unbindService(serviceConnection);
    }

注意:

1,记得在androidManifest.xml中配置MonitorService服务
2,如果需要设置的目标view是button的话可能会不显示,代码中的tv_menu 是textview。

猜你喜欢

转载自blog.csdn.net/qwe1314225/article/details/83543314