1

My main activity uses the handy WakefulIntentService by CommonsWare to schedule an alarm that polls my server for changes in data. When the alarm fires, I call a service:

Intent backgroundIntent = new Intent(context, PollService.class);
WakefulIntentService.sendWakefulWork(context, backgroundIntent);

The service reads a piece of server data, 'token' and compares it with an 'oldToken' value stored in preferences. If the tokens do not match, I send a notification with a pending intent to start an activity.

SharedPreferences settings = getSharedPreferences(PREFS_NAME, 0);
String oldToken = settings.getString("oldToken", "empty");
Log.d(TAG, "Old token: " + oldToken);
if (!token.equals(oldToken)){
    ...

This works fine for a while, but after a random number of hours, 'oldToken' starts returning 'empty' as if the service can no longer access shared preferences.

Then I noticed this shows up in logcat:

03-12 08:32:51.325     506-7595/? W/BroadcastQueue﹕ Unable to launch app com.xxx.xxx/10086 for broadcast Intent { flg=0x14 cmp=com.xxx.xxx/com.commonsware.cwac.wakeful.AlarmReceiver (has extras) }: process is bad

I've been trying to think if these two events are related. They do seem to occur at the same time.

Why am I getting the "process is bad" error? Why does my service lose my connection to shared preferences?

Thanks for your consideration.

Josh Janvrin
  • 323
  • 3
  • 9
  • 1
    Seems like you're not the only one, http://stackoverflow.com/questions/3253676/how-to-fix-process-is-bad-error-for-an-android-widget, http://stackoverflow.com/questions/26452317/prevent-android-process-is-bad-error Unfortunately there doesn't seem to be any explanation or solution, just unsatisfying workarounds, maybe post some more details of what you're doing (like code). – ci_ Mar 12 '15 at 22:24
  • @ci_ Thanks, I had checked those questions out. I'm drilling down into logcat to see if I can find anything else fishy that happens around the time the 'process is bad' message fires. – Josh Janvrin Mar 15 '15 at 11:14
  • Did you ever figure this out? – Luka Bradeško Nov 27 '15 at 12:09
  • No, I moved away from alarms and went to GCM. Seemed like a better practice. Sorry I couldn't be more help. – Josh Janvrin Nov 28 '15 at 22:36

2 Answers2

0

Your service must be crashing everytime it restarts (bad persistent data?). When this happens too often, the service is "force stopped" by the OS, thus pushing it to bad state. Even if you use GCM/FCM instead of alarms, you will end up here as once the process turns bad, it will not be able to receive broadcasts of your FCM/GCM from Google Play Services. The only way to get out of this is to uninstall app -> shut down-> remove and put back battery-> restart-> install app.

Logcat will show a log like below, indicating the cancelled broadcast:

12-06 18:37:31.802 3566-3566/? W/GCM-DMM: broadcast intent callback: result=CANCELLED forIntent { act=com.google.android.c2dm.intent.RECEIVE pkg=your_pkg_name (has extras) }

Also note that, when your app crashes, the crash dialog stays for 5 mins; in those 5 mins, neither your app will receive any FCM messages, nor any other external broadcasts(e.g. registered broadcast in manifest for ACTION_POWER_CONNECTED etc). Once those 5 mins are elapsed and dialog disappeared, then your app will function normally.

A classic case would be of an app in which there is an exception in onCreate() itself.This one would become a prime candidate for bad process. App will not get auto-updated through playstore when in bad state; however it could be updated manually by going to playstore.App will not get auto-updated through playstore when in bad state; however it could be updated manually by going to playstore or by rebooting the phone. Note: Atleast my experience with Nexus 5x has been that we need not remove the battery to get the app out of the bad state; reboot is enough.

Uncaught Exception
  • 2,149
  • 18
  • 25
0

I had this process is bad error, and I had to keep my FCM Service exported. add:

android:exported="true"

or remove exported altogether.

My services now looks like this:

    <service
        android:name=".service.MyFirebaseMessagingService"
        android:exported="true"
        >
        <intent-filter>
            <action android:name="com.google.firebase.MESSAGING_EVENT" />
        </intent-filter>
    </service>
    <service
        android:name=".service.MyFirebaseInstanceIdService"
        android:exported="true"
        >
        <intent-filter>
            <action android:name="com.google.firebase.INSTANCE_ID_EVENT" />
        </intent-filter>
    </service>
ViliusK
  • 11,345
  • 4
  • 67
  • 71