app/src/main/java/com/huawei/android/hms/agent/push/QueryAgreementApi.java
public class QueryAgreementApi extends BaseApiAgent {

    /**
     * HuaweiApiClient 连接结果回调
     *
     * @param rst    结果码
     * @param client HuaweiApiClient 实例
     */
    @Override
    public void onConnect(int rst, final HuaweiApiClient client) {
        //需要在子线程中执行获取push协议展示的操作
        new Thread() {
            public void run() {
                if (client == null || !ApiClientMgr.INST.isConnect(client)) {
                    HMSAgentLog.e("client not connted");
                    return;
                }

                HuaweiPush.HuaweiPushApi.queryAgreement(client);
            }
        }.start();
    }

    /**
     * 请求push协议展示
     */
    public void queryAgreement() {
        connect();
    }
}
app/src/main/java/com/huawei/android/hms/agent/push/DeleteTokenApi.java
public class DeleteTokenApi extends BaseApiAgent {

    /**
     * 待删除的push token
     */
    private String token;

    /**
     * HuaweiApiClient 连接结果回调
     *
     * @param rst    结果码
     * @param client HuaweiApiClient 实例
     */
    @Override
    public void onConnect(int rst, final HuaweiApiClient client) {
        //需要在子线程中执行删除TOKEN操作
        new Thread() {
            public void run() {
                //调用删除TOKEN需要传入通过getToken接口获取到TOKEN，并且需要对TOKEN进行非空判断
                if (!TextUtils.isEmpty(token)){
                    try {
                        if (client == null || !ApiClientMgr.INST.isConnect(client)) {
                            HMSAgentLog.e("client not connted");
                            return;
                        }

                        HuaweiPush.HuaweiPushApi.deleteToken(client, token);
                    } catch (PushException e) {
                        HMSAgentLog.e("删除TOKEN失败:" + e.getMessage());
                    }
                }
            }
        }.start();
    }

    /**
     * 删除指定的pushtoken
     * 该接口只在EMUI5.1以及更高版本的华为手机上调用该接口后才不会收到PUSH消息。
     * @param token 要删除的token
     */
    public void deleteToken(String token) {
        this.token = token;
        connect();
    }
}
app/src/main/java/com/huawei/android/hms/agent/push/GetPushStateApi.java
public class GetPushStateApi extends BaseApiAgent {

    /**
     * HuaweiApiClient 连接结果回调
     *
     * @param rst    结果码
     * @param client HuaweiApiClient 实例
     */
    @Override
    public void onConnect(int rst, final HuaweiApiClient client) {
        //需要在子线程中执行获取push状态的操作
        new Thread() {
            public void run() {
                if (client == null || !ApiClientMgr.INST.isConnect(client)) {
                    HMSAgentLog.e("client not connted");
                    return;
                }

                HuaweiPush.HuaweiPushApi.getPushState(client);
            }
        }.start();
    }

    /**
     * 获取push状态，push状态的回调通过广播发送。
     * 要监听的广播，请参见HMS-SDK开发准备中PushReceiver的注册
     */
    public void getPushState() {
        connect();
    }
}
app/src/main/java/com/huawei/android/hms/agent/common/handler/ConnectHandler.java
public interface ConnectHandler {
    /**
     * HuaweiApiClient 连接结果回调
     * @param rst 结果码
     */
    void onConnect(int rst);
}
app/src/main/java/com/huawei/android/hms/agent/common/IClientConnectCallback.java
public interface IClientConnectCallback {
    /**
     * HuaweiApiClient 连接结果回调
     * @param rst 结果码
     * @param client HuaweiApiClient 实例
     */
    void onConnect(int rst, HuaweiApiClient client);
}
app/src/main/java/com/huawei/android/hms/agent/common/HMSAgentLog.java
public final class HMSAgentLog {

    /**
     * 日志回调，将要打印的日志回调给开发者，由开发者将日志输出
     */
    public interface IHMSAgentLogCallback {
        void logD(String tag, String log);
        void logV(String tag, String log);
        void logI(String tag, String log);
        void logW(String tag, String log);
        void logE(String tag, String log);
    }

    private static final int START_STACK_INDEX = 4;
    private static final int PRINT_STACK_COUTN = 2;

    private static IHMSAgentLogCallback logCallback = null;

    public static void setHMSAgentLogCallback(IHMSAgentLogCallback callback){
        logCallback = callback;
    }

    public static void d(String log) {
        StringBuilder sb = new StringBuilder();
        appendStack(sb);
        sb.append(log);

        if (logCallback != null) {
            logCallback.logD("HMSAgent", sb.toString());
        } else {
            Log.d("HMSAgent", sb.toString());
        }
    }

    public static void v(String log) {
        StringBuilder sb = new StringBuilder();
        appendStack(sb);
        sb.append(log);
        if (logCallback != null) {
            logCallback.logV("HMSAgent", sb.toString());
        } else {
            Log.v("HMSAgent", sb.toString());
        }
    }

    public static void i(String log) {
        StringBuilder sb = new StringBuilder();
        appendStack(sb);
        sb.append(log);
        if (logCallback != null) {
            logCallback.logI("HMSAgent", sb.toString());
        } else {
            Log.i("HMSAgent", sb.toString());
        }
    }

