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中。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章