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

5

我有一个已经生产了2年的系统,是一个用于控制公司设备的EMM系统。

该系统使用FireBase将从服务器应用程序发送到设备上执行的功能。

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

旧版本的Android Studio构建了目前正在生产中的apk。 我在休息了一年后开始着手开发第2版系统。 因此,我将我的Android Studio更新为最新版本(4)。

问题:

当我尝试构建项目并将其推送到设备时,我遇到了以下问题:

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

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

是否存在某种原因导致自从 AS 升级以来这将不再起作用?

有没有设置我可以在 AS 中更改以解决这个问题?

我尝试过:

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

FireBaseremoteMessageMap 是一个 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");

thanks

[edit1]

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);

        }
2个回答

5
不需要将remoteMessageMap传递给另一个类。问题的根源在于java方法大小的限制。以下是与此问题相关的oracle官方文档的一部分:

code_length
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
}

通过这种方式,方法的大小将被优化,调用性能将会得到显著提高。


1
嗨,感谢您的回答。好的,推送通知中的消息是关键。系统可以接收大约400种不同类型的推送通知。这些推送通知有一个关键字,有时还有其他参数。我可以在消息上进行切换。例如,所有与应用程序上的缓存交互的功能都将以CLEARCACHE开头,因此我可以拦截通知,提取消息并检查它是否以CLEARCACHE开头。如果是,则触发第二个处理仅处理CLEARCACHE内容的方法。示例见编辑1。 - turtleboy
1
编辑1是原始代码,所以我可以将所有与清除缓存有关的if / else放入第二个方法中。然后在原始代码中检查消息是否以"CLEARCACHE"开头 - 然后调用第二个方法? - turtleboy
不客气,伙计 :) 是的,按照你说的处理操作分支的两个级别可能是一个好主意。因此,您可以将所有共同的代码行放入“handleClearCache”方法中,然后调用与特定CLEARCACHE命令相关的另一个方法。因此,在这种情况下,您可以创建意图并将“compID”,“command”和“pushguid” extras放入“handleClearCache”方法(在常见操作中),然后将此意图加上“remoteMessageMap”传递给第二级方法以进一步添加extras(如果需要)并调用“startService”。 - aminography
创建一个通用代码的方法,如下所示,并使用参数调用它 Intent intentExecutePushCommand = new Intent(getApplicationContext(), ExecutePushCommandIntentService.class); intentExecutePushCommand.putExtra("compID", MenuActivity.companyID); intentExecutePushCommand.putExtra("command", message); intentExecutePushCommand.putExtra("pushguid", pushGuid);startService(intentExecutePushCommand); - Arul

0

看起来你在重复很多次相同的代码行,只需将这些代码行和可能还有几行代码放入一个单独的方法中,在每个else if中调用该方法,这将减小onMessageReceived()的大小。

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接