    public static void w(String log) {
        StringBuilder sb = new StringBuilder();
        appendStack(sb);
        sb.append(log);
        if (logCallback != null) {
            logCallback.logW("HMSAgent", sb.toString());
        } else {
            Log.w("HMSAgent", sb.toString());
        }
    }

    public static void e(String log) {
        StringBuilder sb = new StringBuilder();
        appendStack(sb);
        sb.append(log);

        if (logCallback != null) {
            logCallback.logE("HMSAgent", sb.toString());
        } else {
            Log.e("HMSAgent", sb.toString());
        }
    }

    private static void appendStack(StringBuilder sb) {
        StackTraceElement[] stacks = Thread.currentThread().getStackTrace();
        if (stacks != null && stacks.length > START_STACK_INDEX) {
            int lastIndex = Math.min(stacks.length-1,START_STACK_INDEX+PRINT_STACK_COUTN);
            for (int i=lastIndex; i >= START_STACK_INDEX; i--) {
                if (stacks[i] == null) {
                    continue;
                }

                String fileName = stacks[i].getFileName();
                if (fileName != null) {
                    int dotIndx = fileName.indexOf('.');
                    if (dotIndx > 0) {
                        fileName = fileName.substring(0, dotIndx);
                    }
                }

                sb.append(fileName);
                sb.append('(');
                sb.append(stacks[i].getLineNumber());
                sb.append(")");
                sb.append("->");
            }
            sb.append(stacks[START_STACK_INDEX].getMethodName());
        }
        sb.append('\n');
    }
}
app/src/main/java/com/huawei/android/hms/agent/push/GetTokenApi.java
public class GetTokenApi extends BaseApiAgent {

    /**
     * client 无效最大尝试次数
     */
    private static final int MAX_RETRY_TIMES = 1;

    /**
     * 结果回调
     */
    private GetTokenHandler handler;

    /**
     * 当前剩余重试次数
     */
    private int retryTimes = MAX_RETRY_TIMES;

    /**
     * HuaweiApiClient 连接结果回调
     *
     * @param rst    结果码
     * @param client HuaweiApiClient 实例
     */
    @Override
    public void onConnect(int rst, HuaweiApiClient client) {
        if (client == null || !ApiClientMgr.INST.isConnect(client)) {
            HMSAgentLog.e("client not connted");
            onPushTokenResult(rst, null);
            return;
        }

        PendingResult<TokenResult> tokenResult = HuaweiPush.HuaweiPushApi.getToken(client);
        tokenResult.setResultCallback(new ResultCallback<TokenResult>() {
            @Override
            public void onResult(TokenResult result) {
                if (result == null) {
                    HMSAgentLog.e("result is null");
                    onPushTokenResult(HMSAgent.AgentResultCode.RESULT_IS_NULL, null);
                    return;
                }

                Status status = result.getStatus();
                if (status == null) {
                    HMSAgentLog.e("status is null");
                    onPushTokenResult(HMSAgent.AgentResultCode.STATUS_IS_NULL, null);
                    return;
                }

                int rstCode = status.getStatusCode();
                HMSAgentLog.d("rstCode=" + rstCode);
                // 需要重试的错误码，并且可以重试
                if ((rstCode == CommonCode.ErrorCode.SESSION_INVALID
                        || rstCode == CommonCode.ErrorCode.CLIENT_API_INVALID) && retryTimes > 0) {
                    retryTimes--;
                    connect();
                } else {
                    onPushTokenResult(rstCode, result);
                }
            }
        });

    }

    /**
     * 获取pushtoken接口调用回调
     * pushtoken通过广播下发，要监听的广播，请参见HMS-SDK开发准备中PushReceiver的注册
     * @param rstCode 结果码
     * @param result 调用获取pushtoken接口的结果
     */
    void onPushTokenResult(int rstCode, TokenResult result) {
        HMSAgentLog.d("callback=" + handler +" retCode=" + rstCode);
        if (handler != null) {
            handler.onResult(rstCode, result);
            handler = null;
        }
        retryTimes = MAX_RETRY_TIMES;
    }

    /**
     * 获取pushtoken接口
     * pushtoken通过广播下发，要监听的广播，请参见HMS-SDK开发准备中PushReceiver的注册
     * @param handler pushtoken接口调用回调
     */
    public void getToken(GetTokenHandler handler) {
        this.handler = handler;
        retryTimes = MAX_RETRY_TIMES;
        connect();
    }
}
app/src/main/java/com/huawei/android/hms/agent/common/ActivityMgr.java
public final class ActivityMgr implements Application.ActivityLifecycleCallbacks {

    /**
     * 单实例
     */
    public static final ActivityMgr INST = new ActivityMgr();

    /**
     * 应用程序
     */
    private Application application;

    /**
     * 最新的activity，如果没有则为null
     */
    private Activity lastActivity;

    /**
     * activity onResume 事件监听
     */
    private List<IActivityResumeCallback> resumeCallbacks = new ArrayList<IActivityResumeCallback>();
    /**
     * activity onPause 事件监听
     */
    private List<IActivityPauseCallback> pauseCallbacks = new ArrayList<IActivityPauseCallback>();

