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 命令相关的另一个方法。所以在这种情况下,您可以创建意图并将compID
、command
和pushguid
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 中更新 gradle?
带有 Flutter 更新的 Android Studio 导致了索引循环