美文网首页Android开发经验谈Android开发Android知识
为APP添加一个登录刷新已打开UI机制

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

作者: xiaolei123 | 来源:发表于2017-11-17 15:44 被阅读83次

    为你的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??

    输入图片说明

    相关文章

      网友评论

        本文标题:为APP添加一个登录刷新已打开UI机制

        本文链接:https://www.haomeiwen.com/subject/dwyjvxtx.html