开机之后在system server创建AppWidgetService的实例,并调用AppWidgetService的SystemRunning方法,代码位于frameworks/base/services/java/com/android/server/SystemServer.java的initAndLoop方法中,正常启动时safeMode为false

    public void initAndLoop() {        // ...        AppWidgetService appWidget = null;        if (factoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {            // ...            if (!disableNonCoreServices) {                // ...                             try {                    Slog.i(TAG, "AppWidget Service");                    appWidget = new AppWidgetService(context);                    ServiceManager.addService(Context.APPWIDGET_SERVICE, appWidget);                } catch (Throwable e) {                    reportWtf("starting AppWidget Service", e);                }            }        }        // ...        final AppWidgetService appWidgetF = appWidget;        // We now tell the activity manager it is okay to run third party        // code.  It will call back into us once it has gotten to the state        // where third party code can really run (but before it has actually        // started launching the initial applications), for us to complete our        // initialization.        ActivityManagerService.self().systemReady(new Runnable() {            public void run() {                // ...                try {                    if (appWidgetF != null) appWidgetF.systemRunning(safeMode);                } catch (Throwable e) {                    reportWtf("Notifying AppWidgetService running", e);                }            }    }


我们看一下appWidgetF.systemRunning方法

    public void systemRunning(boolean safeMode) {        mSafeMode = safeMode;        mAppWidgetServices.get(0).systemReady(safeMode);        // 注册广播接收器    }
这里主要做了如下动作:

1. 调用AppWidgetServiceImpl的systemReady方法

2. 注册各种广播接收器,包括开机结束,配置改变,应用安装卸载,sdcard应用是否可用,用户移除信息等

接下来重点看AppWidgetServiceImpl.systemReady方法

    public void systemReady(boolean safeMode) {        mSafeMode = safeMode;        synchronized (mAppWidgetIds) {            ensureStateLoadedLocked();        }    }    private void ensureStateLoadedLocked() {        if (!mStateLoaded) {            if (!mHasFeature) {                return;            }            loadAppWidgetListLocked();            loadStateLocked();            mStateLoaded = true;        }    }    void loadAppWidgetListLocked() {        Intent intent = new Intent(AppWidgetManager.ACTION_APPWIDGET_UPDATE);        try {            List broadcastReceivers = mPm.queryIntentReceivers(intent,                    intent.resolveTypeIfNeeded(mContext.getContentResolver()),                    PackageManager.GET_META_DATA, mUserId);            final int N = broadcastReceivers == null ? 0 : broadcastReceivers.size();            for (int i = 0; i < N; i++) {                ResolveInfo ri = broadcastReceivers.get(i);                addProviderLocked(ri);            }        } catch (RemoteException re) {            // Shouldn't happen, local call        }    }    // only call from initialization -- it assumes that the data structures are all empty    void loadStateLocked() {        AtomicFile file = savedStateFile();        try {            FileInputStream stream = file.openRead();            readStateFromFileLocked(stream);            if (stream != null) {                try {                    stream.close();                } catch (IOException e) {                    Slog.w(TAG, "Failed to close state FileInputStream " + e);                }            }        } catch (FileNotFoundException e) {            Slog.w(TAG, "Failed to read state: " + e);        }    }

此处使用变量mStateLoaded来保证只执行一次加载动作。

在loadAppWidgetListLocked方法中,找到所有包含AppWidgetManager.ACTION_APPWIDGET_UPDATE这个action的broadcastReceiver,然后调用addProviderLocked方法逐项解析其中的meta-data,即描述widget的xml文件,并保存在mInstalledProviders中。

在loadStateLocked方法中,解析系统中描述桌面插件状态的xml文件(在android4.4中该文件位于/data/system/users/0/appwidgets.xml ),将信息保存在mHost,mPackagesWithBindWidgetPermission和mAppWidgetIds中。

更多相关文章

  1. Android退出程序的多种方法
  2. Android数据共享 sharedPreferences 的使用方法
  3. Android Studio使用过程中遇到的问题(一)-- "value 2"异常解决方法
  4. 简单总结RectF、Rect 和Matrix ,还有Paint的使用方法
  5. 关于用Android的API重写drawRegion方法的代码
  6. Android实现退出时关闭所有Activity的方法

随机推荐

  1. IDEA同款数据库管理工具,提示太全了,用起来
  2. 花了3天总结的RabbitMQ实用技巧,有点东西!
  3. 在公司做的项目和自己在学校做的有什么区
  4. 线上项目出BUG没法调试?推荐这款阿里开源
  5. 拿到一台新的Windows电脑,我会做什么?
  6. 听说你的JWT库用起来特别扭,推荐这款贼好
  7. RabbitMQ实现延迟消息居然如此简单,整个插
  8. TCP/IP四次挥手
  9. 你居然还去服务器上捞日志,搭个日志收集系
  10. Android(安卓)UI自动化测试最佳实践