    /**
     * 私有构造方法
     * 放在外面直接创建实例
     */
    private ActivityMgr(){}

    /**
     * 初始化方法
     * @param app 应用程序
     */
    public void init(Application app, Activity initActivity) {
        HMSAgentLog.d("init");

        if (application != null) {
            application.unregisterActivityLifecycleCallbacks(this);
        }

        application = app;
        lastActivity = initActivity;
        app.registerActivityLifecycleCallbacks(this);
    }

    /**
     * 释放资源，一般不需要调用
     */
    public void release() {
        HMSAgentLog.d("release");
        if (application != null) {
            application.unregisterActivityLifecycleCallbacks(this);
        }

        lastActivity = null;
        clearActivitResumeCallbacks();
        application = null;
    }

    /**
     * 注册activity onResume事件
     * @param callback activity onResume事件回调
     */
    public void registerActivitResumeEvent(IActivityResumeCallback callback) {
        HMSAgentLog.d("registerOnResume:" + callback);
        resumeCallbacks.add(callback);
    }

    /**
     * 反注册activity onResume事件回调
     * @param callback 已经注册的 activity onResume事件回调
     */
    public void unRegisterActivitResumeEvent(IActivityResumeCallback callback) {
        HMSAgentLog.d("unRegisterOnResume:" + callback);
        resumeCallbacks.remove(callback);
    }

    /**
     * 注册activity onPause 事件
     * @param callback activity onPause 事件回调
     */
    public void registerActivitPauseEvent(IActivityPauseCallback callback) {
        HMSAgentLog.d("registerOnPause:" + callback);
        pauseCallbacks.add(callback);
    }

    /**
     * 反注册activity onPause事件回调
     * @param callback 已经注册的 activity onPause事件回调
     */
    public void unRegisterActivitPauseEvent(IActivityPauseCallback callback) {
        HMSAgentLog.d("unRegisterOnPause:" + callback);
        pauseCallbacks.remove(callback);
    }

    /**
     * 清空 activity onResume事件回调
     */
    public void clearActivitResumeCallbacks() {
        HMSAgentLog.d("clearOnResumeCallback");
        resumeCallbacks.clear();
    }

    /**
     * 清空 activity onPause 事件回调
     */
    public void clearActivitPauseCallbacks() {
        HMSAgentLog.d("clearOnPauseCallback");
        pauseCallbacks.clear();
    }

    /**
     * 获取最新的activity
     * @return 最新的activity
     */
    public Activity getLastActivity() {
        return lastActivity;
    }

    /**
     * activity onCreate 监听回调
     * @param activity 发生onCreate事件的activity
     * @param savedInstanceState 缓存状态数据
     */
    @Override
    public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
        HMSAgentLog.d("onCreated:" + activity.getClass().toString());
        lastActivity = activity;
    }

    /**
     * activity onStart 监听回调
     * @param activity 发生onStart事件的activity
     */
    @Override
    public void onActivityStarted(Activity activity) {
        HMSAgentLog.d("onStarted:" + activity.getClass().toString());
        lastActivity = activity;
    }

    /**
     * activity onResume 监听回调
     * @param activity 发生onResume事件的activity
     */
    @Override
    public void onActivityResumed(Activity activity) {
        HMSAgentLog.d("onResumed:" + activity.getClass().toString());
        lastActivity = activity;

        List<IActivityResumeCallback> tmdCallbacks = new ArrayList<IActivityResumeCallback>(resumeCallbacks);
        for (IActivityResumeCallback callback : tmdCallbacks) {
            callback.onActivityResume(activity);
        }
    }

    /**
     * activity onPause 监听回调
     * @param activity 发生onPause事件的activity
     */
    @Override
    public void onActivityPaused(Activity activity) {
        HMSAgentLog.d("onPaused:" + activity.getClass().toString());
        List<IActivityPauseCallback> tmdCallbacks = new ArrayList<IActivityPauseCallback>(pauseCallbacks);
        for (IActivityPauseCallback callback : tmdCallbacks) {
            callback.onActivityPause(activity);
        }
    }

    /**
     * activity onStop 监听回调
     * @param activity 发生onStop事件的activity
     */
    @Override
    public void onActivityStopped(Activity activity) {
        HMSAgentLog.d("onStopped:" + activity.getClass().toString());
    }

    /**
     * activity onSaveInstanceState 监听回调
     * @param activity 发生 onSaveInstanceState 事件的activity
     */
    @Override
    public void onActivitySaveInstanceState(Activity activity, Bundle outState) {
    }

    /**
     * activity onDestroyed 监听回调
     * @param activity 发生 onDestroyed 事件的activity
     */
    @Override
    public void onActivityDestroyed(Activity activity) {
        HMSAgentLog.d("onDestroyed:" + activity.getClass().toString());
        if (activity == lastActivity) {
            lastActivity = null;
        }
    }
}
app/src/main/java/com/huawei/android/hms/agent/push/EnableReceiveNormalMsgApi.java
public class EnableReceiveNormalMsgApi extends BaseApiAgent {

    /**
     * 是否打开开关
     */
    boolean enable;

