Android Studio 更新了,现在代码太大了

Posted

技术标签:

【中文标题】Android Studio 更新了,现在代码太大了【英文标题】:Android studio updated and code too large now 【发布时间】:2021-03-10 07:52:22 【问题描述】:

我的系统已经生产了 2 年。它是一个用于控制企业设备的 EMM 系统。

它使用FireBase 将设备上执行的功能从服务器应用发送到设备。

您可以向设备发送大约 400 条可能的命令,所有这些命令最初都在一个类中处理,该类会覆盖 FireBaseMessagingService 类中的 onMessageReceived()

旧版本的 android Studio 构建了该 apk,现已投入生产。大约一年后,我开始使用我的系统的第 2 版。所以我将我的 Android 工作室更新到了最新的 (4)。

问题:

当我尝试构建项目并推送到设备时,我得到了

error: code too large public void onMessageReceived(RemoteMessage remoteMessage) 

如前所述,onMessageReceived 方法可以处理来自服务器应用程序的 400 种不同类型的推送通知,因此方法体中有很多 if/else 语句。

有什么原因导致AS升级后这不起作用?

我可以在 AS 中更改任何设置来解决这个问题吗?

我尝试过的:

我考虑将一半的 if/else 放在另一个服务类中,以减少方法代码。这将涉及将remoteMessageMap 传递给另一个类以继续进行 if/else 处理。

来自 FireBase 的remoteMessageMap 是一个 Map,而 Maps 扩展接口时不可序列化,因此无法传递它。

public class MyAndroidFirebaseMsgService extends FirebaseMessagingService 

    private static final String TAG = "MyAndroidFCMService";
    AppObj appObj;


    @Override
    public void onMessageReceived(RemoteMessage remoteMessage) 


        Log.e(TAG, "remoteMessage.getData() = " + remoteMessage.getData());

        Map remoteMessageMap = remoteMessage.getData();

        String message = (String)remoteMessageMap.get("message");

谢谢

[编辑1]

else if(message.trim().equalsIgnoreCase("CLEARCACHE_REMOVE_APP_WL"))


            Log.e(TAG, "received CLEARCACHE_REMOVE_APP_WL");

            String pushGuid =  (String)remoteMessageMap.get("pushguid");
            Log.e(TAG, "pushGuid = " + pushGuid);

            String clearCacheRemoveWhitelist =  (String)remoteMessageMap.get("clear_cache_app_names");


            Intent intentExecutePushCommand = new Intent( getApplicationContext(), ExecutePushCommandIntentService.class);
            intentExecutePushCommand.putExtra("compID", MenuActivity.companyID);
            intentExecutePushCommand.putExtra("command", message);
            intentExecutePushCommand.putExtra("pushguid", pushGuid);
            intentExecutePushCommand.putExtra("clear_cache_app_names", clearCacheRemoveWhitelist);



            startService(intentExecutePushCommand);

        else if(message.trim().equalsIgnoreCase("CLEARCACHE_GET_PACKAGENAMES_WL"))


            Log.e(TAG, "received CLEARCACHE_GET_PACKAGENAMES_WL");

            String pushGuid =  (String)remoteMessageMap.get("pushguid");
            Log.e(TAG, "pushGuid = " + pushGuid);


            Intent intentExecutePushCommand = new Intent( getApplicationContext(), ExecutePushCommandIntentService.class);
            intentExecutePushCommand.putExtra("compID", MenuActivity.companyID);
            intentExecutePushCommand.putExtra("command", message);
            intentExecutePushCommand.putExtra("pushguid", pushGuid);

            startService(intentExecutePushCommand);

        else if(message.trim().equalsIgnoreCase("CLEARCACHE_ADD_PACKAGENAME_WL"))


            Log.e(TAG, "received CLEARCACHE_ADD_PACKAGENAME_WL");

            String pushGuid =  (String)remoteMessageMap.get("pushguid");
            Log.e(TAG, "pushGuid = " + pushGuid);

            String packageName =  (String)remoteMessageMap.get("package_name");


            Intent intentExecutePushCommand = new Intent( getApplicationContext(), ExecutePushCommandIntentService.class);
            intentExecutePushCommand.putExtra("compID", MenuActivity.companyID);
            intentExecutePushCommand.putExtra("command", message);
            intentExecutePushCommand.putExtra("pushguid", pushGuid);
            intentExecutePushCommand.putExtra("package_name", packageName);

            startService(intentExecutePushCommand);

        

