Adding a login refresh to APP has opened UI mechanism

Posted by staffanolin on Wed, 10 Jul 2019 01:58:51 +0200

Add a Unified Refresh Event for your APP

> Recently I saw a friend's blog and wrote an article. Tips for Controlling Page Refresh

> I think my idea is quite different from his. Write about my own control refresh event here <br/>.

First

Take my recent project as an example. We want to make a unified refresh for all the interfaces that need to refresh data after login. Otherwise, login clearly, but the interface is not refreshed, which will cause bad user experience. Then I came up with a solution: <br/>.

1. First, define an annotation for refreshing, which is used on Method method Method: OnLoginAction.java


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

/**
 * The method that needs to be invoked when logging in
 * Created by xiaolei on 2017/4/12.
 */
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface OnLoginAction
{
}

2. Define a protocol proxy for all interfaces that need to refresh data, that is, interfaces. UIDataDelegate.java


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

This interface we do not write anything, just as a simple logo, will be used later.

3. Define a broadcast for refreshing the interface

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&lt;UIDataDelegate&gt; uiDataInterface;
    public static final String ACTION = "com.tianjs.p2p.login.action";
    public LoginRecever(UIDataDelegate uiDataDelegate)
    {
        this.uiDataInterface = new SoftReference&lt;&gt;(uiDataDelegate);
    }
    @Override
    public void onReceive(Context context, Intent intent)
    {

    }
}

Here we define the constructor, and the parameter passed in is the protocol proxy defined in the second point. UIDataDelegate

4. Implement our BaseActivity to implement the protocol interface UIDataDelegate defined by implements BaseActivity.java

public abstract class BaseActivity extends Activity implements UIDataDelegate
{

}

5. On Create and on Destory of BaseActivity, respectively, initialize, register and cancel broadcasts at the time of destruction. 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();
    }
}

> Here I need to mention that I registered the broadcast using V4 package, so that this broadcast is only valid in this process <br/>. >java &gt;LocalBroadcastManager.getInstance(this).registerReceiver(recever,null); &gt;

6. Here comes the key code. We have defined a unified interface BaseActivity, a broadcasting LoginRecever for action execution, a unified interface UIDataDelegate for action interface and a self-defined annotation @OnLoginAction. > So far, we can try it out.

import android.widget.TextView;
import com.tianjs.tianjinsuop2p.R;
import com.tianjs.tianjinsuop2p.base.BaseActivity;
/**
 * Opened interface that needs to be refreshed automatically after login
 * 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","refresh data")
    }
}

After successful login, send broadcast operation:

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

> So far, we've done 50% of our work, so how do we automatically call this method annotated by @OnLoginAction after sending the broadcast?

7. Make a point. Here's the key code:

Find LoginRecever.java, which we defined above, and since it responds to broadcast operations, it must be related to this broadcast receiver. Did we just pass the UIDataDelegate interface into LoginRecever? So we can do this here:


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&lt;UIDataDelegate&gt; uiDataInterface;
    public static final String ACTION = "com.tianjs.p2p.login.action";

    public LoginRecever(UIDataDelegate uiDataDelegate)
    {
        this.uiDataInterface = new SoftReference&lt;&gt;(uiDataDelegate);
    }

    @Override
    public void onReceive(Context context, Intent intent)
    {
        if (intent != null &amp;&amp; intent.getAction() != null &amp;&amp; intent.getAction().equals(ACTION) &amp;&amp; uiDataInterface != null &amp;&amp; uiDataInterface.get() != null)
        {
            UIDataDelegate delegate = uiDataInterface.get();
            Class&lt;?&gt; 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) &amp;&amp; method.getParameterTypes().length == 0)
                    {
                        try
                        {
                            method.invoke(delegate,new Object[]{});
                        }catch (Exception e)
                        {
                            e.printStackTrace();
                        }
                    }
                }
            }
        }
    }
}

> This will automatically find the current class, all the methods in it, and filter out the methods annotated by @OnLoginAction, which must also be parameterized. > Soft references are used here to avoid situations where your activity cannot be recycled

> Great success!

No picture, I say J8??

Topics: Java Android