Android 工作室已更新,现在代码太大
Android studio updated and code too large now
我有一个系统已经生产了2年了。它是一个用于控制公司设备的 EMM 系统。
它使用 FireBase
将在设备上执行的功能从服务器应用程序发送到设备。
您可以向设备发送大约 400 条可能的命令,所有这些命令最初都在一个 class 中处理,它覆盖了 FireBaseMessagingService
[=53] 中的 onMessageReceived()
=].
Android studio 的旧版本构建了现在正在生产中的 apk。大约一年后,我开始使用我的系统的第 2 版。所以我将我的 Android 工作室更新到最新 (4)。
问题:
当我尝试构建项目并推送到设备上时,我得到
error: code too large public void onMessageReceived(RemoteMessage remoteMessage) {
如前所述,此onMessageReceived
方法可以处理来自服务器应用程序的400种不同类型的推送通知,因此方法主体中有很多if/else语句。
有什么原因导致 AS 升级后这不起作用?
我可以在 AS 中更改任何设置来克服这个问题吗?
我尝试过的:
我考虑过将if/else的一半放在另一个服务class中,以减少方法代码。这将涉及将 remoteMessageMap
传递给另一个 class 以继续进行 if/else 处理。
remoteMessageMap
来自 FireBase 的是一个 Map,而 Map 是不可序列化的,因为它们扩展了接口,所以不能传递它。
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");
谢谢
[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);
}
无需将 remoteMessageMap
传递给另一个 class。问题的根源是 java 方法大小的限制。这是与此问题相关的 official documentation of oracle 的一部分:
code_length
The value of the code_length item gives the number of bytes in the code array for this method.
The value of code_length must be greater than zero (as the code array must not be empty) and less than 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
}
这样可以优化方法大小,调用性能也会大大提高。
您似乎重复了很多次相同的代码行,只需将这些代码行和可能更多的代码放在每个 else if
上调用的单独方法中,这将减少onMessageReceived()
的大小
Intent intentExecutePushCommand = new Intent( getApplicationContext(), ExecutePushCommandIntentService.class);
intentExecutePushCommand.putExtra("compID", MenuActivity.companyID);
intentExecutePushCommand.putExtra("command", message);
intentExecutePushCommand.putExtra("pushguid", pushGuid);
我有一个系统已经生产了2年了。它是一个用于控制公司设备的 EMM 系统。
它使用 FireBase
将在设备上执行的功能从服务器应用程序发送到设备。
您可以向设备发送大约 400 条可能的命令,所有这些命令最初都在一个 class 中处理,它覆盖了 FireBaseMessagingService
[=53] 中的 onMessageReceived()
=].
Android studio 的旧版本构建了现在正在生产中的 apk。大约一年后,我开始使用我的系统的第 2 版。所以我将我的 Android 工作室更新到最新 (4)。
问题:
当我尝试构建项目并推送到设备上时,我得到
error: code too large public void onMessageReceived(RemoteMessage remoteMessage) {
如前所述,此onMessageReceived
方法可以处理来自服务器应用程序的400种不同类型的推送通知,因此方法主体中有很多if/else语句。
有什么原因导致 AS 升级后这不起作用?
我可以在 AS 中更改任何设置来克服这个问题吗?
我尝试过的:
我考虑过将if/else的一半放在另一个服务class中,以减少方法代码。这将涉及将 remoteMessageMap
传递给另一个 class 以继续进行 if/else 处理。
remoteMessageMap
来自 FireBase 的是一个 Map,而 Map 是不可序列化的,因为它们扩展了接口,所以不能传递它。
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");
谢谢
[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);
}
无需将 remoteMessageMap
传递给另一个 class。问题的根源是 java 方法大小的限制。这是与此问题相关的 official documentation of oracle 的一部分:
code_length
The value of the code_length item gives the number of bytes in the code array for this method.
The value of code_length must be greater than zero (as the code array must not be empty) and less than 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
}
这样可以优化方法大小,调用性能也会大大提高。
您似乎重复了很多次相同的代码行,只需将这些代码行和可能更多的代码放在每个 else if
上调用的单独方法中,这将减少onMessageReceived()
Intent intentExecutePushCommand = new Intent( getApplicationContext(), ExecutePushCommandIntentService.class);
intentExecutePushCommand.putExtra("compID", MenuActivity.companyID);
intentExecutePushCommand.putExtra("command", message);
intentExecutePushCommand.putExtra("pushguid", pushGuid);