    /**
     * HuaweiApiClient 连接结果回调
     *
     * @param rst    结果码
     * @param client HuaweiApiClient 实例
     */
    @Override
    public void onConnect(int rst, final HuaweiApiClient client) {
        //需要在子线程中执行开关的操作
        new Thread() {
            public void run() {
                if (client == null || !ApiClientMgr.INST.isConnect(client)) {
                    HMSAgentLog.e("client not connted");
                    return;
                }

                // 开启/关闭透传消息
                HuaweiPush.HuaweiPushApi.enableReceiveNormalMsg(client, enable);
            }
        }.start();
    }

    /**
     * 打开/关闭透传消息
     * @param enable 打开/关闭
     */
    public void enableReceiveNormalMsg(boolean enable) {
        this.enable = enable;
        connect();
    }
}
app/src/main/java/com/huawei/android/hms/agent/common/INoProguard.java
public interface INoProguard {
}
app/src/main/java/com/huawei/android/hms/agent/push/handler/GetTokenHandler.java
public interface GetTokenHandler {
    /**
     * 获取pushtoken调用结果回调
     * @param rtnCode 结果码
     * @param tokenResult 登录结果
     */
    void onResult(int rtnCode, TokenResult tokenResult);
}
app/src/main/java/com/huawei/android/hms/agent/push/EnableReceiveNotifyMsgApi.java
public class EnableReceiveNotifyMsgApi extends BaseApiAgent {

    /**
     * 是否打开开关
     */
    boolean enable;

    /**
     * HuaweiApiClient 连接结果回调
     *
     * @param rst    结果码
     * @param client HuaweiApiClient 实例
     */
    @Override
    public void onConnect(int rst, final HuaweiApiClient client) {
        //需要在子线程中执行开关的操作
        new Thread() {
            public void run() {
                if (client == null || !ApiClientMgr.INST.isConnect(client)) {
                    HMSAgentLog.e("client not connted");
                    return;
                }

                // 开启/关闭自呈现消息
                HuaweiPush.HuaweiPushApi.enableReceiveNotifyMsg(client, enable);
            }
        }.start();
    }

    /**
     * 打开/关闭自呈现消息
     * @param enable 打开/关闭
     */
    public void enableReceiveNotifyMsg(boolean enable) {
        this.enable = enable;
        connect();
    }
}
app/src/main/java/com/huawei/android/hms/agent/common/ApiClientMgr.java
public final class ApiClientMgr implements HuaweiApiClient.ConnectionCallbacks, HuaweiApiClient.OnConnectionFailedListener, IActivityResumeCallback {

    /**
     * 单实例
     */
    public static final ApiClientMgr INST = new ApiClientMgr();

    /**
     * 应用市场包名
     */
    private static final String PACKAGE_NAME_HIAPP = "com.huawei.appmarket";

    /**
     * 回调锁，避免连接回调紊乱
     */
    private static final Object CALLBACK_LOCK = new Object();

    /**
     * 静态注册回调锁，避免注册和回调紊乱
     */
    private static final Object STATIC_CALLBACK_LOCK = new Object();

    /**
     * client操作锁，避免连接使用紊乱
     */
    private static final Object APICLIENT_LOCK = new Object();

    /**
     * api client 连接超时
     */
    private static final int APICLIENT_CONNECT_TIMEOUT = 30000;

    /**
     * 解决升级错误时activity onResume 稳定在3秒时间判断BridgeActivity上面有没有其他activity
     */
    private static final int UPDATE_OVER_ACTIVITY_CHECK_TIMEOUT = 3000;

    /**
     * api client 解决错误拉起界面超时
     */
    private static final int APICLIENT_STARTACTIVITY_TIMEOUT = 3000;

    /**
     * client 连接超时消息
     */
    private static final int APICLIENT_TIMEOUT_HANDLE_MSG = 3;

    /**
     * client 拉起activity超时消息
     */
    private static final int APICLIENT_STARTACTIVITY_TIMEOUT_HANDLE_MSG = 4;

    /**
     * 解决升级错误时activity onResume 稳定在3秒时间判断BridgeActivity上面有没有其他activity
     */
    private static final int UPDATE_OVER_ACTIVITY_CHECK_TIMEOUT_HANDLE_MSG = 5;

    /**
     * 最大尝试连接次数
     */
    private static final int MAX_RESOLVE_TIMES = 3;

    /**
     * 上下文，用来处理连接失败
     */
    private Context context;

    /**
     * 当前应用包名
     */
    private String curAppPackageName;

    /**
     * HuaweiApiClient 实例
     */
    private HuaweiApiClient apiClient;

    /**
     * 是否允许解决connect错误（解决connect错误需要拉起activity）
     */
    private boolean allowResolveConnectError = false;

    /**
     * 是否正在解决连接错误
     */
    private boolean isResolving;

    /**
     * HMSSDK 解决错误的activity
     */
    private BridgeActivity resolveActivity;

    /**
     * 是否存在其他activity覆盖在升级activity之上
     */
    private boolean hasOverActivity = false;

    /**
     * 当前剩余尝试次数
     */
    private int curLeftResolveTimes = MAX_RESOLVE_TIMES;

    /**
     * 连接回调
     */
    private List<IClientConnectCallback> connCallbacks = new ArrayList<IClientConnectCallback>();

