AndroidPi

Window与WindowManager机制

接着Activity的启动流程分析Window的添加过程,与Activity相关联的window的创建发生在Activity.performLaunchActivity()方法中,当activity实例创建后,会调用该activity的attach()方法,该方法中会创建window的实例,它是一个PhoneWindow对象,但此时该window实例还未设置布局,也未添加到WindowManager中: Activity.java final void attach(Context context, ActivityThread aThread, Instrumentation instr, IBinder token, int ident, Application application, Intent intent, ActivityInfo info, CharSequence title, Activity parent, String id, NonConfigurationInstances lastNonConfigurationInstances, Configuration config, String referrer, IVoiceInteractor voiceInteractor, Window window, ActivityConfigCallback activityConfigCallback) { attachBaseContext(context); mFragments.attachHost(null /*parent*/); mWindow = new PhoneWindow(this, window, activityConfigCallback); mWindow.setWindowControllerCallback(this); mWindow.setCallback(this); mWindow.setOnWindowDismissedCallback(this); mWindow.getLayoutInflater().setPrivateFactory(this); if (info.softInputMode != WindowManager.LayoutParams.SOFT_INPUT_STATE_UNSPECIFIED) { mWindow.setSoftInputMode(info.softInputMode); } if (info.uiOptions != 0) { mWindow.setUiOptions(info.uiOptions); } mUiThread = Thread.currentThread(); mMainThread = aThread; mInstrumentation = instr; mToken = token; mIdent = ident; mApplication = application; mIntent = intent; mReferrer = referrer; mComponent = intent....

March 10, 2018 · 24 min · 4947 words · LEOY

Activity启动流程:总览

网络上已经有许多关于这个主题的文章了,但路只有自己走一遍才会熟悉,源码的分析与理解也是一样的。因此从这篇文章开始我将开始从源码阅读中去理解Android Framework层以及更多系统相关的知识点。从点到线再到面地去掌握Android开发的武艺。 src/com/android/launcher3/Launcher.java 点击桌面应用Lanucher3的快捷方式: /** * Launches the intent referred by the clicked shortcut. * * @param v The view representing the clicked shortcut. */ public void onClick(View v) { // Make sure that rogue clicks don't get through while allapps is launching, or after the // view has detached (it's possible for this to happen if the view is removed mid touch). if (v.getWindowToken() == null) { return; } if (!...

March 7, 2018 · 71 min · 15070 words · LEOY

Android系统启动流程

Android系统架构 1 2

March 4, 2018 · 1 min · 3 words · LEOY

动态规划

动态规划(Dynamic programming)通常用来解决最优化问题,在这类问题中,通过做出一组选择来达到最优解。在做出每个选择的同时,通常会生成与原问题形式相同的子问题。当多于一个选择子集都生成相同的子问题时,动态规划技术通常就会很有效,其关键技术就是对每个这样的子问题都保存其解,当重复出现时即可便重复求解。 动态规划与分治方法相似,都是通过组合子问题的解来求解原问题,分治法将问题划分为不相交的子问题,递归地求解子问题,再将它们组合起来求出原问题的解。与之相反,动态规划应用于子问题重叠的情况,即不同的子问题具有公共的子子问题(子问题的求解是递归进行的,将其划分为更小的子子问题)。 实现方法 与朴素递归算法之所以效率很低,是因为它反复求解相同的子问题。因此,动态规划方法仔细安排求解顺序,对每个子问题只求解一次,并将结果保存下来,如果随后再次需要此子问题的解,只需查找保存的结果,而不必重新计算。因此,动态规划方法是通过额外的空间来换取时间,是典型的时空权衡(time-memory trade-off)的例子。并且时间上的节约可能是非常巨大的,可能将一个指数时间的解转化为一个多项式时间的解。动态规划有两种等价的实现方法,分别是带备忘的自顶向下法和自底向上法。 带备忘的自顶向下法(top-down with memoization) 此方法仍按自然的递归形式编写过程,但过程会保存每个子问题的解(通常保存在一个数组或散列表中)。当需要一个子问题的解时,过程首先检查是否已经保存过此解。如果是则直接返回保存的值,从而节省了计算时间,否则,按通常的方式计算这个子问题。 自底向上法(bottom-up method) 这种方法一般需要恰当定义子问题“规模”的概念,使得任何子问题的求解都只依赖于“更小的”子问题的求解。因而可以将子问题按规模排序,按由小至大的顺序进行求解。当求解某个大问题时,它所依赖的那些更小的子问题都已经求解完毕,结果已经保存。么个子问题只需求解一次,当我们求解它时,它所有的前提子问题都已经求解完成。 两种方法得到的算法具有相同的渐进运行时间,仅有的差异是在某些特殊情况下,自顶向下的方法并未真正递归地考察所有可能的子问题。由于没有频繁递归函数调用的开销,自底向上方法的时间复杂度函数通常具有更小的系数。 子问题图 在思考一个动态规划问题时,应该弄清楚所涉及的子问题和子问题之间的依赖关系。问题的子问题图准确第表达了这些信息。它是一个有向图,每个顶点对应一个子问题,若求解子问题x的最优解时需要直接用到子问题y的最优解,那么在子问题图中就有一条从子问题x的顶点到子问题y的顶点的有向边。 自底向上的动态规划方法处理子问题图中顶点的顺序为:对于一个给定的子问题x,在求解它之前求解邻接到它的子问题y。即自底向上动态规划算法是按“逆拓扑序(reserve topological sort)”来处理子问题图中的顶点。类似,可以用“深度优先搜索”来描述自顶向下动态规划算法处理子问题的顺序。

December 4, 2017 · 1 min · 19 words · LEOY

图的表示与搜索

图论问题渗透整个计算机科学,解决图论问题的相关算法对计算机科学领域至关重要。最基本的是对图的遍历与搜索,不过首先要讨论的是如何将图表示为可用的数据结构。 图的表示 算法导论中介绍了图的两种常用表示方法,分别是邻接链表和邻接矩阵,在面向对象编程中,还有一种常用表示方法,即对象和指针(引用),也有称为边列表(edge list)。 根据图的定义,有向图和无向图均由一个顶点集合和这个顶点集合$V$中顶点间是否连接以及是否有向所构成的一个边集合$E$组成,定义图为顶点集和相应边集的二元组\(G = (V, E)\),对图的三种表示形式只是对这一定义在编程语言或者说是内存中的表示形式。其中对象和指针(边列表)表示方法是最接近原始的定义的,即顶点集合与边集合。 将图的n个顶点使用0到n-1的序号进行编号,下面分别对三种表示方法进行描述,并比较其在如下几个方面的不同: 内存占用 判断两个顶点是否相连(即连接这两个顶点的边是否存在)的时间复杂度 寻找一个顶点的所有邻居顶点 对象指针(边列表) 对象指针 Set<Vertex> vertexSet = new HashSet(); Set<Edge> edgeSet = new HashSet(); Vertex a = new Vertex(0); Vertex b = new Vertex(1); Vertex c = new Vertex(2); Vertex d = new Vertex(3); vertexSet.add(Arrays.asList({})); edgeSet.addAll(Arrays.asList({new Edge(a, b), new Edge(a, c), new Edge(a, d), new Edge(b, a), new Edge(c, a), new Edge(c, d), new Edge(d, a), new Edge(d, c)})); 边列表 边列表中的每个元素表示两个相邻顶点构成的边,其中顶点用其序号给出。 int[][] edgeList = {{0, 1}, {0, 2}, {0, 3}, {1, 0}, {2, 0}, {2, 3}, {3, 0}, {3, 2}}; 邻接链表 邻接链表中第$i$个元素包含与顶点$v[i]$相邻的其它顶点的序号:...

December 3, 2017 · 1 min · 183 words · LEOY