tencent cloud

Android FAQs
Last updated: 2025-11-26 15:58:02
Android FAQs
Last updated: 2025-11-26 15:58:02

Issue: Mini program fails to start

There may be several reasons for this:
Incorrect configuration file path: The configAssetName should specify the complete path of the file in the assets directory. If the configuration file is in a subdirectory, you need to include the directory path, for example: server/tcmpp-android-configurations.json.
Modification of configuration file: You cannot modify the contents of the mini program configuration file; otherwise, the mini program will not function properly.
Mismatch in packageName: The packageName in the configuration file must match the superapp's applicationId . If they do not match, the superapp will fail to run, as the packageName is verified during initialization. You can disable package name verification with the following setting:
MiniInitConfig config = builder
.verifyPkg(false) // Ignore the package name verification
.build();


Initialization annotation: Ensure that the initialization annotation @ProxyService has generated the class ExtProxyServiceScope.




How does the SDK ensure privacy compliance?

The mini program SDK initializes when the developer calls methods from the TmfMiniSDK class. Therefore, you should call these methods only after the user has given consent for privacy compliance.

How to troubleshoot errors in custom mini program APIs?

Check if XxxJsPluginScope has been generated in the compilation path, as shown below:

Ensure that the event names defined on the client side match the method names called in the mini program.Note that the event names for custom mini program APIs are case-sensitive..

Mini program domain and privacy API verification logic

While using the mini program, the legality of the API request domain name will be verified, and authorization for privacy APIs will be checked if set in the management backend. However, verification is skipped in the following scenario:
The mini program is running in an unreleased version and the mini program debugging is enabled. See Mini Program Debugging.

Support for modular projects

When developers use the annotations @JsPlugin or @ProxyService in multiple modules within a modular project, the following error may occur during the Make Project process:

