自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+

原创 滴滴插件化VirtualAPK框架原理解析(二)之Service 管理

在前一篇博客滴滴插件化框架VirtualAPK原理解析(一)之插件Activity管理 中VirtualAPK是如何对Activity进行管理的,本篇博客,我们继续来学习这个框架,这次我们学习的是如何去管理Service。Service工作原理分析说道如何对Service进行插件化,肯定得先了解Service的工作过程,不然何谈插件化?所以我们先一起学习Service的工作原理。Service分为

2017-07-30 23:21:11 3940 1

原创 滴滴插件化框架VirtualAPK原理解析(一)之插件Activity管理

上周末,滴滴与360都开源了各自的插件化框架,Virtualapk与RePlugin,作为一个插件化方面的狂热研究者,在周末就迫不及待的下载了Virtualapk框架来进行研究,本篇博客带来的是Virtualapk原理解析的第一篇Activity管理,博客只是自己的理解,小弟才疏学浅,可能有很多理解不对的地方,欢迎各位大神指出。(看博客之前,请大家先下载Virtualapk的项目,https://g

2017-07-02 21:15:48 9564 5

原创 leetcode刷题(89)——34. 在排序数组中查找元素的第一个和最后一个位置

给定一个按照升序排列的整数数组 nums,和一个目标值 target。找出给定目标值在数组中的开始位置和结束位置。你的算法时间复杂度必须是 O(log n) 级别。如果数组中不存在目标值,返回 [-1, -1]。示例 1:输入: nums = [5,7,7,8,8,10], target = 8输出: [3,4]示例 2:输入: nums = [5,7,7,8,8,10], target = 6输出: [-1,-1]其实这里就是二分查找的变体,思路就是分别求左右界,然后进行合并即可,代

2020-08-06 14:48:24 20

原创 leetcode刷题(88)——415. 字符串相加

给定两个字符串形式的非负整数 num1 和num2 ,计算它们的和。提示:num1 和num2 的长度都小于 5100num1 和num2 都只包含数字 0-9num1 和num2 都不包含任何前导零你不能使用任何內建 BigInteger 库, 也不能直接将输入的字符串转换为整数形式我的思路:1.2个字符串如果长度不一样,则对于短的字符串,前面进行0补位2.从后面开始相加,因为要处理大于10进位问题,我之前按正序进行相加,就会出现进位出错问题3.进位还有个问题,就是for循环结束了,第一

2020-08-04 17:26:27 31

原创 leetcode刷题(87)——46. 全排列

给定一个 没有重复 数字的序列,返回其所有可能的全排列。示例:输入: [1,2,3]输出:[ [1,2,3], [1,3,2], [2,1,3], [2,3,1], [3,1,2], [3,2,1]]回溯算法的套路for 选择 in 选择列表: # 做选择 将该选择从选择列表移除 路径.add(选择) backtrack(路径, 选择列表) # 撤销选择 路径.remove(选择) 将该选择再加入选择列表于

2020-08-03 19:55:12 21

原创 leetcode刷题(86)——739.二分查找

给定一个 n 个元素有序的(升序)整型数组 nums 和一个目标值 target ,写一个函数搜索 nums 中的 target,如果目标值存在返回下标,否则返回 -1。示例 1:输入: nums = [-1,0,3,5,9,12], target = 9输出: 4解释: 9 出现在 nums 中并且下标为 4示例 2:输入: nums = [-1,0,3,5,9,12], target = 2输出: -1解释: 2 不存在 nums 中因此返回 -1提示:你可以假设 nums 中的所

2020-08-01 16:48:51 26

原创 Android Framework分析(3)——Zygote进程源码分析
原力计划

Zygote进程源码分析由app_process运行ZygoteInit classzygote由java编写而成,不能直接由init进程启动运行。若想执行zygote类,必须先创建虚拟机,然后在虚拟机上运行ZygoteInit类。执行这一任务的就是app_process程序。下面我们开始分析zygote进程的启动流程:/system/core/rootdir/init.rc可以看到init.rc中有如下导包import /init.$(ro.zygote).rc如果是64位系统,$(ro

2020-07-10 11:32:35 91

原创 Android Framework分析(1)-init
原力计划

分析基于28的源码,涉及源码:system/core/init/ - init.cpp - init_parser.cpp - signal_handler.cppinit进程是Linux系统中用户空间的第一个进程,进程号固定为1。Kernel启动后,在用户空间启动init进程,并调用init中的main()方法执行init进程的职责。对于init进程的功能分为4部分:1.解析并运行所有的init.rc相关文件2.根据rc文件,生成相应的设备驱动节点3.处理子进程的终止(signal

2020-07-06 21:31:41 104

原创 Android framework学习(2)——Handler Native层
原力计划

基于android28源码,MessageQueue类里面涉及到多个native方法,除了MessageQueue的native方法,native层本身也有一套完整的消息机制,用于处理native的消息,如下图Native层的消息机制。Java层可以向MessageQueue消息队列中添加消息,Native层也可以向MessageQueue消息队列中添加消息MessageQueue初始化过程的调用链如下:在MessageQueue中的native方法如下: private native st

2020-06-30 16:57:28 127

原创 Android使用kotlin自定义plugin插件找不到类,Unable to load class

情况是这样,自定义gradle plugin,新建了一个module,并引入了groovy插件apply plugin: 'groovy'同时resources下也生声明了使用如下代码上传到本地仓库uploadArchives { repositories.mavenDeployer { repository(url: uri('../repo')) //仓库的路径,此处是项目根目录下的 repo 的文件夹 pom.groupId = 'com.myl.a

2020-06-20 09:59:40 196

原创 leetcode刷题(85)——739.每日温度

根据每日 气温 列表,请重新生成一个列表,对应位置的输出是需要再等待多久温度才会升高超过该日的天数。如果之后都不会升高,请在该位置用 0 来代替。例如,给定一个列表 temperatures = [73, 74, 75, 71, 69, 72, 76, 73],你的输出应该是 [1, 1, 4, 2, 1, 1, 0, 0]。提示:气温 列表长度的范围是 [1, 30000]。每个气温的值的均为华氏度,都是在 [30, 100] 范围内的整数。1.暴力法public int[] dailyTempe

2020-06-11 14:39:57 116

原创 leetcode刷题(84)——9. 回文数

判断一个整数是否是回文数。回文数是指正序(从左向右)和倒序(从右向左)读都是一样的整数。示例 1:输入: 121输出: true示例 2:输入: -121输出: false解释: 从左向右读, 为 -121 。 从右向左读, 为 121- 。因此它不是一个回文数。示例 3:输入: 10输出: false解释: 从右向左读, 为 01 。因此它不是一个回文数。public class Solution9 { public boolean isPalindrome(int x)

2020-06-10 16:11:33 72

原创 leetcode刷题(83)——面试题46. 把数字翻译成字符串

对于题目的理解,其实也不难,我们并没有必要把数字真的转换成它要求的字母,只要得出有多少种分割方法就行了。这种分割的问题也叫“隔板问题”——在数字之间的缝隙里插入隔板,看有多少种分法,是一类组合问题。这里由于受到26个字母的限制,只需要考虑分割之后,每两个“隔间”内有两个数字就可以了。也就是说,我们只需要考虑当前数字与它后面的数字的组合是不是在[10,25]内即可,这里之所以是边界是10,因为会出现01,02这种,这种不是有效的2位数,不能转化为对应的字母这么想的话,实际上该问题已经有点像经典的“爬楼梯”

2020-06-10 15:22:32 71

原创 Android Apk瘦身方案2——gradle插件将png自动压缩为webp
原力计划

实现思路在 mergeRes 和 processRes 任务之间插入 WebP 压缩任务,如下图所示:使用开源框架Cwebp,使用命令行对所有的图片进行遍历处理,然后将结果输出Google 官方提供的下载地址:https://storage.googleapis.com/downloads.webmproject.org/releases/webp/index.html 下载的 cwebp 二进制可执行文件 64 位版本。由于 WebP 格式在 14 <= minSdkVersion &lt

2020-06-09 20:11:26 201

原创 Android Apk瘦身方案1——R.java文件常量内联
原力计划

R.java 文件结构R.java 是自动生成的,它包含了应用内所有资源的名称到数值的映射关系。先创建一个最简单的工程,看看 R.java 文件的内容:R文件生成的目录为app/build/generated/not_namespaced_r_class_sources/xxxxxDebug/processXXXXDebugResources/r/com/xxx/xxx/R.javaR.java 内部包含了很多内部类:如 layout、mipmap、drawable、string、id 等等这些

2020-06-05 22:57:39 188

原创 Android Gradle源码分析

一.如何调试Android Gralde源码最简单的方式如下:1.配置 gradle.properties比较方便的做法是配置全局的 gradle.properties,这样对所有 Gradle 工具都适用,配置文件位于 ~/.gradle/gradle.properties,在 gradle.properties 文件中加上 org.gradle.jvmargs 属性:org.gradle.jvmargs=-XX:MaxPermSize=4g -XX:+HeapDumpOnOutOfMemoryE

2020-06-04 11:24:52 121

原创 leetcode刷题(82)——14. 最长公共前缀

编写一个函数来查找字符串数组中的最长公共前缀。如果不存在公共前缀,返回空字符串 “”。示例 1:输入: [“flower”,“flow”,“flight”]输出: “fl”示例 2:输入: [“dog”,“racecar”,“car”]输出: “”解释: 输入不存在公共前缀。说明:所有输入只包含小写字母 a-z 。思路标签:链表当字符串数组长度为 0 时则公共前缀为空,直接返回令最长公共前缀 ans 的值为第一个字符串,进行初始化遍历后面的字符串,依次将其与 ans 进行比较,

2020-05-19 15:22:47 83

原创 leetcode刷题(81)——103. 二叉树的锯齿形层次遍历

给定一个二叉树,返回其节点值的锯齿形层次遍历。(即先从左往右,再从右往左进行下一层遍历,以此类推,层与层之间交替进行)。例如:给定二叉树 [3,9,20,null,null,15,7], 3 / \ 9 20 / \ 15 7返回锯齿形层次遍历如下:[ [3], [20,9], [15,7]]BFS(广度优先遍历)思路最直观的方法是 BFS,逐层遍历树。BFS 在每层的默认顺序是从左到右,因此需要调整 BFS 算法以生成锯齿序列。最关键

2020-05-16 17:51:34 68

原创 leetcode刷题(80)—— 23. 合并K个排序链表

合并 k 个排序链表,返回合并后的排序链表。请分析和描述算法的复杂度。示例:输入:[ 1->4->5, 1->3->4, 2->6]输出: 1->1->2->3->4->4->5->6方法1:使用优先队列合并我们需要维护当前每个链表没有被合并的元素的最前面一个,k个链表就最多有 k个满足这样条件的元素,每次在这些元素里面选取 val 属性最小的元素合并到答案中。在选取最小元素的时候,我们可以用优先队列来优化这

2020-05-13 20:25:42 63

原创 都2020年了Andoid还能如何性能优化(1)—— 启动速度优化
原力计划

一.启动类型冷启动指进程死亡的情况下,从点击应用图标到UI界面完全显示且用户可操作的全部过程。大致流程:Click Event -> IPC -> Process.start -> ActivityThread -> bindApplication -> LifeCycle -> ViewRootImpl用户点击桌面图标,这个点击事件它会触发一个IPC的操作,之后便会执行到Process的start方法中,这个方法是用于进程创建的,接着,便会执行到Activit

2020-05-13 16:21:04 212

原创 leetcode刷题(79)—— 160. 相交链表

编写一个程序,找到两个单链表相交的起始节点。如下面的两个链表:在节点 c1 开始相交。示例 1:输入:intersectVal = 8, listA = [4,1,8,4,5], listB = [5,0,1,8,4,5], skipA = 2, skipB = 3输出:Reference of the node with value = 8输入解释:相交节点的值为 8 (注意,如果两个链表相交则不能为 0)。从各自的表头开始算起,链表 A 为 [4,1,8,4,5],链表 B 为 [5,0

2020-05-13 11:36:27 59

原创 leetcode刷题(78)—— 876. 链表的中间结点

给定一个带有头结点 head 的非空单链表,返回链表的中间结点。如果有两个中间结点,则返回第二个中间结点。示例 1:输入:[1,2,3,4,5]输出:此列表中的结点 3 (序列化形式:[3,4,5])返回的结点值为 3 。 (测评系统对该结点序列化表述是 [3,4,5])。注意,我们返回了一个 ListNode 类型的对象 ans,这样:ans.val = 3, ans.next.val = 4, ans.next.next.val = 5, 以及 ans.next.next.next = N

2020-05-12 21:12:43 91

原创 leetcode刷题(77)—— 148. 排序链表

在 O(n log n) 时间复杂度和常数级空间复杂度下,对链表进行排序。示例 1:输入: 4->2->1->3输出: 1->2->3->4示例 2:输入: -1->5->3->4->0输出: -1->0->3->4->5最开始笨拙的想法/** * Definition for singly-linked list. * public class ListNode { * int val; *

2020-05-12 21:10:20 59

原创 leetcode刷题(76)—— 56. 合并区间

给出一个区间的集合,请合并所有重叠的区间。示例 1:输入: [[1,3],[2,6],[8,10],[15,18]]输出: [[1,6],[8,10],[15,18]]解释: 区间 [1,3] 和 [2,6] 重叠, 将它们合并为 [1,6].示例 2:输入: [[1,4],[4,5]]输出: [[1,5]]解释: 区间 [1,4] 和 [4,5] 可被视为重叠区间。方法一:排序思路如果我们按照区间的左端点排序,那么在排完序的列表中,可以合并的区间一定是连续的。如下图所示,标记为蓝色、

2020-05-12 18:18:21 69

原创 leetcode刷题(75)— 547. 朋友圈

班上有 N 名学生。其中有些人是朋友,有些则不是。他们的友谊具有是传递性。如果已知 A 是 B 的朋友,B 是 C 的朋友,那么我们可以认为 A 也是 C 的朋友。所谓的朋友圈,是指所有朋友的集合。给定一个 N * N 的矩阵 M,表示班级中学生之间的朋友关系。如果M[i][j] = 1,表示已知第 i 个和 j 个学生互为朋友关系,否则为不知道。你必须输出所有学生中的已知的朋友圈总数。示例 1:输入: [[1,1,0], [1,1,0], [0,0,1]]输出: 2 说明:已知学生0和学生

2020-05-12 15:24:57 620

原创 leetcode刷题(74)—128. 最长连续序列

给定一个未排序的整数数组,找出最长连续序列的长度。要求算法的时间复杂度为 O(n)。示例:输入: [100, 4, 200, 1, 3, 2]输出: 4解释: 最长连续序列是 [1, 2, 3, 4]。它的长度为 4。方法 2:排序想法如果我们可以将数组中的数字升序迭代,找连续数字会变得十分容易。为了将数组变得有序,我们将数组进行排序。算法首先检查输入的数组是否为空数组,如果是,函数直接返回 0 。对于其他情况,我们将 nums 数组排序,并考虑除了第一个数字以外的每个数字与它前一个数字

2020-05-11 17:31:39 53

原创 leetcode刷题(74)——215.数组中的第K个最大元素

方法1:思路是创建一个小顶堆,将所有数组中的元素加入堆中,并保持堆的大小小于等于 k。这样,堆中就保留了前 k 个最大的元素。这样,堆顶的元素就是正确答案。像大小为 k 的堆中添加元素的时间复杂度为 O(logk),我们将重复该操作 N 次,故总时间复杂度为 O(Nlogk)。class Solution { public int findKthLargest(int[] nums, int k) { // init heap 'the smallest element fir

2020-05-11 17:00:05 54

原创 leetcode刷题(73)——33. 搜索旋转排序数组

假设按照升序排序的数组在预先未知的某个点上进行了旋转。( 例如,数组 [0,1,2,4,5,6,7] 可能变为 [4,5,6,7,0,1,2] )。搜索一个给定的目标值,如果数组中存在这个目标值,则返回它的索引,否则返回 -1 。你可以假设数组中不存在重复的元素。你的算法时间复杂度必须是 O(log n) 级别。示例 1:输入: nums = [4,5,6,7,0,1,2], target = 0输出: 4示例 2:输入: nums = [4,5,6,7,0,1,2], target =

2020-05-11 14:34:18 60

原创 leetcode刷题(72)——岛屿的最大面积

给定一个包含了一些 0 和 1 的非空二维数组 grid 。一个 岛屿 是由一些相邻的 1 (代表土地) 构成的组合,这里的「相邻」要求两个 1 必须在水平或者竖直方向上相邻。你可以假设 grid 的四个边缘都被 0(代表水)包围着。找到给定的二维数组中最大的岛屿面积。(如果没有岛屿,则返回面积为 0 。)示例 1:[[0,0,1,0,0,0,0,1,0,0,0,0,0], [0,0,0,0,0,0,0,1,1,1,0,0,0], [0,1,1,0,1,0,0,0,0,0,0,0,0], [0

2020-05-10 21:46:13 81

原创 leetcode刷题(71)——93. 复原IP地址

给定一个只包含数字的字符串,复原它并返回所有可能的 IP 地址格式。有效的 IP 地址正好由四个整数(每个整数位于 0 到 255 之间组成),整数之间用 ‘.’ 分隔。示例:输入: “25525511135”输出: [“255.255.11.135”, “255.255.111.35”]解体思路:这里明显是可以使用回溯的方法,一层层往下,直到枚举出所有的结果。需要注意一点是,如果是出现0,那么只能占用1位,也就是0.192.1.1是合理的,000.1.11.1是不合理的。后面题解就有涉及一部分

2020-05-09 17:54:37 132

原创 leetcode刷题(70)——71. 简化路径

以 Unix 风格给出一个文件的绝对路径,你需要简化它。或者换句话说,将其转换为规范路径。在 Unix 风格的文件系统中,一个点(.)表示当前目录本身;此外,两个点 (…) 表示将目录切换到上一级(指向父目录);两者都可以是复杂相对路径的组成部分。更多信息请参阅:Linux / Unix中的绝对路径 vs 相对路径请注意,返回的规范路径必须始终以斜杠 / 开头,并且两个目录名之间必须只有一个斜杠 /。最后一个目录名(如果存在)不能以 / 结尾。此外,规范路径必须是表示绝对路径的最短字符串。示例 1:

2020-05-09 14:25:38 66

原创 leetcode刷题(69)——151.翻转字符串里的单词

给定一个字符串,逐个翻转字符串中的每个单词。示例 1:输入: “the sky is blue”输出: “blue is sky the”示例 2:输入: " hello world! "输出: “world! hello”解释: 输入字符串可以在前面或者后面包含多余的空格,但是反转后的字符不能包括。示例 3:输入: “a good example”输出: “examp...

2020-05-08 15:05:23 42

原创 leetcode刷题(68)——43. 字符串相乘

给定两个以字符串形式表示的非负整数 num1 和 num2,返回 num1 和 num2 的乘积,它们的乘积也表示为字符串形式。示例 1:输入: num1 = “2”, num2 = “3”输出: “6”示例 2:输入: num1 = “123”, num2 = “456”输出: “56088”说明:num1 和 num2 的长度小于110。num1 和 num2 只包含数字 0...

2020-05-08 11:41:55 64

原创 leetcode刷题(67)——567. 字符串的排列

给定两个字符串 s1 和 s2,写一个函数来判断 s2 是否包含 s1 的排列。换句话说,第一个字符串的排列之一是第二个字符串的子串。示例1:输入: s1 = “ab” s2 = “eidbaooo”输出: True解释: s2 包含 s1 的排列之一 (“ba”).示例2:输入: s1= “ab” s2 = “eidboaoo”输出: False注意:输入的字符串只包含小写字...

2020-05-07 21:16:26 55

原创 leetocode刷题(66)—— 136. 只出现一次的数字

给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现两次。找出那个只出现了一次的元素。说明:你的算法应该具有线性时间复杂度。 你可以不使用额外空间来实现吗?示例 1:输入: [2,2,1]输出: 1示例 2:输入: [4,1,2,1,2]输出: 4需要额外空间的解法class Solution { public int singleNumber(in...

2020-04-25 11:55:30 66

原创 leetocode刷题(1)—— 1. 两数之和

给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标。你可以假设每种输入只会对应一个答案。但是,你不能重复利用这个数组中同样的元素。示例:给定 nums = [2, 7, 11, 15], target = 9因为 nums[0] + nums[1] = 2 + 7 = 9所以返回 [0, 1]class Solut...

2020-04-14 10:52:03 42

原创 全局Context无侵入式获取

当我们在使用第三方库,或者自己封装库,如果需要需要用到Context时,一般做法就是将初始化方法暴露给调用方,让调用方在初始化类库时,传入Context。publi class App extends Application { /** * 是否是Debug环境 */ public static final boolean IS_DEBUG = true;...

2020-03-23 17:08:54 177

原创 leetcode刷题(65)——300. 最长上升子序列

定一个无序的整数数组,找到其中最长上升子序列的长度。示例:输入: [10,9,2,5,3,7,101,18]输出: 4解释: 最长的上升子序列是 [2,3,7,101],它的长度是 4。说明:可能会有多种最长上升子序列的组合,你只需要输出对应的长度即可。你算法的时间复杂度应该为 O(n2) 。进阶: 你能将算法的时间复杂度降低到 O(n log n) 吗?注意这里和上一题不一样的...

2020-01-30 23:08:26 78

原创 leetcode刷题(64)——674. 最长连续递增序列

给定一个未经排序的整数数组,找到最长且连续的的递增序列。示例 1:输入: [1,3,5,4,7]输出: 3解释: 最长连续递增序列是 [1,3,5], 长度为3。尽管 [1,3,5,7] 也是升序的子序列, 但它不是连续的,因为5和7在原数组里被4隔开。示例 2:输入: [2,2,2,2,2]输出: 1解释: 最长连续递增序列是 [2], 长度为1。注意:数组长度不会超过100...

2020-01-30 22:28:37 82

原创 leetcode刷题(63)——714. 买卖股票的最佳时机含手续费

给定一个整数数组 prices,其中第 i 个元素代表了第 i 天的股票价格 ;非负整数 fee 代表了交易股票的手续费用。你可以无限次地完成交易,但是你每次交易都需要付手续费。如果你已经购买了一个股票,在卖出它之前你就不能再继续购买股票了。返回获得利润的最大值。示例 1:输入: prices = [1, 3, 2, 8, 4, 9], fee = 2输出: 8解释: 能够达到的最大利...

2020-01-30 21:24:44 96

提示
确定要删除当前文章?
取消 删除