为APP添加一个登录刷新已打开UI机制

为你的APP添加一个统一刷新事件

最近看到一个朋友的博客,写了一篇文章 控制页面刷新小技巧


我觉得我的想法与他的有很大的出入,这里写写我自己的控制刷新事件吧

首先

拿我最近的项目做做例子吧,我们想在登录之后,对所有需要刷新数据的界面做一个统一的刷新,否则明明登录了,但是界面未刷新,会造成用户体验好差。然后我就想出了这么个法子:


1.首先定义一个用于刷新的注解,使用于方法Method上: OnLoginAction.java

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * 当登录的时候,需要调用的方法
 * Created by xiaolei on 2017/4/12.
 */
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface OnLoginAction
{
}

2.为所有需要刷新数据的界面,定义一个协议代理,就是接口。 UIDataDelegate.java

/**
 * Created by xiaolei on 2017/4/12.
 */
public interface UIDataDelegate
{
}

这个接口我们啥方法都不写,只是作为一个单纯的标识而已,后面会用到。


3.定义一个用于刷新界面的广播

LoginRecever.java

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import com.tianjs.tianjinsuop2p.base.UIDataDelegate;
import java.lang.ref.SoftReference; 
import java.lang.reflect.Method;
/**
 * Created by xiaolei on 2017/4/12.
 */
public class LoginRecever extends BroadcastReceiver
{
    private static final String TAG = "LoginRecever";
    private SoftReference<UIDataDelegate> uiDataInterface;
    public static final String ACTION = "com.tianjs.p2p.login.action";
    public LoginRecever(UIDataDelegate uiDataDelegate)
    {
        this.uiDataInterface = new SoftReference<>(uiDataDelegate);
    }
    @Override
    public void onReceive(Context context, Intent intent)
    {
        
    }
}

这里我们定义构造函数,传入的参数,就是第二点定义的那个协议代理。UIDataDelegate


4.把我们的BaseActivity实现 implements 我们定义的协议接口 UIDataDelegate BaseActivity.java

public abstract class BaseActivity extends Activity implements UIDataDelegate
{
    
}

5.在BaseActivity的onCreate和onDestory分别对广播的初始化,注册,以及 销毁时的注销 BaseActivity.java

import android.app.Activity;
import com.tianjs.tianjinsuop2p.Receivers.LoginRecever;

public abstract class BaseActivity extends Activity implements UIDataDelegate
{
    private LoginRecever recever;
    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        recever = new LoginRecever(this);
        LocalBroadcastManager.getInstance(this).registerReceiver(recever,new IntentFilter(LoginRecever.ACTION));
    }
    
    @Override
    protected void onDestroy()
    {
        LocalBroadcastManager.getInstance(this).unregisterReceiver(recever);
        super.onDestroy();
    }
}

这里我需要提一下,我注册广播使用的是 V4包的,这样的话,这个广播,只在本进程内有效 LocalBroadcastManager.getInstance(this).registerReceiver(recever,null);


6.关键代码来了,以上我们定义了一个统一的界面BaseActivity 一个用于执行动作的广播 LoginRecever 一个统一需要操作界面的接口 UIDataDelegate 和一个 自己定义的注解 @OnLoginAction

到此为止,我们可以试用一下

import android.widget.TextView;
import com.tianjs.tianjinsuop2p.R;
import com.tianjs.tianjinsuop2p.base.BaseActivity;
/**
 * 需要在登录之后自动刷新的,已打开的界面
 * Created by xiaolei on 2017/3/20.
 */
public class DataActivity extends BaseActivity
{
    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_alert);
    }
    
    @OnLoginAction
    public void loadData()
    {
        Log.e("DataActivity","刷新数据")
    }
}

登录成功之后,发送广播操作:

Intent intent = new Intent();
intent.setAction(LoginRecever.ACTION);
LocalBroadcastManager.getInstance(LoginActicity.this).sendBroadcast(intent);

到此为止,我们算是已经完成了 50%的工作量了,那么,如何在发送广播之后,自动调用这个被@OnLoginAction注解的方法呢?

7.划重点啊,这里是关键的代码:

找到我们上面定义的 LoginRecever.java,既然是响应广播操作嘛,肯定跟这个广播接收器有关。 我们刚才是不是把已经实现UIDataDelegate接口传进LoginRecever里面来了吗?那么,我们这里可以这么做:

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;