To support multi-module projects, follow these configurations:
1. In the build.gradle of each module that uses the @JsPlugin or @ProxyService annotation, add the following code:
android {
defaultConfig {
javaCompileOptions {
annotationProcessorOptions {
// Configure module name: Define a unique name following Android class naming conventions
arguments = [tcmppModuleName: "Demo"]
}
}
}
}
2. Register the module in the initialization code:
@ProxyService(proxy = MiniConfigProxy.class)
public class MiniConfigProxyImpl extends MiniConfigProxy {
@Override
public MiniInitConfig buildConfig() {
MiniInitConfig.Builder builder = new MiniInitConfig.Builder();

// Register all defined modules; the registerModule parameter value should match the tcmppModuleName defined above
return builder


How to view SDK log output?

1. Developers can filter SDK logs in the Android Studio using the keyword TMF_MINI.



2. View mini program JS error logs.
Method 1: Filter JS logs using the keyword MINI_JS_LOG.

Method 2: Debug mini program JS errors in Chrome.


How to enable mini program debugging mode?

To facilitate debugging and log viewing for the mini program, the client needs to enable the mini program debug entry. For details, see Extension Button List for the More Menu
/**
* Returns the buttons in the "More" panel. Each button must be assigned an ID, and the ID value should be an integer between 100 and 200.
* Note: This method applies when called within the mini program process.
* @param builder
* @return
*/
public ArrayList<MoreItem> getMoreItems(MoreItemList.Builder builder){
builder.addDebug("Debug", icon) // Set the Debug button on the control panel
return builder.build();
}
Once set up, a Debug button will appear in the mini program control panel. Tapping it will enable debug mode, and you'll need to restart the mini program to activate it.


Does the mini program SDK automatically clear mini program package cache?

No, developers need to manually call the mini program SDK's deletion methods to clear the mini programs package cache (Deleting Mini Programs). If not, the superapp's cache will increase as the number of mini program used increases.

Why can't I use the mini program normally after enabling the R8 full mode?

R8 full mode obfuscation uses stricter rules, which can cause some annotations in older versions of the mini-program SDK to be lost, potentially preventing the mini-program from starting correctly. Starting from Android Gradle Plugin version 8.0, R8 full mode is enforced during compilation. Please upgrade the mini program SDK mini_core to version 2.0.5 or later to be compatible with the R8 full mode.

How to resolve the web-view multi-process data directory conflicts?

Issue description:
web-view does not support using the same data directory in multiple processes. If not managed properly, this can lead to the following error:

The mini program operates on a multi-process architecture, and the SDK has been adapted to address this issue. However, if customers integrate third-party libraries within the mini program process, some of these libraries may not have adapted to the web-view data directory, which can prevent the mini program from starting properly.
Solution:
1. It is recommended to avoid integrating third-party libraries in the mini program process if it is not required. The mini program process can be identified as follows:
public class TCMPPDemoApplication extends Application
@Override
public void onCreate() {
super.onCreate();
if (TmfMiniSDK.isMiniProcess(this)) {
// Skip the third-party framework initialization in the mini program process
}
}
}
2. If you must integrate third-party libraries that use web-view, modify the web-view data directory as early as possible to avoid issues. Here’s how:
public class TCMPPDemoApplication extends Application {
@Override
protected void attachBaseContext(Context base) {
super.attachBaseContext(base);
sApp = this;
// com.tencent.tmfmini.sdk.launcher.DFMWebViewCompat;
DFMWebViewCompat.setDataDirectorySuffix(this);
}
}

Some devices display a brief black screen during cold start of mini programs

Some devices may experience a brief black screen when cold starting the mini program due to performance issues or lengthy UI thread operations. To avoid this, you can set a preview background for the proxy Activity:
1. Extend the MiniApp class to create a custom theme that modifies the default preview background to replace the black screen:
<style name="MyMiniApp" parent="MiniApp">
<!--Enable window preview using windowDisablePreview-->
<item name="android:windowDisablePreview">false</item>
<!--Set the preview background using windowBackground-->
<item name="android:windowBackground">#FF0000</item>
</style>
2. Update AndroidManifest.xml: Change the theme of MiniActivity to your custom theme.
<activity
tools:replace="android:theme"
android:name="com.tencent.tmfmini.sdk.ui.MiniActivity1"
android:theme="@style/MyMiniApp" />

<activity
tools:replace="android:theme"
android:name="com.tencent.tmfmini.sdk.ui.MiniActivity2"
android:theme="@style/MyMiniApp"/>

<activity
tools:replace="android:theme"
android:name="com.tencent.tmfmini.sdk.ui.MiniActivity3"
android:theme="@style/MyMiniApp" />

<activity
tools:replace="android:theme"
android:name="com.tencent.tmfmini.sdk.ui.MiniActivity4"
android:theme="@style/MyMiniApp"/>

<activity
tools:replace="android:theme"
android:name="com.tencent.tmfmini.sdk.ui.MiniActivity5"
android:theme="@style/MyMiniApp" />
<activity
tools:replace="android:theme"
android:name="com.tencent.tmfmini.sdk.ui.MiniActivity6"
android:theme="@style/MyMiniApp" />

How to set the conditions for canary release?

Superapp developers can use the methods provided by the SDK to set user or device attributes, making it easier to apply in scenarios like canary release.
Customize device ID
When initializing the SDK, set a custom device ID through initialization configuration to match the canary release conditions in the console. Example:
@ProxyService(proxy = MiniConfigProxy.class)
public class MiniConfigProxyImpl extends MiniConfigProxy {
@Override
public MiniInitConfig buildConfig() {
MiniInitConfig.Builder builder = new MiniInitConfig.Builder();
return builder
.configAssetName("tcsas-android-configuration.json")
.deviceUID(ModuleApplet.D_UID)// Set a custom device ID
.build();
}
}
Set user ID
The SDK provides an API that allows the superapp to set the currently logged-in user ID for matching canary release conditions in the console. Example:
/**
* Set account info
*
* @param userId
*/
public static void setUserId(String userId)
TmfMiniSDK.setUserId("xxxxx");

How to start a mini program in single-task mode?

Mini programs run in multi-task mode by default. Developers can specify whether to use single-task mode by setting the MiniStartOptions.isSingleTask parameter when launching the mini program.
public void startMiniApp(String appid) {
// Create mini program launch parameters
MiniStartOptions miniStartOptions = new MiniStartOptions();
// Set the isSingleTask parameter to true to ensure the mini program runs in single-task mode
miniStartOptions.isSingleTask = true;
TmfMiniSDK.startMiniApp(activity, appid, MiniScene.LAUNCH_SCENE_SEARCH, MiniApp.TYPE_ONLINE, miniStartOptions);
}

Common ways to call superapp native pages from within a mini program

Mini programs on Android use a multi-process, multi-task mechanism where the mini program and the superapp run in separate processes, and the mini program’s pages reside in a separate task independent from the superapp. Based on this architecture, launching a native page from a mini program can be achieved through several methods, with specific scenarios and implementations described as follows.
The complete code implementation for the following examples is available in the GitHub demo. Check details in the Components mini program via Interfaces -> Interface -> Page interaction.
Method 1: Launch Activity page within the same mini program task
Take the payment page of the mini program as an example.
Note:
1. When launching an Activity within the same task, obtain the mini program container Activity by calling IMiniAppContext.getAttachedActivity() and use it as the context to launch the target Activity.
Do not use the FLAG_ACTIVITY_NEW_TASK flag on startup, as this forces the creation of a new task, which contradicts the intention of launching within the same task.
2. When launching the Activity, do not use the FLAG_ACTIVITY_NEW_TASK as this forces the creation of a new task, which contradicts the intention of launching within the same task.
Create a custom API named mockPayment. After calling this API from the mini program side, it generates simulated payment data and launches the payment page.
@JsEvent("mockPayment")
public void mockPayment(final RequestEvent req) {
Activity activity = mMiniAppContext.getAttachedActivity();
if (activity.isFinishing()) {
req.fail("app activity already finished");
return;
}
try {
//mock payment default test password 666666
JSONObject mockPayData = mockPayData();
PaymentManager.g().gotoPayPage(activity, mMiniAppContext, mockPayData, (res, data) -> {
QMLog.d("mockPayment", "result: " + data + "; success: " + res);
if (res) {
req.ok(data);
}else {
req.fail("pay failed");
}
});
} catch (JSONException e) {
req.fail("create mock pay data failed");
}
}
The PaymentManager class uses the current mini program's container Activity to launch the payment page within the same task.
public class PaymentManager {
...
//Enter the order payment page
private void gotoPayPage(Activity activity, IMiniAppContext miniAppContext, JSONObject checkRet, AsyncResult result) {
activity.runOnUiThread(() -> {
String fee = checkRet.optString("actualAmount");
double paymentValue = Double.parseDouble(fee) / 10000;
Intent intent = new Intent(activity, PaymentMethodActivity.class);
intent.setAction(Intent.ACTION_VIEW);
intent.putExtra("totalFee", paymentValue);
intent.putExtra("rawData", checkRet.toString());
activity.startActivity(intent);
paymentRequest = new PaymentRequest(miniAppContext, checkRet, result, paymentValue);
Log.e("TAG", "payment request " + this.hashCode());
});
}
}
Method 2: Launch a dialog pop-up from the mini program container Activity
Take a login authorization pop-up as an example.
Note:
The Dialog component runs within the mini program process. Significant attention should be directed towards the cross-process communication issues if data interaction or business collaboration with the superapp is required in the process.
Besides the common Android multi-process communication mechanisms, you can also use the SDK's built-in Multi-Process Interaction mechanism for the communication and collaboration across processes.
Create an authorization DialogFragment
public class LoginDialogFragment extends DialogFragment {
private String mMiniAppName;
private AuthListener mAuthListener;

//Used to set login authorization, listen for callbacks
public void setAuthListener(AuthListener authListener) {
mAuthListener = authListener;
}
//...Initialize page and parameters

@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
btnAgree.setOnClickListener(v -> {
// Handle agree button click
// Complete login and authorization operations, and return the username
if (mAuthListener != null) {
mAuthListener.onAuthCallback(true, "Super app user");
}
dismiss();
});
Button btnRefuse = dialog.findViewById(R.id.btn_refuse);
btnRefuse.setOnClickListener(v -> {
// Handle refuse button click
if (mAuthListener != null) {
mAuthListener.onAuthCallback(false, null);
}
dismiss();
});
return dialog;
}


public interface AuthListener {
void onAuthCallback(boolean isAuth, String userName);
}
}
Create a custom API named mockLogin to parse login parameters and display the dialog
1. Use mMiniAppContext.getAttachedActivity() to get the current mini program container Activity, and call dialog.show() based on this Activity.
2. Set an authorization status listener via loginDialogFragment.setAuthListener(), and notify the mini program side of the final result through a RequestEvent object.

