先自我介绍一下,小编浙江大学毕业,去过华为、字节跳动等大厂,目前阿里P7
深知大多数程序员,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年最新Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上Android开发知识点,真正体系化!
由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新
如果你需要这些资料,可以添加V获取:vip204888 (备注Android)
正文
Application.getProcessName()方法直接返回当前进程名。这不就是我们想要的API吗!
但是这个方法只有在android9【也就是aip28】之后的系统才能调用。
public class ProcessUtil {
/**
- 通过Application新的API获取进程名,无需反射,无需IPC,效率最高。
*/
public static String getCurrentProcessNameByApplication() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
return Application.getProcessName();
}
return null;
}
}
android9以前的系统怎么办呢?
android9以前的系统怎么办呢?
android9以前的系统怎么办呢?
方法二:ActivityThread.currentProcessName() 方法
于是大叔好奇,看了看Application.getProcessName()的源码,他是如何实现的?
public class Application extends ContextWrapper implements ComponentCallbacks2 {
public static String getProcessName() {
return ActivityThread.currentProcessName();
}
}
我们发现了ActivityThread.currentProcessName()这个方法。
于是大叔继续翻了下源码:
/**
- {@hide}
*/
public final class ActivityThread extends ClientTransactionHandler {
public static String currentProcessName() {
//…
}
}
奥利给,ActivityThread.currentProcessName()方法居然是public static的。
奥利给,ActivityThread.currentProcessName()方法居然是public static的。
奥利给,ActivityThread.currentProcessName()方法居然是public static的。
但是,马上就发现:
ActivityThread类是hide的,app无法直接调用。
ActivityThread类是hide的,app无法直接调用。
ActivityThread类是hide的,app无法直接调用。
于是大叔继续翻源码,看看这个方法是什么时候新增的。
大叔发现这个方法在android4.3.1上就已经有了这个方法了。
在android4.0.4上没有找到currentProcessName()方法。
那么意味着,我们是不是可以反射调用 ActivityThread.currentProcessName() ?
答案当然是可以。
于是我们在ProcessUtil工具类中实现了这个方法:
public class ProcessUtil {
/**
- 通过反射ActivityThread获取进程名,避免了ipc
*/
public static String getCurrentProcessNameByActivityThread() {
String processName = null;
try {
final Method declaredMethod = Class.forName(“android.app.ActivityThread”, false, Application.class.getClassLoader())
.getDeclaredMethod(“currentProcessName”, (Class<?>[]) new Class[0]);
declaredMethod.setAccessible(true);
final Object invoke = declaredMethod.invoke(null, new Object[0]);
if (invoke instanceof String) {
processName = (String) invoke;
}
} catch (Throwable e) {
}
return processName;
}
}
四、将三种方法结合得到一个更优方案
于是我们将三个方法结合。
- 我们优先通过 Application.getProcessName() 方法获取进程名。
- 如果获取失败,我们再反射ActivityThread.currentProcessName()获取进程名
- 如果失败,我们才通过常规方法ActivityManager来获取进程名
如下代码:
public class ProcessUtil {
private static String currentProcessName;
/**
- @return 当前进程名
*/
@Nullable
public static String getCurrentProcessName(@NonNull Context context) {
if (!TextUtils.isEmpty(currentProcessName)) {
return currentProcessName;
}
//1)通过Application的API获取当前进程名
currentProcessName = getCurrentProcessNameByApplication();
if (!TextUtils.isEmpty(currentProcessName)) {
return currentProcessName;
}
//2)通过反射ActivityThread获取当前进程名
currentProcessName = getCurrentProcessNameByActivityThread();
if (!TextUtils.isEmpty(currentProcessName)) {
return currentProcessName;
}
//3)通过ActivityManager获取当前进程名
currentProcessName = getCurrentProcessNameByActivityManager(context);
return currentProcessName;
}
/**
- 通过Application新的API获取进程名,无需反射,无需IPC,效率最高。
*/
public static String getCurrentProcessNameByApplication() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
return Application.getProcessName();
}
return null;
}
/**
- 通过反射ActivityThread获取进程名,避免了ipc
*/
public static String getCurrentProcessNameByActivityThread() {
String processName = null;
try {
final Method declaredMethod = Class.forName(“android.app.ActivityThread”, false, Application.class.getClassLoader())
.getDeclaredMethod(“currentProcessName”, (Class<?>[]) new Class[0]);
declaredMethod.setAccessible(true);
final Object invoke = declaredMethod.invoke(null, new Object[0]);
if (invoke instanceof String) {
processName = (String) invoke;
}
} catch (Throwable e) {
e.printStackTrace();
}
return processName;
}
/**
- 通过ActivityManager 获取进程名,需要IPC通信
*/
public static String getCurrentProcessNameByActivityManager(@NonNull Context context) {
if (context == null) {
return null;
}
int pid = Process.myPid();
ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
if (am != null) {
List<ActivityManager.RunningAppProcessInfo> runningAppList = am.getRunningAppProcesses();
if (runningAppList != null) {
for (ActivityManager.RunningAppProcessInfo processInfo : runningAppList) {
if (processInfo.pid == pid) {
return processInfo.processName;
}
}
}
}
return null;
}
}
五、简单的测试下性能
大叔做了个简单的测试,测试下三种方法调用需要的时长:
在模拟器上做的测试,模拟器配置如下:
测试代码如下:
private fun testGetCurrentProcessNameByApplication(){
val beginTime = SystemClock.elapsedRealtimeNanos()
ProcessUtil.getCurrentProcessNameByApplication()
Log.i(TG, “getCurrentProcessNameByApplication duration=${SystemClock.elapsedRealtimeNanos() - beginTime}”)
}
private fun testGetCurrentProcessNameByActivityThread(){
val beginTime = SystemClock.elapsedRealtimeNanos()
ProcessUtil.getCurrentProcessNameByActivityThread()
Log.i(TG, “getCurrentProcessNameByActivityThread duration=${SystemClock.elapsedRealtimeNanos() - beginTime}”)
最后
那我们该怎么做才能做到年薪60万+呢,对于程序员来说,只有不断学习,不断提升自己的实力。我之前有篇文章提到过,感兴趣的可以看看,到底要学习哪些知识才能达到年薪60万+。
通过职友集数据可以查看,以北京 Android 相关岗位为例,其中 【20k-30k】 薪酬的 Android 工程师,占到了整体从业者的 30.8%!
北京 Android 工程师「工资收入水平 」
今天重点内容是怎么去学,怎么提高自己的技术。
1.合理安排时间
2.找对好的系统的学习资料
3.有老师带,可以随时解决问题
4.有明确的学习路线
当然图中有什么需要补充的或者是需要改善的,可以在评论区写下来,一起交流学习。
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
需要这份系统化的资料的朋友,可以添加V获取:vip204888 (备注Android)
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
4461918)]
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
需要这份系统化的资料的朋友,可以添加V获取:vip204888 (备注Android)
[外链图片转存中…(img-zoObyWNC-1713394461918)]
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!