android appwidget service的初始化

开机之后在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<ResolveInfo> 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中。

猜你喜欢

转载自blog.csdn.net/w_xue/article/details/39208833
今日推荐