ThemeChooser---debug (5.1)
2016-04-27 16:59
169 查看
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; }
相关文章推荐
- GIMP
- 笔试题41. LeetCode OJ (28)
- Java并发编程:synchronized
- JS模拟类的实现
- org.xml.sax.SAXParseException: prolog 中不允许有内容
- spring框架学习(五)注解
- 【补充习题三】待定常数法之微分中值定理
- hdoj1013
- #leetcode#198. House Robber
- jqGrid的treegrid的bug修复
- 对嵌入式Linux中的根文件系统的理解和解析
- git Pull Request 是什么意思?
- linux 利用nethogs查看某进程的网卡流量
- Tiled GPU perf. warning: Backbuffer was not cleared/discarded, doing Render.OpaqueGeometry/RenderFor
- 使用javah生成jni文件(命令行命令)
- struts2集合
- CakePHP程序员必须知道的21条技巧
- nginx反向代理到后端tomcat,并将IP地址发送到后端的配置
- Java常见错误-“Dynamic Web Module 3.0 requires Java 1.6 or newer.”错误
- nrf51822 --- 微信移植 (官方例子移植到SDK10.0)