Android进阶资料
以下的资料是近年来,我和一些朋友面试收集整理了很多大厂的面试真题和资料,还有来自如阿里、小米、爱奇艺等一线大厂的大牛整理的架构进阶资料。希望可以帮助到大家。
Android进阶核心笔记
百万年薪必刷面试题
最全Android进阶学习视频
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
//获取到mObservers的反射对象
Field mObserversField = liveDataClass.getDeclaredField(“mObservers”);
//让mObserversField可以被访问
mObserversField.setAccessible(true);
//获取到这个mObserversField的值
Object mObservers = mObserversField.get(this);
//获取到mObservers的get方法的反射对象
Method get = mObservers.getClass().getDeclaredMethod(“get”, Object.class);
//设置这个反射对象可以被访问
get.setAccessible(true);
//执行这个方法 得到Entry
Object invokeEntry = get.invoke(mObservers, observer);
//定义一个空的对象 LifecycleBoundObserver
Object observerWrapper = null;
if(invokeEntry!=null && invokeEntry instanceof Map.Entry){
observerWrapper = ((Map.Entry)invokeEntry).getValue();
}
if(observerWrapper == null){
throw new NullPointerException(“ObserverWrapper不能为空”);
}
//获取到ObserverWrapper的类对象
Class<?> superclass = observerWrapper.getClass().getSuperclass();
//获取搭配这个类中的mLastVersion成员变量
Field mLastVersionField = superclass.getDeclaredField(“mLastVersion”);
mLastVersionField.setAccessible(true);
//获取到mVersion的反射对象
Field mVersionField = liveDataClass.getDeclaredField(“mVersion”);
//打开权限
mVersionField.setAccessible(true);
//得到的就是mVersion在当前类中的值
Object o = mVersionField.get(this);
//把它的值给mLastVersion
mLastVersionField.set(observerWrapper,o);
}
}
}
这里面的代码是我在第一次听课的过程中一步一步写的,整体的思路并不是我想的,也可以说是学习了。上面的代码也都有注释,就不过多解释了,下面看怎么去用,首先通过通知栏控制Activity,也就是页面,下面我就都用页面二字代替Activity了。说白了其中的思路就是当我点击了通知栏上的某一个按钮的时候,服务会知道这个事情,因为之前注册了广播,但是页面怎么知道这个事情呢,所以其实就是要让服务去告诉页面,我当前点击了通知栏上某一个按钮。然后页面就去做出相应的操作,在这里服务是被观察者,而页面是观察者,所以我们可以在服务中安插一个卧底,让它告诉我们通知栏干了啥事。这么一想思路就很清晰了,下面来看具体的实现。
进入MusicService中,
/**
- 通知栏控制Activity页面UI
*/
private LiveDataBus.BusMutableLiveData activityLiveData;
创建对象,传入String就代表接收的也是String,这里你可以传递任何类型的数据。
然后要在onCreate进行实例化。
activityLiveData = LiveDataBus.getInstance().with(“activity_control”, String.class);
这样,卧底就安插好了,下面就是要告诉卧底什么时候要给页面传递消息了。
首先当然是播放了,注意上图中红色方框中的代码,postValue就是发送消息,PLAY是在Constant中定义的全局变量。就是告诉页面,我当前的音乐开始播放了。
当我点击通知的播放按钮时回调用这个方法,那么在这个方法里面首先控制了通知栏本身的按钮UI,于是我再加上对页面的控制,就是一举两得。
关闭通知栏的时候也要告诉页面,这个时候页面上的UI也要做出改变,
下一首和上一首都要通知页面,到这里该告诉页面的信息都说了,再说的话卧底可能就要暴露了,不太好吧。既然卧底的消息都发出去了,那么页面怎么做出相应的改变呢?进入MainActivity。
/**
- 当Service中通知栏有变化时接收到消息
*/
private LiveDataBus.BusMutableLiveData activityLiveData;
创建对象,然后在initData中调用notificationObserver方法对服务发送过来的消息进行处理。
notificationObserver的代码如下:
/**
- 通知栏动作观察者
*/
private void notificationObserver() {
activityLiveData = LiveDataBus.getInstance().with(“activity_control”, String.class);
activityLiveData.observe(MainActivity.this, true, new Observer() {
@Override
public void onChanged(String state) {
switch (state) {
case PLAY:
btnPlay.setIcon(getDrawable(R.mipmap.icon_pause));
btnPlay.setIconTint(getColorStateList(R.color.gold_color));
changeUI(musicService.getPlayPosition());
break;
case PAUSE:
case CLOSE:
btnPlay.setIcon(getDrawable(R.mipmap.icon_play));
btnPlay.setIconTint(getColorStateList(R.color.white));
changeUI(musicService.getPlayPosition());
break;
case PREV:
BLog.d(TAG, “上一曲”);
changeUI(musicService.getPlayPosition());
break;
case NEXT:
BLog.d(TAG, “下一曲”);
changeUI(musicService.getPlayPosition());
break;
default:
break;
}
}
});
}
在上面我通过在服务中安插卧底得知通知栏的一些机密信息,那么通知栏也不是省油的灯,也可以安插卧底在Activity中,得知页面的信息,然后更好的伪装自己。再次之前,首先要添加一个依赖。打开app下的build.gradle,在dependencies闭包中添加如下依赖库,然后Sync
//Service中使用lifecycle
implementation “androidx.lifecycle:lifecycle-service:2.2.0”
到这一步就先不管这个了。还是在MainActivity中,
/**
- 当在Activity中做出播放状态的改变时,通知做出相应改变
*/
private LiveDataBus.BusMutableLiveData notificationLiveData;
然后在initData中,增加一个notification_control的标识key
目前我只是通过MainActivity的底部播放按钮开始播放音乐,这个时候时候通知栏有变化,但是如果这时再点击一次按钮,就是暂停了,而不是重新播放,暂停后再点就是继续播放。所以要在底部按钮的点击事件中,发送一个消息过去。
下面进入到MusicService。
/**
- Activity控制通知栏UI
*/
private LiveDataBus.BusMutableLiveData notificationLiveData;
然后在MusicService的onCreate方法中调用activityObserver方法
再写这个方法之前,先修改一些MusicService继承的Service,改成LifecycleService,如果你没有这个类就说明你的依赖库没有加进来。
然后
下面写这个activityObserver方法,代码如下:
/**
- Activity的观察者
*/
private void activityObserver() {
notificationLiveData = LiveDataBus.getInstance().with(“notification_control”, String.class);
notificationLiveData.observe(MusicService.this, new Observer() {
@Override
public void onChanged(String state) {
//UI控制
UIControl(state, TAG);
}
});
}
也是比较的简单因为它和通知栏相应时传递的值是一样的,所以可以复用UIControl方法,这样环节就走通过了。
很明显,无论是通过页面操作通知栏还是通知栏操作页面,都搞定了。
这个播放进度相信不会陌生,因为之前在LocalMusicActivity中时就已经实现了这个通过,不过当时是只在当前的的Activity中实现的,现在是要获取到后台播放音乐的MediaPlayer的当前播放音乐的进度,所以有些不同,还记得当时安插的卧底吗,可以再给它一个任务,让它在进度变化时发送一个消息给页面,这样就可以了。那么怎么来做呢?可以把之前在LocalMusicActivity中的两个方法复制到MusicService中,然后再稍加改动即可。
private Handler mHandler = new Handler(new Handler.Callback() {
@Override
public boolean handleMessage(Message message) {
//进度发生改变时,
activityLiveData.postValue(PROGRESS);
//更新进度
updateProgress();
return true;
}
});
/**
- 更新进度
*/
private void updateProgress() {
// 使用Handler每间隔1s发送一次空消息,通知进度条更新
// 获取一个现成的消息
Message msg = Message.obtain();
// 使用MediaPlayer获取当前播放时间除以总时间的进度
int progress = mediaPlayer.getCurrentPosition();
msg.arg1 = progress;
mHandler.sendMessageDelayed(msg, INTERNAL_TIME);
}
最后
其实Android开发的知识点就那么多,面试问来问去还是那么点东西。所以面试没有其他的诀窍,只看你对这些知识点准备的充分程度。so,出去面试时先看看自己复习到了哪个阶段就好。
上面分享的百度、腾讯、网易、字节跳动、阿里等公司2021年的高频面试题,博主还把这些技术点整理成了视频和PDF(实际上比预期多花了不少精力),包含知识脉络 + 诸多细节,由于篇幅有限,上面只是以图片的形式给大家展示一部分。
【Android思维脑图(技能树)】
知识不体系?这里还有整理出来的Android进阶学习的思维脑图,给大家参考一个方向。
【Android高级架构视频学习资源】
**Android部分精讲视频领取学习后更加是如虎添翼!**进军BATJ大厂等(备战)!现在都说互联网寒冬,其实无非就是你上错了车,且穿的少(技能),要是你上对车,自身技术能力够强,公司换掉的代价大,怎么可能会被裁掉,都是淘汰末端的业务Curd而已!现如今市场上初级程序员泛滥,这套教程针对Android开发工程师1-6年的人员、正处于瓶颈期,想要年后突破自己涨薪的,进阶Android中高级、架构师对你更是如鱼得水,赶快领取吧!
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
【Android高级架构视频学习资源】
**Android部分精讲视频领取学习后更加是如虎添翼!**进军BATJ大厂等(备战)!现在都说互联网寒冬,其实无非就是你上错了车,且穿的少(技能),要是你上对车,自身技术能力够强,公司换掉的代价大,怎么可能会被裁掉,都是淘汰末端的业务Curd而已!现如今市场上初级程序员泛滥,这套教程针对Android开发工程师1-6年的人员、正处于瓶颈期,想要年后突破自己涨薪的,进阶Android中高级、架构师对你更是如鱼得水,赶快领取吧!
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!