Magisk与EdXposed框架安装实践(Android P及以上)
记得初中的时候还在用Android 2.3,高中开始刷机,每个月都去追论坛大佬的自定义精简ROM,不亦乐乎,这一晃都过了快十年了。从以前旧版Android(支持到8.x)的Xposed到现在的EdXposed、Magisk等玩机框架,大佬些的脚步从未停歇。模块开发生态也好了很多(得益于Github及各种文档)。不过由于现在ROM厂商越来越深度的定制和限制(当然也是考虑到普通用户的安全),ROOT起来也麻烦了不少。
其实我自从以前用Android 4.x时搞过机,后来也很久没接触这些了。最近把手边的测试机器(小米POCO F1,骁龙845,Android 10、MIUI 12)拿来搞了搞,发现操作过程也不是很麻烦,本文就仅作记录吧,方便以后查阅,毕竟各种链接每次都临时搜还是很费事。
Xposed由于现在Android新版本的普及,新上市的手机基本都是8.0以上了。所以以前的Xposed框架已经不适用。EdXposed团队成为了后续版本研发的继任者,从Xpsoed的wikipedia中可以查到交接历史:
2017年7月,abforce在GitHub上发布了支持Nougat的xposed, ...
等差数列异或和的小规律
背景异或(xor,运算符号^):按位计算,同0异1,1 ^ 0 = 1 ,1 ^ 1 = 0 ,如此。
现定义等差数列 1, 2, ... , n 的 异或和 为 f(n) = 1 ^ 2 ^ ... ^ n ,求f(n)的值。
实现我们很容易想到质朴的实现如下:
1234567int func(int n) { int xor_sum = 0; for (int i = 1; i <= n; ++i) { xor_sum ^= i; } return xor_sum;}
时间复杂度O(n),空间复杂度此处没有太大必要讨论。
通式联想到等差数列的四则运算都是有求和公式的,那么异或运算有没有呢?直接这么看也看不出来,先输出个十来项看看规律:
12int a[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18};// 1 3 0 4 1 7 0 8 1 11 0 12 1 15 0 16 1 19 ...
Kotlin变长参数的一些小坑
Java中的变长参数先来看看Java中的变长参数,很简单,为了后面的对比,我们做进行一个连续的传参:
12345678910111213141516171819import java.util.Arrays;public class TestVarargs { public static void main(String[] args) { test1("1", "2"); } private static void test1(String... args) { test2(args); } private static void test2(Object... args) { System.out.println(Arrays.toString(args)); System.out.println(args.length); }}// 输出结果// [1, 2]// ...
浅谈JVM语言之函数式编程
Java中的函数式编程闲聊函数式编程在上世纪五十年代就有了,只不过在工业界一直不温不火,最近十年才被广泛认知。其理论基础也并非为编程而设计,而是一种数学抽象(Lamda演算),其实初中就学过了,λ表达式。
在JS(建议把JS作为函数式编程思想学习的入门语言,Java的实现略显臃肿,可能不太便于理解)当中,函数式编程算是应用比较多的了。各现代高级编程语言,都或多或少地支持了函数式编程。
一些基本特点总结
相比平常的指令式编程,函数式编程更在乎执行结果而非过程;
函数是一等公民,可以像普通的数值、引用等变量一样赋值、作为参数传递、作为返回值;
函数是纯函数,即函数不能产生副作用,如不能修改全局变量等,固定的输入就映射固定的输出。
简单示意一下不代表任何语言,因为不同语言在实现方式上有差异,但核心思想不变:
123456789101112// 定义一个函数g,并赋值给ff = g(x, y) = x + y// 写一个方法,函数作为参数传递printF(g) { print(g(1, 2))}// 调用方法printF(f) // 打印结果3// 作为返回值get ...
macOS下载AOSP的小坑
爬坑以下载Android X源码为例,过程和下载AOSP是一样的,只是分支不同而已。源码在线地址:frameworks/support
安装Homebrew在Mac上搞开发必须的包管理工具,类似Ubuntu上的apt。安装非常简单,一行命令的事情,来自官网(Homebrew):
1/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install.sh)"
安装repo工具可以直接下载谷歌官方的repo源码(https://gerrit.googlesource.com/git-repo)然后自己配置命令,但这样很麻烦,直接用brew安装整套Android编译工具:
1brew cask install android-platform-tools
装完就可以直接使用repo命令了。
下载AOSP源码详细过程可参考:Win10用WSL下载AOSP
123456# 创建一个源码目录,命名随意mkdir AOSPcd AOSP# 这里以An ...
覆盖安装Play Store版本的国产App
前言对于Android平台,如果在国内应用商店安装诸如微信、支付宝等国产大型App,相比去Google Play Store安装,会多要不少权限,即便权限无差异,在隐私政策等规则方面,Play Store也会更严格一些,能上架的应用肯定不敢乱搞。之前也有不少用户反映在Play Store安装的微信要流畅不少,某些功能细节也会有差异。
不过由于严格的审核机制,Play Store上的国产App更新频率普遍落后于国内应用商店,如果我们已经安装了国内的最新版本,正常情况下就没办法覆盖安装低版本了。Play Store上也会显示已安装,没有重新安装这种选项。可我们想在不卸载原有版本且保留数据的情况下覆盖安装Play Store上的版本,该怎么办呢?
下文以微信为例。
方案第一种方法很简单,比如我现在装了国内应用商店上的微信,版本为7.0.14,那我可以等着Play Store上架7.0.15版本的微信后直接升级,自然就替换成了Play Store版本的微信。
第二种方法,拒绝等待。我们可以将Play Store上的微信下载下来,手动安装。但是,Play Store是没有提供Apk官方下载途径的 ...
用Gradle脚本管理Manifest文件
编译时区分不同的manifest很多Android项目都会区分debug和release的manifest文件,以便调试,一些组件化的项目甚至有多个manifest文件来调试不同的组件。举个简单的例子,在app的build.gradle文件中:
1234567891011121314android { defaultConfig { applicationId "com.xxx.xxx" } sourceSets { main { if(是否为debug打包) { manifest.srcFile "${projectDir}/src/main/debug/AndroidManifest.xml" } else { manifest.srcFile "${projectDir ...
Win10用WSL下载AOSP
WSL还是挺方便的,配合国内镜像源,可以轻松下载Android源码。
启用WSL关于Win10启用WSL的方法微软官方的文档非常清晰了:适用于 Linux 的 Windows 子系统安装指南 (Windows 10)。由于我这里只用到WSL 1而非WSL 2,所以Win10版本号更新到1909即可,等2004正式推送再折腾WSL 2吧。
安装Ubuntu 20.04直接在微软应用商店搜索Ubuntu即可下载安装。
更好地体验WSL,建议安装Windows Terminal这一步非必须,不过Windows Terminal很香的,开源哦。不试试吗?可参考我之前的:Win10也要愉快地使用Bash
安装repo,下载AOSP1、进入WSL子系统后,我们就可以开始各种配置了,由于最新的Ubuntu 20.04已经默认安装Python 3,所以我们需要先装一下Python 2,以便使用repo工具:
1sudo apt-get install python2.7
然后把python命令软链接到2.7,不然等会儿你repo用不了(这一步很关键):
12cd /usr/binsudo ln -s ...
自定义EditText的无障碍描述(不读hint)
问题我们一般给一个控件设置描述时,会这样:
1xxxView.setContentDescription("xxx");
但是,当你给EditText设置这个时,会发现毫无卵用。为什么呢?
搜了下EditText和其直接父类TextView,没有重写setContentDescription方法,那应该不是setXXX时发生改变,而是getXXX的问题。
果然,在TextView中发现:
123456789101112131415161718192021/** * Returns the text that should be exposed to accessibility services. * <p> * This approximates what is displayed visually. If the user has specified * that accessibility services should speak passwords, this method will * bypass any password transfor ...
快速修改字节码并重打jar包
背景不管是做Android项目还是Java后端Web项目,我们一般都会引用各种三方库。遇到特殊需求时,可能需要修改jar包中的代码。本文以实际示例讲解一些基本方法,方便大家快速入坑。
首先我们都知道直接解压jar包的话,都是class二进制文件,打开后是看不见代码的。之所以可以在开发环境中直接查看jar中的代码是因为IDE已经帮你反编译好了,才能看见Java源码。
入坑如何修改这些jar包中的代码逻辑呢?大致有两种思路:
A、反编译class为java源文件 -> 修改Java源码 -> 重新编译成class文件 -> 将新的class文件覆盖jar包中的原有文件
B、解压得到class文件 -> 直接修改其中的二进制代码(即对应的字节码) -> 将修改后的class文件覆盖jar包中的原有文件
注: 下文基于Java 8环境。
A方法这种方法也是最常见的方式,也相对较简单,但有一些弊端,后面会讲到。我们直接按步骤来走一遍。
1、先下载 JD-GUI 最新版,得益于Java的跨平台特性,各操作系统都能跑。如果是Windows系统,直接运行exe即可,若是L ...
Win10也要愉快地使用Bash
对于习惯了Linux和Mac的同学来说,Windows自带的终端确实不太好用。其实我们完全可以用Bash取而代之。
安装Windows Terminal自从巨硬拥抱开源之后,那是骚操作频频。Windows Terminal是一个开源项目,它本身只是一个终端容器,可以装载系统自带的CMD、PowerShell甚至是WSL子系统的终端。
下载安装很简单,可以在应用商店直接搜索Terminal安装,也可以去GitHub上下载安装包:https://github.com/microsoft/terminal/releases
注:需要Win10版本不小于1903。Win+R打开“运行”输入 winver 命令即可查看系统版本。
安装Git for Windows先到官网(https://git-scm.com/download/win)下载 64-bit Git for Windows Setup 然后安装,基本上一路下一步,但需要注意几点最后一步有3个Enable xxx,默认第3个(和symbollink相关)没勾,请把它勾上。
安装Git主要是为了它附送的Git Bash,这是本文的主角 ...
Windows安装repo的真正解决方案
2020-02-22更新!我发现谷歌在最近几天发布了git-repo 2.4版本,并更新了 Microsoft Windows Details 文档,直接解决了此文问题,比本文以前的三方解决办法简单很多很多。
最新官方解决方案一、基础设施
安装最新的Git for Windows(参考下面的旧文即可),目前版本是2.25.1
安装Python 3 ,目前版本是3.8.1,不要安装Python 2,这是和旧办法的不同之处
配置各种环境变量(参照旧文即可),Python 3在安装的时候勾选Add path那项就能自动配置
二、搞起最新的repo工具和旧文的安装Repo步骤类似,只不过所有都替换成谷歌官方的:
123mkdir ~/bincurl https://storage.googleapis.com/git-repo-downloads/repo > ~/bin/repochmod a+rx ~/bin/repo
然后注意,先下载最新的repo工具源码,再进行init操作:
1234567891011# 先随便新建源码目录mkdir -p ~/AOSP/.repocd ~ ...
源码茶舍之如何由Uri找寻ContentProvider
引子我们都知道四大组件之一ContentProvider的用处,它给大家提供一种统一的数据访问格式。调用者无需关心数据源于何处(如DB、XML文件和网络等),只需获取到对应的ContentResolver来进行增删查改即可。自己实现一个Provider的时候,也会在配置文件中声明如下:
12345<provider android:name=".provider.TestProvider" android:authorities="com.xxx.yyy.provider" android:exported="true" android:readPermission="com.xxx.yyy.permission.READ_PROVIDER" />
其中 authorities 是该Provider的唯一标识,所以一般都写成包名与其他字符串的组合形式,若需提供数据给其他应用,则 exported 要设为true,同时比较规范的做法还需要加上读写权限。然后,我们再从常见的 ...
源码茶舍之FLAG_EXCLUDE_STOPPED_PACKAGES与广播唤醒
发现我们先随便实现一个BroadcastReceiver,静态注册:
12345class TestReceiver : BroadcastReceiver() { override fun onReceive(context: Context?, intent: Intent?) { Log.w("TEST-1", "onReceive ${intent?.action}") }}
12345<receiver android:name=".TestReceiver"> <intent-filter> <action android:name="com.xxx.yyy.action_test_receiver" /> </intent-filter></receiver>
其他诸如Activity什么的就不写了哈,然后我们启动这个测 ...
走进各大语言的协程世界
想聊聊C++、C#、JS、Kotlin等语言中的协程实现与应用。
挖坑待填,未完待续……