【问题标题】:Android studio updated and code too large nowAndroid Studio 更新了,现在代码太大了
【发布时间】: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);

        }

【问题讨论】:

    标签: java android firebase android-studio firebase-cloud-messaging


    【解决方案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);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-09-21
      • 2016-04-04
      • 1970-01-01
      • 2023-03-31
      • 1970-01-01
      • 2011-10-17
      相关资源
      最近更新 更多