SDK Debugging Guide

Last updated:2021-12-15
Expand all
SDK Debugging Guide

SDK Startup Process

  • Check whether AppKey is configured in AndroidManifest.xml. If not, startup will fail.
  • Check whether the AndroidManifest.xml configuration is correct. All items marked as Required in the Android SDK Integration Guide must be configured correctly, otherwise startup will fail.
  • Check whether the JPush SDK library files are valid. If the library files are invalid, startup will fail.
  • Check whether the network is available. It is recommended to test with 4G. If the network is available, the SDK will connect to the server and log in; otherwise startup will fail.
  • After successful login, you can see logs similar to the following in logcat.

Verification Checklist

  • Confirm that all Required items in AndroidManifest.xml have been added. Missing required items will cause error logs.
  • Confirm that the AppKey generated in the Portal has been written correctly into AndroidManifest.xml. If not, logs will report an error.
  • Confirm that the init(context) API is called when the app starts.
  • Confirm that the test device or emulator has network access. If the network is normal, shortly after the client calls init, you should see a successful login message (Login succeed) in the logs, as shown in the SDK startup process above.
  • Start the app, log in to the Portal, and send either a custom message or a notification to the app. The client should receive the delivered notification or custom message within a few seconds.

Handling Alias and Tag Setting Failures

Because network connections may be unstable, there is a certain probability that alias and tag operations in the JPush SDK will fail.

If app developers handle these failures properly, occasional failures have only limited impact on normal JPush usage.

The following example uses the Android SDK.

Basic idea:

  • When a setting succeeds, write a success flag into SharedPreferences, so you do not need to set it again later.
  • If error 6002 (timeout) occurs, retry after a short delay.
// This code comes from the alias-setting Activity in the JPush Example project. // In a real app, you can call this logic from any appropriate entry point. private void setAlias() { EditText aliasEdit = (EditText) findViewById(R.id.et_alias); String alias = aliasEdit.getText().toString().trim(); if (TextUtils.isEmpty(alias)) { Toast.makeText(PushSetActivity.this,R.string.error_alias_empty, Toast.LENGTH_SHORT).show(); return; } if (!ExampleUtil.isValidTagAndAlias(alias)) { Toast.makeText(PushSetActivity.this,R.string.error_tag_gs_empty, Toast.LENGTH_SHORT).show(); return; } // Use a Handler to set the alias asynchronously mHandler.sendMessage(mHandler.obtainMessage(MSG_SET_ALIAS, alias)); } private final TagAliasCallback mAliasCallback = new TagAliasCallback() { @Override public void gotResult(int code, String alias, Set<String> tags) { String logs; switch (code) { case 0: logs = "Set tag and alias success"; Log.i(TAG, logs); // It is recommended to write a success flag into SharedPreferences here. // Once set successfully, you usually do not need to set it again. break; case 6002: logs = "Failed to set alias and tags due to timeout. Try again after 60s."; Log.i(TAG, logs); // Retry after 60 seconds mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_SET_ALIAS, alias), 1000 * 60); break; default: logs = "Failed with errorCode = " + code; Log.e(TAG, logs); } ExampleUtil.showToast(logs, getApplicationContext()); } }; private static final int MSG_SET_ALIAS = 1001; private final Handler mHandler = new Handler() { @Override public void handleMessage(android.os.Message msg) { super.handleMessage(msg); switch (msg.what) { case MSG_SET_ALIAS: Log.d(TAG, "Set alias in handler."); // Call the JPush interface to set the alias JPushInterface.setAliasAndTags( getApplicationContext(), (String) msg.obj, null, mAliasCallback ); break; default: Log.i(TAG, "Unhandled msg - " + msg.what); } } };
          // This code comes from the alias-setting Activity in the JPush Example project.
// In a real app, you can call this logic from any appropriate entry point.
private void setAlias() {
    EditText aliasEdit = (EditText) findViewById(R.id.et_alias);
    String alias = aliasEdit.getText().toString().trim();
    if (TextUtils.isEmpty(alias)) {
        Toast.makeText(PushSetActivity.this,R.string.error_alias_empty, Toast.LENGTH_SHORT).show();
        return;
    }
    if (!ExampleUtil.isValidTagAndAlias(alias)) {
        Toast.makeText(PushSetActivity.this,R.string.error_tag_gs_empty, Toast.LENGTH_SHORT).show();
        return;
    }

    // Use a Handler to set the alias asynchronously
    mHandler.sendMessage(mHandler.obtainMessage(MSG_SET_ALIAS, alias));
}