【问题讨论】:

【参考方案1】:

无需将remoteMessageMap 传递给另一个类。问题的根源在于 java 方法大小的限制。这是与此问题相关的official documentation of oracle 的一部分:

代码长度 code_length 项的值给出了此方法的代码数组中的字节数。 code_length 的值必须大于零(因为代码数组不能为空)且小于 65536。

关键是你的onMessageReceived 方法太长了,大于64KB 的编译代码。奇怪的是为什么它在以前版本的 Android Studio 中编译得很好:)

无论如何,解决方案是将方法分解成更小的片段。我的建议是某些消息类型的碎片化。例如:

private static final String COMMAND_1 = "COMMAND_1";
private static final String COMMAND_2 = "COMMAND_2";

@Override
public void onMessageReceived(RemoteMessage remoteMessage) 
    Log.e(TAG, "remoteMessage.getData() = " + remoteMessage.getData());

    Map remoteMessageMap = remoteMessage.getData();

    String message = (String) remoteMessageMap.get("message");
    
    String type = extrated_from_received_message;

    switch (type) 
        case COMMAND_1:
            handleCommand1(remoteMessageMap);
            break;
        case COMMAND_2:
            handleCommand2(remoteMessageMap);
            break;

        // more commands ...

        default:
            // ...
    


private void handleCommand1(Map remoteMessageMap)
    // do whatever related to command 1


private void handleCommand2(Map remoteMessageMap)
    // do whatever related to command 2

这样可以优化方法大小,大大提高调用性能。

【讨论】:

您好,感谢您的回答。好的,来自推送通知的消息是关键。该系统可以接收大约 400 种不同类型的推送通知。这些推送通知有一个键,有时还有附加参数。我可以打开消息。例如,与手机上的缓存交互的所有功能都以 CLEARCACHE 开头,因此我可以拦截通知,提取消息并检查它是否以 CLEARCACHE 开头。如果是,则触发仅处理 CLEARCACHE 内容的第二种方法。编辑示例 1 edit 1 是原始代码,因此我可以将所有与 clearcache 相关的 if /else 放入第二种方法中。然后在原始代码中检查消息是否以“CLEARCACHE”-开头。那么第二种方法呢? 不客气,伙计 :) 是的,正如您所说,在两个级别上处理操作分支可能是个好主意。因此,您可以将所有共同的代码行放入handleClearCache 方法中,然后调用与特定CLEARCACHE 命令相关的另一个方法。所以在这种情况下,您可以创建意图并将compIDcommandpushguid extras 放在handleClearCache 方法中(在常用操作中),并将此意图加上remoteMessageMap 传递给二级方法添加更多额外内容(如果需要)并致电startService 为下面的通用代码创建一个方法,并使用参数 Intent intentExecutePushCommand = new Intent( getApplicationContext(), ExecutePushCommandIntentService.class); 调用它intentExecutePushCommand.putExtra("compID", MenuActivity.companyID); intentExecutePushCommand.putExtra("command", message); intentExecutePushCommand.putExtra("pushguid", pushGuid); startService(intentExecutePushCommand);【参考方案2】:

您似乎多次重复相同的代码行,只需将这些代码行以及更多代码行放在一个单独的方法中,该方法在每个 else if 上调用,这将减少 @ 的大小987654322@

   Intent intentExecutePushCommand = new Intent( getApplicationContext(), ExecutePushCommandIntentService.class);
   intentExecutePushCommand.putExtra("compID", MenuActivity.companyID);
   intentExecutePushCommand.putExtra("command", message);
   intentExecutePushCommand.putExtra("pushguid", pushGuid);

【讨论】:

以上是关于Android Studio 更新了,现在代码太大了的主要内容,如果未能解决你的问题,请参考以下文章

如何更新Android Studio

如何在 android studio 中更新 gradle?

android studio怎么更新android-ndk

带有 Flutter 更新的 Android Studio 导致了索引循环

将 Android Studio 和 SDK 更新到 22。现在,当尝试打开地图片段时,它会崩溃

Android Studio 更新 0.5.3 - 找不到平台“android-19”