    /**
     * 注册的静态回调
     */
    private List<IClientConnectCallback> staticCallbacks = new ArrayList<IClientConnectCallback>();

    private static class EmptyConnectCallback implements IClientConnectCallback {

        private String msgPre;

        private EmptyConnectCallback(String msgPre){
            this.msgPre = msgPre;
        }

        /**
         * HuaweiApiClient 连接结果回调
         *
         * @param rst    结果码
         * @param client HuaweiApiClient 实例
         */
        @Override
        public void onConnect(int rst, HuaweiApiClient client) {
            HMSAgentLog.d(msgPre + rst);
        }
    }

    /**
     * 超时handler用来处理client connect 超时
     */
    private Handler timeoutHandler = new Handler(new Handler.Callback() {
        @Override
        public boolean handleMessage(Message msg) {

            boolean hasConnCallbacks;
            synchronized (CALLBACK_LOCK) {
                hasConnCallbacks = !connCallbacks.isEmpty();
            }

            if (msg != null && msg.what == APICLIENT_TIMEOUT_HANDLE_MSG && hasConnCallbacks) {
                HMSAgentLog.d("connect time out");
                resetApiClient();
                onConnectEnd(HMSAgent.AgentResultCode.APICLIENT_TIMEOUT);
                return true;
            } else if (msg != null && msg.what == APICLIENT_STARTACTIVITY_TIMEOUT_HANDLE_MSG && hasConnCallbacks) {
                HMSAgentLog.d("start activity time out");
                onConnectEnd(HMSAgent.AgentResultCode.APICLIENT_TIMEOUT);
                return true;
            } else if (msg != null && msg.what == UPDATE_OVER_ACTIVITY_CHECK_TIMEOUT_HANDLE_MSG && hasConnCallbacks) {
                HMSAgentLog.d("Discarded update dispose:hasOverActivity=" + " resolveActivity=" + resolveActivity);
                if (hasOverActivity && resolveActivity != null && !resolveActivity.isFinishing()) {
                    onResolveErrorRst(ConnectionResult.CANCELED);
                }
                return true;
            }
            return false;
        }
    });

    /**
     * 私有构造方法
     */
    private ApiClientMgr () {
    }

    /**
     * 初始化
     * @param app 应用程序
     */
    public void init(Application app) {

        HMSAgentLog.d("init");

        // 保存应用程序context
        context = app.getApplicationContext();

        // 取得应用程序包名
        curAppPackageName = app.getPackageName();

        // 注册activity onResume回调
        ActivityMgr.INST.unRegisterActivitResumeEvent(this);
        ActivityMgr.INST.registerActivitResumeEvent(this);
    }

    /**
     * 断开apiclient，一般不需要调用
     */
    public void release() {
        HMSAgentLog.d("release");
        HuaweiApiClient client =  getApiClient();
        if (client != null) {
            client.disconnect();
        }

        synchronized (STATIC_CALLBACK_LOCK) {
            staticCallbacks.clear();
        }

        synchronized (CALLBACK_LOCK) {
            connCallbacks.clear();
        }
    }

    /**
     * 获取当前的 HuaweiApiClient
     * @return HuaweiApiClient 实例
     */
    public HuaweiApiClient getApiClient() {
        synchronized (APICLIENT_LOCK) {
            return apiClient;
        }
    }

    /**
     * 判断client是否已经连接
     * @param client 要检测的client
     * @return 是否已经连接
     */
    public boolean isConnect(HuaweiApiClient client) {
        return client != null && client.isConnected();
    }

    /**
     * 注册apiclient连接事件
     * @param staticCallback 连接回调
     */
    public void registerClientConnect(IClientConnectCallback staticCallback){
        synchronized (STATIC_CALLBACK_LOCK) {
            staticCallbacks.add(staticCallback);
        }
    }

    /**
     * 反注册apiclient连接事件
     * @param staticCallback 连接回调
     */
    public void removeClientConnectCallback(IClientConnectCallback staticCallback) {
        synchronized (STATIC_CALLBACK_LOCK) {
            staticCallbacks.remove(staticCallback);
        }
    }

    /**
     * 重新创建apiclient
     * 2种情况需要重新创建：1、首次 2、client的状态已经紊乱
     * @return 新创建的client
     */
    private HuaweiApiClient resetApiClient(){
        synchronized (APICLIENT_LOCK) {
            if (apiClient != null) {
                // 对于老的apiClient，1分钟后才丢弃，防止外面正在使用过程中这边disConnect了
                disConnectClientDelay(apiClient, 60000);
            }

            HMSAgentLog.d("reset client");

            // 这种重置client，极端情况可能会出现2个client都回调结果的情况。此时可能出现rstCode=0，但是client无效。
            // 因为业务调用封装中都进行了一次重试。所以不会有问题
            apiClient = new HuaweiApiClient.Builder(context)
                    .addApi(HuaweiPush.PUSH_API)
                    .addConnectionCallbacks(INST)
                    .addOnConnectionFailedListener(INST)
                    .build();
            return apiClient;
        }
    }
    /**
     * 连接
     * @param callback 连接回调,一定不能为null
     */
    public void connect(IClientConnectCallback callback, boolean allowResolve) {

        if (context == null) {
            callback.onConnect(HMSAgent.AgentResultCode.HMSAGENT_NO_INIT, null);
            return;
        }

        HuaweiApiClient client =  getApiClient();
        // client 有效，则直接回调
        if (client != null && client.isConnected()) {
            HMSAgentLog.d("client is valid");
            callback.onConnect(0, client);
            return;
        } else {
            // client无效，将callback加入队列，并启动连接
            synchronized (CALLBACK_LOCK) {
                HMSAgentLog.d("client is invalid：size=" + connCallbacks.size());
                allowResolveConnectError = allowResolveConnectError || allowResolve;
                if (connCallbacks.isEmpty()) {
                    connCallbacks.add(callback);

                    // 连接尝试最大次数
                    curLeftResolveTimes = MAX_RESOLVE_TIMES;

                    startConnect();
                } else {
                    connCallbacks.add(callback);
                }
            }
        }
    }

