ServiceMonitor

来源:互联网 发布:fisher调节阀计算软件 编辑:程序博客网 时间:2024/05/19 01:10
我们先看ServiceMonitor的构造函数。就是保存几个变量
161    public ServiceMonitor(String ownerTag, boolean debug,
162            Context context, String settingKey, Callbacks callbacks) {
163        mTag = ownerTag + ".ServiceMonitor";
164        mDebug = debug;
165        mContext = context;
166        mSettingKey = settingKey;
167        mCallbacks = callbacks;
168    }


然后再看start函数
170    public void start() {
171        // listen for setting changes
172        ContentResolver cr = mContext.getContentResolver();
173        cr.registerContentObserver(Settings.Secure.getUriFor(mSettingKey),
174                false /*notifyForDescendents*/, mSettingObserver, UserHandle.USER_ALL);
175
176        // listen for package/component changes
177        IntentFilter filter = new IntentFilter();
178        filter.addAction(Intent.ACTION_PACKAGE_ADDED);
179        filter.addAction(Intent.ACTION_PACKAGE_CHANGED);
180        filter.addAction(Intent.ACTION_PACKAGE_REMOVED);
181        filter.addDataScheme("package");
182        mContext.registerReceiver(mBroadcastReceiver, filter);
183
184        mHandler.sendEmptyMessage(MSG_START_SERVICE);
185    }


这个函数首先注册一个ContentObserver,来检测构造函数中赋值的mSettingKey,如果有改动这个函数,就调用mSettingObserver
一旦调用到mSettingKey的改动就调用mSettingObserver的onChange函数,开始发送MSG_START_SERVICE event。
94    private final ContentObserver mSettingObserver = new ContentObserver(mHandler) {
95        public void onChange(boolean selfChange) {
96            onChange(selfChange, null);
97        }
98
99        public void onChange(boolean selfChange, Uri uri) {
100            if (mDebug) Log.d(mTag, "onChange selfChange=" + selfChange + " uri=" + uri);
101            ComponentName cn = getComponentNameFromSetting();
102            if (cn == null && mServiceName == null || cn != null && cn.equals(mServiceName)) {
103                if (mDebug) Log.d(mTag, "skipping no-op restart");
104                return;
105            }
106            if (mBound) {
107                mHandler.sendEmptyMessage(MSG_STOP_SERVICE);
108            }
109            mHandler.sendEmptyMessageDelayed(MSG_START_SERVICE, WAIT_FOR_STOP);
110        }
111    };
在start函数中还注册了IntentFilter 来侦测package的add,changed,remove函数,其回调函数是mBroadcastReceiver
141    private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
142        public void onReceive(Context context, Intent intent) {
143            String pkg = intent.getData().getSchemeSpecificPart();
144            if (mServiceName != null && mServiceName.getPackageName().equals(pkg)) {
145                mHandler.sendMessage(mHandler.obtainMessage(MSG_PACKAGE_INTENT, intent));
146            }
147        }
148    };
如果检测到上述三个动作,则发送MSG_PACKAGE_INTENT event
在start 函数的最后发送MSG_START_SERVICE event。在MSG_START_SERVICE 又发送MSG_CONTINUE_START_SERVICE命令来启动service
237    private void continueStartService() {
238        if (mDebug) Log.d(mTag, "continueStartService");
239        Intent intent = new Intent().setComponent(mServiceName);
240        try {
241            mServiceConnection = new SC();
242            mBound = mContext.bindService(intent, mServiceConnection, Context.BIND_AUTO_CREATE);
243            if (mDebug) Log.d(mTag, "mBound: " + mBound);
244        } catch (Throwable t) {
245            Log.w(mTag, "Error binding to service: " + mServiceName, t);
246        }
247        if (!mBound) {
248            mCallbacks.onNoService();
249        }
250    }


最终在239行设定精确的service 名字的Intent,调用242上的bindService来启动service,这个service的名字是什么呢?
225    private void startService() {
226        mServiceName = getComponentNameFromSetting();
227        if (mDebug) Log.d(mTag, "startService mServiceName=" + mServiceName);
228        if (mServiceName == null) {
229            mBound = false;
230            mCallbacks.onNoService();
231        } else {
232            long delay = mCallbacks.onServiceStartAttempt();
233            mHandler.sendEmptyMessageDelayed(MSG_CONTINUE_START_SERVICE, delay);
234        }
235    }
原来是在startService 中通过getComponentNameFromSetting 得到要启动service的名字
187    private ComponentName getComponentNameFromSetting() {
188        String cn = Settings.Secure.getStringForUser(mContext.getContentResolver(),
189                mSettingKey, UserHandle.USER_CURRENT);
190        return cn == null ? null : ComponentName.unflattenFromString(cn);
191    }
可见名字是由mSettingKey得到的。也就是说调用ServiceMonitor的类,告诉其名字,让其帮忙启动这个service.当这个service所在package add/changed/remove 的时候,会在mBroadcastReceiver 中发出MSG_PACKAGE_INTENT event,我们在开看看这个event的处理函数
195    private void packageIntent(Intent intent) {
196        if (mDebug) Log.d(mTag, "packageIntent intent=" + intent
197                + " extras=" + bundleToString(intent.getExtras()));
198        if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
199            mHandler.sendEmptyMessage(MSG_START_SERVICE);
200        } else if (Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
201                || Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())) {
202            final PackageManager pm = mContext.getPackageManager();
203            final boolean serviceEnabled = isPackageAvailable()
204                    && pm.getApplicationEnabledSetting(mServiceName.getPackageName())
205                            != PackageManager.COMPONENT_ENABLED_STATE_DISABLED
206                    && pm.getComponentEnabledSetting(mServiceName)
207                            != PackageManager.COMPONENT_ENABLED_STATE_DISABLED;
208            if (mBound && !serviceEnabled) {
209                stopService();
210                scheduleCheckBound();
211            } else if (!mBound && serviceEnabled) {
212                startService();
213            }
214        }
215    }


前面做一些判断后,会在209行stop service 或者 在212行startService.


总的来说,就是告诉ServiceMonitor 类要启动的service的名字,ServiceMonitor会自动管理service的启动和停止,已经这个service所在包变化时,这个service的状态.

0 0