I have a system that has been produced for 2 years now. It is an EMM system for controlling corporate devices.
It uses FireBase
to send the functionality executed on the device from the server app to the device.
There are around 400 possible commands you can send to a device and all these commands are handled in one class initially, which overrides the onMessageReceived()
from the FireBaseMessagingService
class.
The older version of Android studio built the apk which is now in production. I have started to work on version 2 of my system after about a year off. so I updated my Android studio to the latest (4).
The Problem:
when I try to build the project and push onto a device, I get
error: code too large public void onMessageReceived(RemoteMessage remoteMessage) {
As stated before this onMessageReceived
method can handle 400 different types of push notifications from the server app, so there are a lot of if/else statements in the method body.
Is there any reason why since the AS upgrade this will not work?
is there any setting I can change in AS to get past this?
What I have tried:
I thought about putting half of the if/else in another service class, to cut down on the method code. This would involve passing the remoteMessageMap
to another class to carry on with the if/else processing.
remoteMessageMap
from FireBase is a Map and Maps are not serializable as they extend the interface, so can't pass it.
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);
}
There is no need to pass the remoteMessageMap
to another class. The source of the problem is the limitation in the java method size. Here is a piece of the official documentation of oracle which is related to this problem:
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.
The point is that your onMessageReceived
method is too long, which is bigger than 64KB of compiled code. It is weird why it was compiled fine in previous versions of Android Studio :)
Anyway, the solution is to break the method into smaller fragments. My suggestion is fragmentation by some message types. For example:
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
}
In this way, the method size would be optimized and the performance of calling it will be far improved.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With