    /**
     * 线程中进行Huawei Api Client 的连接
     */
    private void startConnect() {

        // 触发一次连接将重试次数减1
        curLeftResolveTimes--;

        HMSAgentLog.d("start thread to connect");
        new Thread() {
            @Override
            public void run() {
                super.run();
                HuaweiApiClient client =  getApiClient();
                if (client == null) {
                    HMSAgentLog.d("create client");
                    client = resetApiClient();
                }

                HMSAgentLog.d("connect");
                timeoutHandler.sendEmptyMessageDelayed(APICLIENT_TIMEOUT_HANDLE_MSG, APICLIENT_CONNECT_TIMEOUT);
                client.connect();
            }
        }.start();
    }

    /**
     * Huawei Api Client 连接结束方法
     * @param rstCode client 连接结果码
     */
    private void onConnectEnd(final int rstCode) {
        HMSAgentLog.d("connect end:" + rstCode);

        synchronized (CALLBACK_LOCK) {
            // 回调各个回调接口连接结束
            for (IClientConnectCallback callback : connCallbacks) {
                aSysnCallback(rstCode, callback);
            }
            connCallbacks.clear();

            // 恢复默认不显示
            allowResolveConnectError = false;
        }

        synchronized (STATIC_CALLBACK_LOCK) {
            // 回调各个回调接口连接结束
            for (IClientConnectCallback callback : staticCallbacks) {
                aSysnCallback(rstCode, callback);
            }
            staticCallbacks.clear();
        }
    }

    /**
     * 起线程回调各个接口，避免其中一个回调者耗时长影响其他调用者
     * @param rstCode 结果码
     * @param callback 回调
     */
    private void aSysnCallback(final int rstCode, final IClientConnectCallback callback) {
        new Thread() {
            @Override
            public void run() {
                super.run();
                HuaweiApiClient client =  getApiClient();
                HMSAgentLog.d("callback connect: rst=" + rstCode + " apiClient=" + client);
                callback.onConnect(rstCode, client);
            }
        }.start();
    }

    /**
     * Activity onResume回调
     *
     * @param activity 发生 onResume 事件的activity
     */
    @Override
    public void onActivityResume(Activity activity) {

        // 如果正在解决错误，则处理被覆盖的场景
        HMSAgentLog.d("is resolving:" + isResolving);
        if (isResolving && !PACKAGE_NAME_HIAPP.equals(curAppPackageName)) {
            if (activity instanceof BridgeActivity) {
                resolveActivity = (BridgeActivity)activity;
                hasOverActivity = false;
                HMSAgentLog.d("received bridgeActivity:" + resolveActivity);
            } else if (resolveActivity != null && !resolveActivity.isFinishing()){
                hasOverActivity = true;
                HMSAgentLog.d("received other Activity:" + resolveActivity);
            }
            timeoutHandler.removeMessages(UPDATE_OVER_ACTIVITY_CHECK_TIMEOUT_HANDLE_MSG);
            timeoutHandler.sendEmptyMessageDelayed(UPDATE_OVER_ACTIVITY_CHECK_TIMEOUT_HANDLE_MSG, UPDATE_OVER_ACTIVITY_CHECK_TIMEOUT);
        }
    }

    /**
     * connect fail 解决结果回调， 由 HMSAgentActivity 在 onActivityResult 中调用
     * @param result 解决结果
     */
    void onResolveErrorRst(int result) {
        HMSAgentLog.d("result="+result);
        isResolving = false;
        resolveActivity = null;
        hasOverActivity = false;

        if(result == ConnectionResult.SUCCESS) {
            HuaweiApiClient client =  getApiClient();
            if (!client.isConnecting() && !client.isConnected() && curLeftResolveTimes > 0) {
                startConnect();
                return;
            }
        }

        onConnectEnd(result);
    }

    /**
     * HMSAgentActivity 拉起拉了（走了onCreate）
     */
    void onActivityLunched(){
        HMSAgentLog.d("resolve onActivityLunched");
        // 拉起界面回调，移除拉起界面超时
        timeoutHandler.removeMessages(APICLIENT_STARTACTIVITY_TIMEOUT_HANDLE_MSG);
        isResolving = true;
    }

    /**
     * Huawe Api Client 连接成功回到
     */
    @Override
    public void onConnected() {
        HMSAgentLog.d("connect success");
        timeoutHandler.removeMessages(APICLIENT_TIMEOUT_HANDLE_MSG);
        onConnectEnd(ConnectionResult.SUCCESS);
    }