@JsEvent("mockLogin")
public void mockLogin(final RequestEvent req) {
Activity activity = mMiniAppContext.getAttachedActivity();
if (activity.isFinishing()) {
req.fail("app activity already finished");
return;
}
try {
JSONObject jsonObject = new JSONObject(req.jsonParams).optJSONObject("data");
if (jsonObject == null) {
req.fail("ill params");
return;
}
String miniAppName = jsonObject.optString("miniAppName");
LoginDialogFragment loginDialogFragment = LoginDialogFragment.newInstance(miniAppName);
loginDialogFragment.setAuthListener((isAuth, userName) -> {
JSONObject result = new JSONObject();
try {
result.put("isAuth", isAuth);
result.put("userName", userName);
} catch (JSONException e) {
req.fail("auth result illegal params");
}
req.ok(result);
});
loginDialogFragment.show(activity.getFragmentManager(), "login");
} catch (JSONException e) {
req.fail("illegal params");
}
}
Method 3: Launch an Activity page in the superapp task
Some Activities, due to their attribute configurations or specific business scenarios, must be launched and displayed within the superapp task. After the page interaction is completed, you need to actively call backToMiniApp or startMiniApp to return to the mini program page. See the example below for reference.
Create a custom API named mockRunMainAppPage to launch an Activity within the superapp task.
@JsEvent("mockRunMainAppPage")
public void mockRunMainAppPage(final RequestEvent req) {
Activity activity = mMiniAppContext.getAttachedActivity();
if (activity.isFinishing()) {
req.fail("app activity already finished");
return;
}
try {
JSONObject params = new JSONObject(req.jsonParams);
String data = params.optString("data");
SameTaskStackActivity.start(activity, data, mMiniAppInfo.appId, mMiniAppInfo.verType);
} catch (JSONException e) {
req.fail("illegal params");
return;
}
req.ok();
}
Add the FLAG_ACTIVITY_NEW_TASK flag to the Intent to prevent it from launching within the mini program task.
To improve the page transition experience, listen for the Activity back event and call the TmfMiniSDK.backToMiniApp(mMiniAppId, mVerType) to return to the mini program page.
public class SameTaskStackActivity extends BaseActivity {
//...other params info
public static void start(Activity activity, String data, String miniAppId, int verType) {
Intent intent = new Intent(activity, SameTaskStackActivity.class);
intent.putExtra(EXTRA_TITLE, data);
intent.putExtra(EXTRA_MINI_APP_ID, miniAppId);
intent.putExtra(EXTRA_VER_TYPE, verType);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
activity.startActivity(intent);
}

@Override
public void onBackPressed() {
super.onBackPressed();
//Monitor the back event and use the backToMiniApp interface to return to the mini program page
//The miniAppId and verType parameters can be obtained through the MiniAppInfo object in BaseJsPlugin
TmfMiniSDK.backToMiniApp(mMiniAppId, mVerType);
}
}


Cross-process communication example

Since the mini program and the superapp run in different processes, when the mini program needs to communicate with the superapp page, besides the standard Android IPC mechanisms, you can also use the SDK’s built-in IpcPlugin mechanism for communication. For specific examples, refer to Multi-Process Interaction .


Was this page helpful?
You can also Contact Sales or Submit a Ticket for help.
Yes
No

Feedback