import com.tianjs.tianjinsuop2p.annotations.OnLoginAction;
import com.tianjs.tianjinsuop2p.base.UIDataDelegate;
import com.tianjs.tianjinsuop2p.config.Globals;
import com.tianjs.tianjinsuop2p.utils.Log;

import java.lang.ref.SoftReference; 
import java.lang.reflect.Method;

/**
 * Created by xiaolei on 2017/4/12.
 */

public class LoginRecever extends BroadcastReceiver
{
    private static final String TAG = "LoginRecever";
    private SoftReference<UIDataDelegate> uiDataInterface;
    public static final String ACTION = "com.tianjs.p2p.login.action";

    public LoginRecever(UIDataDelegate uiDataDelegate)
    {
        this.uiDataInterface = new SoftReference<>(uiDataDelegate);
    }

    @Override
    public void onReceive(Context context, Intent intent)
    {
        if (intent != null && intent.getAction() != null && intent.getAction().equals(ACTION) && uiDataInterface != null && uiDataInterface.get() != null)
        {
            UIDataDelegate delegate = uiDataInterface.get();
            Class<?> klass = delegate.getClass();
            Log.e(TAG, "LoginRecever:" + klass.getSimpleName());
            Method methods[] = klass.getDeclaredMethods();
            if (methods != null)
            {
                for (Method method : methods)
                {
                    if(method.isAnnotationPresent(OnLoginAction.class) && method.getParameterTypes().length == 0)
                    {
                        try
                        {
                            method.invoke(delegate,new Object[]{});
                        }catch (Exception e)
                        {
                            e.printStackTrace();
                        }
                    }
                }
            }
        }
    }
}

这里会自动寻找当前类,里面所有的方法,并且过滤筛选出被 @OnLoginAction注解的方法,还必须是无参数的。 这里使用了软引用,可以避免你的activity回收不了的情况


大功告成 !


没图我说个J8??

输入图片说明

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏后端之路

junit测试之第三方组件mock

今天某个一直稳定运行的测试挂了,没有开发同学出来认领。 ? 对应模块的小伙伴询问此处依赖的环境是哪个,可以去调查失败的原因。 好吧,回顾一下关于第三方组件mo...

2095
来自专栏Hellovass 的博客

动态生成分享图片

本文描述了如何实现该需求的思路,代码可能不通用,但是该思路应该可以解决很多类似的需求…

1983
来自专栏向治洪

android断点下载

断点下载往往用在大文件的下载过程中,如传统的迅雷下载用的就是断点下载技术,说起来原理比较简单:对文件进行分片,并对分片的文件进行标记,然后分片下载,下载完成后对...

22010
来自专栏软件开发 -- 分享 互助 成长

WIFI环境下Android手机和电脑通信

前面已经写过一篇java实现最基础的socket网络通信,这篇和之前那篇大同小异,只是将客户端代码移植到手机中,然后获取本机IP的方法略有不同。 先讲一下本篇中...

3435
来自专栏向治洪

android orm持久层框架

android数据库开发   Android中内置了sqlite,但是常用的开发语言java是面向对象的,而数据库是关系型的,二者之间的转化每次都很麻烦(主...

1695
来自专栏Android-薛之涛

Android-Fragment

我们在创建Fragment的管理器的时候,会选择导入那个包下的FragmentManager.有app包下和v4包下的,这里我推荐用v4包的FragmentMa...

1223
来自专栏三流程序员的挣扎

Navigation 详解一

Navigation 是 JetPack 中的一个组件,用于方便的实现页面的导航,所以抽象出了一个 destination 的概念,大部分情况一个 destin...

1311
来自专栏分享达人秀

ViewPager快速实现引导页

在很多APP第一次启动时都会出现引导页,在一些APP里面还会包括一些左右滑动翻页和页面轮播切换的情况。在之前也已经学习了AdapterViewFlipp...

1747
来自专栏指尖下的Android

菜鸡的MVP架构漫谈

相信大家在网上看过关于MVP架构的博客数不胜数,至于MVP到底是什么,也不需要我再从百度百科复制一遍了,通俗的说MVP就是解决Model和View的耦合,没有使...

492
来自专栏非著名程序员

Retrofit初探和简单使用

? Retrofit简单介绍 Retrofit是Square提供的开源产品,为Android平台的应用提供一个类型安全的REST客户端。它是基于注解,提供 J...

1949

扫码关注云+社区