    /**
     * 当client变成断开状态时会被调用。这有可能发生在远程服务出现问题时（例如：出现crash或资源问题导致服务被系统杀掉）。
     * 当被调用时，所有的请求都会被取消，任何listeners都不会被执行。需要 CP 开发代码尝试恢复连接（connect）。
     * 应用程序应该禁用需要服务的相关UI组件，等待{@link #onConnected()} 回调后重新启用他们。<br>
     *
     * @param cause 断开的原因. 常量定义： CAUSE_*.
     */
    @Override
    public void onConnectionSuspended(int cause) {
        HMSAgentLog.d("connect suspended");
        connect(new EmptyConnectCallback("onConnectionSuspended try end:"), true);
    }

    /**
     * 建立client到service的连接失败时调用
     *
     * @param result 连接结果，用于解决错误和知道什么类型的错误
     */
    @Override
    public void onConnectionFailed(ConnectionResult result) {
        timeoutHandler.removeMessages(APICLIENT_TIMEOUT_HANDLE_MSG);

        if (result == null) {
            HMSAgentLog.e("result is null");
            onConnectEnd(HMSAgent.AgentResultCode.RESULT_IS_NULL);
            return;
        }

        int errCode = result.getErrorCode();
        HMSAgentLog.d("errCode=" + errCode + " allowResolve=" + allowResolveConnectError);

        if(HuaweiApiAvailability.getInstance().isUserResolvableError(errCode) && allowResolveConnectError) {
            Activity activity = ActivityMgr.INST.getLastActivity();
            if (activity != null) {
                try {
                    timeoutHandler.sendEmptyMessageDelayed(APICLIENT_STARTACTIVITY_TIMEOUT_HANDLE_MSG, APICLIENT_STARTACTIVITY_TIMEOUT);
                    Intent intent = new Intent(activity, HMSAgentActivity.class);
                    intent.putExtra(HMSAgentActivity.CONN_ERR_CODE_TAG, errCode);
                    activity.startActivity(intent);
                    return;
                } catch (Exception e) {
                    HMSAgentLog.e("start HMSAgentActivity exception:" + e.getMessage());
                    onConnectEnd(HMSAgent.AgentResultCode.START_ACTIVITY_ERROR);
                    return;
                }
            } else {
                // 当前没有界面处理不了错误
                HMSAgentLog.d("no activity");
                onConnectEnd(HMSAgent.AgentResultCode.NO_ACTIVITY_FOR_USE);
                return;
            }
        } else {
            //其他错误码直接透传
        }

        onConnectEnd(errCode);
    }

    private static void disConnectClientDelay(final HuaweiApiClient clientTmp, int delay) {
        new Handler().postDelayed(new Runnable() {
            @Override
            public void run() {
                clientTmp.disconnect();
            }
        }, delay);
    }
}


Question: package com.huawei.android.hms.agent;
import android.app.Activity;
import android.app.Application;
import com.huawei.android.hms.agent.common.ActivityMgr;
import com.huawei.android.hms.agent.common.ApiClientMgr;
import com.huawei.android.hms.agent.common.HMSAgentLog;
import com.huawei.android.hms.agent.common.IClientConnectCallback;
import com.huawei.android.hms.agent.common.INoProguard;
import com.huawei.android.hms.agent.common.handler.ConnectHandler;
import com.huawei.android.hms.agent.push.DeleteTokenApi;
import com.huawei.android.hms.agent.push.EnableReceiveNormalMsgApi;
import com.huawei.android.hms.agent.push.EnableReceiveNotifyMsgApi;
import com.huawei.android.hms.agent.push.GetPushStateApi;
import com.huawei.android.hms.agent.push.GetTokenApi;
import com.huawei.android.hms.agent.push.QueryAgreementApi;
import com.huawei.android.hms.agent.push.handler.GetTokenHandler;
import com.huawei.hms.api.HuaweiApiAvailability;
import com.huawei.hms.api.HuaweiApiClient;




/**
 * HMSAgent 封装入口类。 提供了HMS SDK 功能的封装，使开发者更聚焦业务的处理。
 */
public final class HMSAgent implements INoProguard {

    /**
     * 基础版本
     */
    private static final String VER_020503001 = "020503001";

    /**
     * 2.5.3 版本2
     * 自身优化：
     *      1、增加了升级时被其他界面覆盖的处理，解决错误回调成功，增加重试次数3次
     *      2、增强异常分支日志
	 *      3、提供了多种HMSAgent初始化方法
     */
    private static final String VER_020503002 = "020503002";

    /**
     * 2.5.3 版本3
     * 自身优化：
     *      1、示例代码manifest增加升级相关的配置
     *      2、代码提取脚本兼容路径有空格的情景
     */
    private static final String VER_020503003 = "020503003";

    /**
     * 当前版本号
     */
    public static final String CURVER = VER_020503003;

    public static final class AgentResultCode {

        /**
         * HMSAgent 成功
         */
        public static final int HMSAGENT_SUCCESS = 0;

        /**
         * HMSAgent 没有初始化
         */
        public static final int HMSAGENT_NO_INIT = -1000;

