Bind to service from new Context for configuration changes or bind from app context?

前端 未结 4 1810
囚心锁ツ
囚心锁ツ 2021-02-02 02:38

I\'m trying to work out if bound service is appropriate for doing background work in my app. The requirements are that various application components can make web requests throu

4条回答
  •  执笔经年
    2021-02-02 02:47

    I had a similar problem, where I have a Bound Service used in an Activity. Inside the activity I define a ServiceConnection, mConnection, and inside onServiceConnected I set a class field, syncService that's a reference to the Service:

    private SynchronizerService syncService;
    
    (...)
    
    /** Defines callbacks for service binding, passed to bindService() */
    private ServiceConnection mConnection = new ServiceConnection() {
    
        @Override
        public void onServiceConnected(ComponentName className, IBinder service) {
            // We've bound to LocalService, cast the IBinder and get
            // LocalService instance
            Log.d(debugTag, "on Service Connected");
            LocalBinder binder = (LocalBinder) service;
            //HERE
            syncService = binder.getService();
            //HERE
            mBound = true;
            onPostConnect();
        }
    
        @Override
        public void onServiceDisconnected(ComponentName arg0) {
            Log.d(debugTag, "on Service Disconnected");
            syncService = null;
            mBound = false;
        }
    };
    

    Using this method, whenever the orientation changed I would get a NullPointerException when referencing the syncService variable, despite the fact the service was running, and I tried several methods that never worked.

    I was about to implement the solution proposed by Sam, using a retained fragment to keep the variable, but first remembered to try a simple thing: setting the syncService variable to static.. and the connection reference is maintained when the orientation changes!

    So now I have

    private static SynchronizerService syncService = null;
    
    ...
    
    /** Defines callbacks for service binding, passed to bindService() */
    private ServiceConnection mConnection = new ServiceConnection() {
    
        @Override
        public void onServiceConnected(ComponentName className, IBinder service) {
            // We've bound to LocalService, cast the IBinder and get
            // LocalService instance
            Log.d(debugTag, "on Service Connected");
            LocalBinder binder = (LocalBinder) service;
            //HERE
            if(syncService == null) {
                Log.d(debugTag, "Initializing service connection");
                syncService = binder.getService();
            }
            //HERE
            mBound = true;
            onPostConnect();
        }
    
        @Override
        public void onServiceDisconnected(ComponentName arg0) {
            Log.d(debugTag, "on Service Disconnected");
            syncService = null;
            mBound = false;
        }
    };
    

提交回复
热议问题