Search code examples
androidsystem-services

System services not available to Activities before onCreate(), but no properties instantiated


I am trying to create a service which checks if the device has an active internet connection and reports it. I have absolutely no clue what's wrong with my code.

I know this question has been asked many times, but most answers, like this, state

  • that one cannot create an activity using the new keyword (see this post);
  • that properties which are instantiated also are the cause of the problem (see this post).

Now as far as I know, I avoided forementioned causes. This is my simplified code:

  • MyActivity

    public MyActivity extends SuperActivity {
    
        // No properties are instantiated
        // No onCreate(Bundle) method
    
    }
    
  • SuperActivity

    public SuperActivity extends Activity {
    
        ApplicationManager appMgr;
        UIManager uiMgr;
        // No properties are instantiated, only declared
    
        @Override
        public void onCreate(Bundle savedInstance) {
            super.onCreate(savedInstance);
    
            this.appMgr = new ApplicationManager(this);
            this.appMgr.getUIManager().init();
        }
    }
    
  • ApplicationManager

    public ApplicationManager {
    
        // No properties are instantiated
        SuperActivity activity;
        Thread serviceThread;
        UIManager uiMgr;
    
        ApplicationManager(SuperActivity activity) {
            this.activity = activity;
            this.uiMgr = new UIManager(this);
        }
    
        void initService() {
            this.serviceThread = new Thread(new Runnable() {
    
                @Override
                public void run() {
                    Intent intent = new Intent(getActivity(), ConnectionService.class);
                    intent.putExtra("CONTEXT", getActivity());
                    intent.putExtra("ALLOW_MOBILE_CONNECTION", true);
                    getActivity().startService(intent);
                }
            });
        }
    
        void startService() {
            this.serviceThread.start();
        }
    
        UIManager getUIManager() {
            return this.uiMgr;
        }
    
        SuperActivity getActivity() {
            return this.activity;
        }
    }
    
  • UIManager

    public class UIManager {
    
        // No properties are instantiated
    
        void init() {
            getApplicationManager().initService();
            getApplicationManager().startService(); // <-- FIRST MARKER,
                                                    //     see below
        }
    
    }
    
  • ConnectionService

    public class ConnectionService {
    
        @Override
        protected Bundle onHandleIntent(Intent intent) {
            Bundle params = intent.getExtras();
            Bundle bundle = new Bundle();
            Context cntxt = (Context) params.getSerializable("CONTEXT");
            try {
                boolean wifi =
                    NetworkUtils.hasWifiCon(cntxt); // <-- SECOND MARKER,
                                                    //     see below
    
                ...
            }
            catch (SocketException exc) { ... }
            return bundle;
        }
    }
    

The error occurs on the line denoted by SECOND MARKER, which gets the system connection service and checks for wifi. This is the service which is not allowed to be called before onCreate().

Furthermore, if I remove or comment the line denoted by FIRST MARKER, the error is gone, but also, of course, the service is not started.

What could be the problem?


Solution

  • You cannot pass around a Context by serializing it in a bundle.

    In an IntentService which I assume your ConnectionService is, just use this for a valid Context.