        /**
         * 请求需要activity，但当前没有可用的activity
         */
        public static final int NO_ACTIVITY_FOR_USE = -1001;

        /**
         * 结果为空
         */
        public static final int RESULT_IS_NULL = -1002;

        /**
         * 状态为空
         */
        public static final int STATUS_IS_NULL = -1003;

        /**
         * 拉起activity异常，需要检查activity有没有在manifest中配置
         */
        public static final int START_ACTIVITY_ERROR = -1004;

        /**
         * onActivityResult 回调结果错误
         */
        public static final int ON_ACTIVITY_RESULT_ERROR = -1005;

        /**
         * 重复请求
         */
        public static final int REQUEST_REPEATED = -1006;

        /**
         * 连接client 超时
         */
        public static final int APICLIENT_TIMEOUT = -1007;
    }

    private HMSAgent(){}


    /**
     * 初始化方法，传入第一个界面的activity
     * @param activity 当前界面
     * @return true：成功 false：失败
     */
    public static boolean init(Activity activity) {
        return init(null, activity);
    }

    /**
     * 初始化方法，建议在Application onCreate里面调用
     * @param app 应用程序
     * @return true：成功 false：失败
     */
    public static boolean init(Application app) {
        return init(app, null);
    }

    /**
     * 初始化方法，建议在Application onCreate里面调用
     * @param app 应用程序
     * @param activity 当前界面
     * @return true：成功 false：失败
     */
    public static boolean init(Application app, Activity activity) {

        Application appTmp = app;
        Activity activityTmp = activity;

        // 两个参数都为null，直接抛异常
        if (appTmp == null && activityTmp == null) {
            HMSAgentLog.e("the param of method HMSAgent.init can not be null !!!");
            return false;
        }

        // 如果application实例为null，则从activity里面取
        if (appTmp == null) {
            appTmp = activityTmp.getApplication();
        }

        // 如果application实例仍然为null，抛异常
        if (appTmp == null) {
            HMSAgentLog.e("the param of method HMSAgent.init app can not be null !!!");
            return false;
        }

        // activity 已经失效，则赋值null
        if (activityTmp != null && activityTmp.isFinishing()) {
            activityTmp = null;
        }

        HMSAgentLog.i("init HMSAgent " + CURVER + " with hmssdkver " + HuaweiApiAvailability.HMS_SDK_VERSION_CODE);

        // 初始化activity管理类
        ActivityMgr.INST.init(appTmp, activityTmp);

        // 初始化HuaweiApiClient管理类
        ApiClientMgr.INST.init(appTmp);

        return true;
    }

    /**
     * 释放资源，这里一般不需要调用
     */
    public static void destroy() {
        ActivityMgr.INST.release();
        ApiClientMgr.INST.release();
    }

    /**
     * 连接HMS SDK， 可能拉起界面(包括升级引导等)，建议在第一个界面进行连接。
     * 此方法可以重复调用，没必要为了只调用一次做复杂处理
     * @param activity 当前界面的activity， 不能传空
     * @param callback 连接结果回调
     */
    public static void connect(Activity activity, final ConnectHandler callback) {
        ApiClientMgr.INST.connect(new IClientConnectCallback() {
            @Override
            public void onConnect(int rst, HuaweiApiClient client) {
                if (callback != null) {
                    callback.onConnect(rst);
                }
            }
        }, true);
    }

    /**
     * 检查本应用的升级
     * @param activity 上下文
     */
    public static void checkUpdate (final Activity activity) {
        HMSAgentLog.d("start checkUpdate");
        ApiClientMgr.INST.connect(new IClientConnectCallback() {
            @Override
            public void onConnect(int rst, HuaweiApiClient client) {
                Activity activityCur = ActivityMgr.INST.getLastActivity();

                if (activityCur != null && client != null) {
                    client.checkUpdate(activityCur);
                } else if (activity != null && client != null){
                    client.checkUpdate(activity);
                } else {
                    // 跟SE确认：activity 为 null ， 不处理
                    HMSAgentLog.e("no activity to checkUpdate");
                }
            }
        }, true);
    }





    /**
     * push接口封装
     */
    public static final class Push {
        /**
         * 获取pushtoken接口
         * pushtoken通过广播下发，要监听的广播，请参见HMS-SDK开发准备中PushReceiver的注册
         * @param handler pushtoken接口调用回调
         */
        public static void getToken(GetTokenHandler handler){
            new GetTokenApi().getToken(handler);
        }

        /**
         * 删除指定的pushtoken
         * 该接口只在EMUI5.1以及更高版本的华为手机上调用该接口后才不会收到PUSH消息。
         * @param token 要删除的token
         */
        public static void deleteToken(String token){
            new DeleteTokenApi().deleteToken(token);
        }

        /**
         * 获取push状态，push状态的回调通过广播发送。
         * 要监听的广播，请参见HMS-SDK开发准备中PushReceiver的注册
         */
        public static void getPushState(){
            new GetPushStateApi().getPushState();
        }

        /**
         * 打开/关闭通知栏消息
         * @param enable 打开/关闭
         */
        public static void enableReceiveNotifyMsg(boolean enable){
Answer:             new EnableReceiveNotifyMsgApi().enableReceiveNotifyMsg(enable);