ThemeChooser---debug(5.1)

  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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值