private final TagAliasCallback mAliasCallback = new TagAliasCallback() {
    @Override
    public void gotResult(int code, String alias, Set<String> tags) {
        String logs;
        switch (code) {
        case 0:
            logs = "Set tag and alias success";
            Log.i(TAG, logs);
            // It is recommended to write a success flag into SharedPreferences here.
            // Once set successfully, you usually do not need to set it again.
            break;
        case 6002:
            logs = "Failed to set alias and tags due to timeout. Try again after 60s.";
            Log.i(TAG, logs);
            // Retry after 60 seconds
            mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_SET_ALIAS, alias), 1000 * 60);
            break;
        default:
            logs = "Failed with errorCode = " + code;
            Log.e(TAG, logs);
        }
        ExampleUtil.showToast(logs, getApplicationContext());
    }
};

private static final int MSG_SET_ALIAS = 1001;

private final Handler mHandler = new Handler() {
    @Override
    public void handleMessage(android.os.Message msg) {
        super.handleMessage(msg);
        switch (msg.what) {
            case MSG_SET_ALIAS:
                Log.d(TAG, "Set alias in handler.");
                // Call the JPush interface to set the alias
                JPushInterface.setAliasAndTags(
                    getApplicationContext(),
                    (String) msg.obj,
                    null,
                    mAliasCallback
                );
                break;
            default:
                Log.i(TAG, "Unhandled msg - " + msg.what);
        }
    }
};

        
This code block is shown in the floating window

Analysis of Android SDK Network Issues

Unstable network connectivity on Android clients may cause the app to fail to receive push messages in time.

Many developers assume that this means JPush delivery is unstable or delayed, or even that there is a problem with the JPush backend delivery system.

The purpose of this article is to analyze network-related causes on Android that may prevent JPush from working properly.

Necessary Conditions for JPush to Work Properly

First, it is important to understand that JPush SDK does not automatically keep working forever after it is integrated into an app.

The necessary condition for normal operation is that the JPush SDK remains connected to the JPush server. For more background, please refer to this article: JPush technical principle: mobile wireless network long connection

The complexity and instability of Android device networking is one of the hardest parts of Android development.

In addition, network capability varies significantly from device to device. Some low-cost domestic devices may have serious network problems, while major-brand devices generally perform much better.

As long as the JPush network connection is healthy:

  • JPush receives messages in a timely manner. Delay is usually on the order of seconds, generally within 1 second. If it takes more than 10 seconds, the problem is almost certainly on the client network side.
  • Even when the phone is sleeping, push messages can still be received in a timely manner.

Problems Caused by Special Handling in Some Systems

MIUI V5

  • Startup management: by default, after the phone boots, only system-default services can start. Third-party apps can start automatically only if this is allowed in startup management.
  • Network assistant: users can manually block installed third-party apps from accessing 2G/3G and WIFI, and also configure whether newly installed apps are allowed to access those networks.

Android 4.0 and Above

  • After force-stopping an app from Settings -> Apps, the app cannot auto-start again, even after reboot. It must be started manually.

Debugging Ideas Based on Current Feedback

1. JPush messages are not received while the phone is sleeping, but can be received after unlock or when the screen lights up

This indicates that while the phone is sleeping, the JPush SDK is being "forced" to lose its connection to the server.

The JPush SDK is designed to keep working even while the phone is sleeping, so push messages can still be received promptly. In practice, JPush can achieve this on most devices.

This "forced" behavior is caused by the Android device environment. Possible causes include:

  • Network settings on the device itself. Standard Android ROMs do not usually have these settings, but some customized ROMs may.
  • Additional handling by security or power-saving tools on the device.

These special mechanisms may shut down the network. Once the network reconnects, JPush also reconnects to the server, and push messages can then be received.

2. Sometimes JPush messages arrive promptly, but sometimes they take several minutes

JPush listens for network-switch broadcasts. When the network disconnects, the existing JPush connection is closed. When a new network becomes available, JPush creates a new connection.

In addition, RTC sends heartbeats periodically. If the previous network was already disconnected, the SDK reconnects when the heartbeat runs.

The current network connection strategy is relatively simple. The purpose is to save battery and reduce traffic usage.

The downside is that when the network does not switch but becomes poor enough to interrupt the JPush connection, the SDK may have to wait until the next RTC heartbeat before reconnecting. This is one reason JPush may sometimes fail to receive messages promptly. The probability depends on network conditions. Based on our own testing, however, push messages are still received in time around 90% of the time.

JPush does not currently use an aggressive network strategy like chat apps such as WeChat. Doing so would inevitably increase battery and traffic consumption significantly.

3. JPush messages are never received

If you cannot receive any push messages at all after integration, it is very likely that there is a configuration error somewhere. Check the client logs first and troubleshoot against the documentation:

Android SDK Integration Guide iOS SDK Integration Guide

You can also refer to these debugging guides:

Android SDK Debugging Guide iOS SDK Debugging Guide

Was this document helpful?

Copyright 2011-2026, jiguang.cn, All Rights Reserved. 粤ICP备12056275号-13 Shenzhen Hexun Huagu Information Technology Co., Ltd.

Open in Docs Center