ThemeChooser---debug(5.1)

来源:互联网 发布:sra数据上传 编辑:程序博客网 时间:2024/06/06 19:07
  private ThemeManager mService;    mService = (ThemeManager) getActivity().getSystemService(Context.THEME_SERVICE);
得到ThemeManager类, 该类里包含了服务接口IThemeService;

ThemeManager类: /frameworks/base/core/java/android/content/res/ThemeManager.java

   public ThemeManager(Context context, IThemeService service) {        mContext = context;          mService = service; //private IThemeService mService;        mHandler = new Handler(Looper.getMainLooper());    }

前面我们得到了mService(ThemeManager), 这里mService调用requestThemeChange方法。

    ThemeChangeRequest request = getThemeChangeRequestForSelectedComponents();    mService.requestThemeChange(request, true);

我们先来看下ThemeChangeRequest类: /frameworks/base/core/java/android/content/res/ThemeChangeRequest.java

    public final class ThemeChangeRequest implements Parcelable {        private final Map<String, String> mThemeComponents = new HashMap<String, String>();//保存组件信息      private final Map<String, String> mPerAppOverlays = new HashMap<String, String>();        .        .        .    }
我们可以看到该类实现了Parcelable接口, ThemeChangeRequest作为传输对象

现在我们来看下ThemeManager: /frameworks/base/core/java/android/content/res/ThemeManager.java

    public class ThemeManager {        .        .        .        private IThemeService mService;        public void requestThemeChange(ThemeChangeRequest request, boolean removePerAppThemes) {            try {                mService.requestThemeChange(request, removePerAppThemes);            } catch (RemoteException e) {                logThemeServiceException(e);            }        }        .        .        .    }

我们可以看到该方法里实际是调用了IThemeService接口的requestThemeChange方法, 现在我们来看下该接口

IThemeService接口: 该接口是用aidl实现的,让我们来看下该aidl文件: IThemeService.aidl : /frameworks/base/core/java/android/content/res/IThemeService.aidl

 interface IThemeService {        void requestThemeChangeUpdates(in IThemeChangeListener listener);        void removeUpdates(in IThemeChangeListener listener);        void requestThemeChange(in ThemeChangeRequest request, boolean removePerAppThemes);        void applyDefaultTheme();        boolean isThemeApplying();        int getProgress();        boolean cacheComposedIcon(in Bitmap icon, String path);        boolean processThemeResources(String themePkgName);        boolean isThemeBeingProcessed(String themePkgName);        void registerThemeProcessingListener(in IThemeProcessingListener listener);        void unregisterThemeProcessingListener(in IThemeProcessingListener listener);        void rebuildResourceCache();    }

我们再来看下实现了该接口的ThemeService类: /frameworks/base/services/core/java/com/android/server/ThemeService.java

 public class ThemeService extends IThemeService.Stub {        .        .        .        @Override        public void requestThemeChange(ThemeChangeRequest request, boolean removePerAppThemes)                throws RemoteException {            mContext.enforceCallingOrSelfPermission(                    Manifest.permission.ACCESS_THEME_MANAGER, null); //获得权限            Message msg;            /**             * Since the ThemeService handles compiling theme resource we need to make sure that any             * of the components we are trying to apply are either already processed or put to the             * front of the queue and handled before the theme change takes place.             *             * TODO: create a callback that can be sent to any ThemeChangeListeners to notify them that             * the theme will be applied once the processing is done.             */            synchronized (mThemesToProcessQueue) {                Map<String, String> componentMap = request.getThemeComponentsMap();                for (Object key : componentMap.keySet()) {                    if (ThemesColumns.MODIFIES_OVERLAYS.equals(key) ||                            ThemesColumns.MODIFIES_NAVIGATION_BAR.equals(key) ||                            ThemesColumns.MODIFIES_STATUS_BAR.equals(key) ||                            ThemesColumns.MODIFIES_ICONS.equals(key)) {                        String pkgName = (String) componentMap.get(key);                        if (mThemesToProcessQueue.indexOf(pkgName) > 0) {                            mThemesToProcessQueue.remove(pkgName);                            mThemesToProcessQueue.add(0, pkgName);                            // We want to make sure these resources are taken care of first so                            // send the dequeue message and place it in the front of the queue                            msg = mResourceProcessingHandler.obtainMessage(                                    ResourceProcessingHandler.MESSAGE_DEQUEUE_AND_PROCESS_THEME); //private ResourceProcessingHandler mResourceProcessingHandler;                            mResourceProcessingHandler.sendMessageAtFrontOfQueue(msg);                        }                    }                }            }            msg = Message.obtain();            msg.what = ThemeWorkerHandler.MESSAGE_CHANGE_THEME;            msg.obj = request;            msg.arg1 = removePerAppThemes ? 1 : 0;            mHandler.sendMessage(msg);        }            .....    }

我们来看下ResourceProcessingHandler类:

  private class ResourceProcessingHandler extends Handler {        private static final int MESSAGE_QUEUE_THEME_FOR_PROCESSING = 3;        private static final int MESSAGE_DEQUEUE_AND_PROCESS_THEME = 4;        public ResourceProcessingHandler(Looper looper) {            super(looper);        }        @Override        public void handleMessage(Message msg) {            switch (msg.what) {                case MESSAGE_QUEUE_THEME_FOR_PROCESSING:                    String pkgName = (String) msg.obj;                    synchronized (mThemesToProcessQueue) {                        if (!mThemesToProcessQueue.contains(pkgName)) {                            if (DEBUG) Log.d(TAG, "Adding " + pkgName + " for processing");                            mThemesToProcessQueue.add(pkgName);                            if (mThemesToProcessQueue.size() == 1) {                                this.sendEmptyMessage(MESSAGE_DEQUEUE_AND_PROCESS_THEME);                            }                        }                    }                    break;                case MESSAGE_DEQUEUE_AND_PROCESS_THEME:                    synchronized (mThemesToProcessQueue) {                        pkgName = mThemesToProcessQueue.get(0);                    }                    if (pkgName != null) {                        if (DEBUG) Log.d(TAG, "Processing " + pkgName);                        String name;                        try {                            PackageInfo pi = mPM.getPackageInfo(pkgName, 0);                            name = getThemeName(pi);                        } catch (PackageManager.NameNotFoundException e) {                            name = null;                        }                        int result = mPM.processThemeResources(pkgName);                        if (result < 0) {                            postFailedThemeInstallNotification(name != null ? name : pkgName);                        }                        sendThemeResourcesCachedBroadcast(pkgName, result);                        synchronized (mThemesToProcessQueue) {                            mThemesToProcessQueue.remove(0);                            if (mThemesToProcessQueue.size() > 0 &&                                    !hasMessages(MESSAGE_DEQUEUE_AND_PROCESS_THEME)) {                                this.sendEmptyMessage(MESSAGE_DEQUEUE_AND_PROCESS_THEME);                            }                        }                        postFinishedProcessing(pkgName);                    }                    break;                default:                    Log.w(TAG, "Unknown message " + msg.what);                    break;            }        }    }

另一个处理类:ThemeWorkerHandler

 private class ThemeWorkerHandler extends Handler {        private static final int MESSAGE_CHANGE_THEME = 1;        private static final int MESSAGE_APPLY_DEFAULT_THEME = 2;        private static final int MESSAGE_REBUILD_RESOURCE_CACHE = 3;        public ThemeWorkerHandler(Looper looper) {            super(looper);        }        @Override        public void handleMessage(Message msg) {            switch (msg.what) {                case MESSAGE_CHANGE_THEME:                    final ThemeChangeRequest request = (ThemeChangeRequest) msg.obj;                    doApplyTheme(request, msg.arg1 == 1);                    break;                case MESSAGE_APPLY_DEFAULT_THEME:                    doApplyDefaultTheme();                    break;                case MESSAGE_REBUILD_RESOURCE_CACHE:                    doRebuildResourceCache();                    break;                default:                    Log.w(TAG, "Unknown message " + msg.what);                    break;            }        }    }

我们再来看下doApplyTheme方法:

 private void doApplyTheme(ThemeChangeRequest request, boolean removePerAppTheme) {       if (request == null || request.getNumChangesRequested() == 0) {            postFinish(true, request, 0);            return;        }        .        .        .       if (request.getIconsThemePackageName() != null) {            updateIcons(request.getIconsThemePackageName());            incrementProgress(progressIncrement);        }       if (request.getWallpaperThemePackageName() != null) {            if (updateWallpaper(request.getWallpaperThemePackageName(),                    request.getWallpaperId())) {                mWallpaperChangedByUs = true;            }            incrementProgress(progressIncrement);        }       .       .       .        postFinish(true, request, updateTime);        mIsThemeApplying = false;    }
1 0
原创粉丝点击