总结
最后为了帮助大家深刻理解Android相关知识点的原理以及面试相关知识,这里放上相关的我搜集整理的24套腾讯、字节跳动、阿里、百度2019-2021面试真题解析,我把技术点整理成了视频和PDF(实际上比预期多花了不少精力),包知识脉络 + 诸多细节。
还有 高级架构技术进阶脑图、Android开发面试专题资料 帮助大家学习提升进阶,也节省大家在网上搜索资料的时间来学习,也可以分享给身边好友一起学习。
网上学习 Android的资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。希望这份系统化的技术体系对大家有一个方向参考。
2021年虽然路途坎坷,都在说Android要没落,但是,不要慌,做自己的计划,学自己的习,竞争无处不在,每个行业都是如此。相信自己,没有做不到的,只有想不到的。祝大家2021年万事大吉。
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
MediaPlaybackService的初始化
public class MediaPlaybackService extends MediaBrowserServiceCompat {
@Override
public void onCreate() {
super.onCreate();
// 1. 初始化 MediaSession
mSession = new MediaSessionCompat(this, “MusicService”);
// 2. 设置 MedisSessionCallback
mSession.setCallback(mSessionCallback);
// 3. 开启 MediaButton 和 TransportControls 的支持
mSession.setFlags(MediaSessionCompat.FLAG_HANDLES_MEDIA_BUTTONS |
MediaSessionCompat.FLAG_HANDLES_TRANSPORT_CONTROLS);
// 4. 初始化 PlaybackState
mStateBuilder = new PlaybackStateCompat.Builder()
.setActions(
PlaybackStateCompat.ACTION_PLAY | PlaybackStateCompat.ACTION_PLAY_PAUSE);
mSession.setPlaybackState(mStateBuilder.build());
// 5. 关联 SessionToken
setSessionToken(mSession.getSessionToken());
}
}
根据包名做权限判断之后,返回根路径
@Override
public BrowserRoot onGetRoot(String clientPackageName, int clientUid, Bundle rootHints) {
// 根据包名对每个访问端做一些访问权限判断等
}
用来根据mediaID来返回第三放App所需要获得媒体数据
@Override
public void onLoadChildren(final String parentMediaId,
final Result<List> result) {
// 根据parentMediaId返回播放列表相关信息
}
客户端连接
private void initMediaBrowser() {
//1.待连接的服务
ComponentName componentName = new ComponentName(“com.example.android.uamp”,“com.example.android.uamp.MusicService”);
//2.创建MediaBrowser
mMediaBrowser = new MediaBrowserCompat(this, componentName, mConnectionCallbacks, null);
//3.建立连接
mMediaBrowser.connect();
}
设置相应的callback,连接Callback,数据变化Callback
连接状态同步
数据变化Callback设置
private final MediaBrowserCompat.ConnectionCallback mConnectionCallbacks =
new MediaBrowserCompat.ConnectionCallback() {
@Override
public void onConnected() {
//连接成功回调
}
@Override
public void onConnectionSuspended() {
//连接中断回调
}
@Override
public void onConnectionFailed() {
//连接失败回调
}
};
MediaControllerCompat.Callback controllerCallback =
new MediaControllerCompat.Callback() {
public void onSessionDestroyed() {
//Session销毁
}
@Override
public void onRepeatModeChanged(int repeatMode) {
//循环模式发生变化
}
@Override
public void onShuffleModeChanged(int shuffleMode) {
//随机模式发生变化
}
@Override
public void onMetadataChanged(MediaMetadataCompat metadata) {
//数据变化
}
@Override
public void onPlaybackStateChanged(PlaybackStateCompat state) {
//播放状态变化
}
};
客户端与服务端数据交互
MediaBrowser通过调用subscribe,会回调到MediaService的onLoadChildren,在这里做一个判断然后构造相应的列表将列表数据返回。返回数据之后。
- 根据MediaID获取数据
客户端通过调用subscribe方法,传递MediaID,在SubscriptionCallback的方法中进行处理。
mMediaBrowser.subscribe(“ID”, new MediaBrowserCompat.SubscriptionCallback() {
@Override
public void onChildrenLoaded(@NonNull String parentId, @NonNull List<MediaBrowserCompat.MediaItem> children) {
//children 为来自Service的列表数据
}
});
服务端和客户端之间传递的数据为MediaItem列表。MediaItem中具备的字段:MediaId,Title,SubTitle,Description,Icon,IconUri,MediaUri等字段。通过其可以帮助我们携带一些数据来进行歌曲的展示和播放。
@Override
public void onLoadChildren(@NonNull final String parentMediaId,
@NonNull final Result<List> result) {
List items = new ArrayList<>();
//根据MediaID做数据填充
switch (parentMediaId) {
case:
default: break;
}
result.sendResult(items);
}
- 发送自定义数据获取内容
客户端通过调用sendCustomAction,根据与服务端的协商,制定相应的action类型,进行数据的传递交互。
mMediaBrowser.sendCustomAction(action, extras, new MediaBrowserCompat.CustomActionCallback() {
@Override
public void onProgressUpdate(String action, Bundle extras, Bundle data) {
super.onProgressUpdate(action, extras, data);
}
@Override
public void onResult(String action, Bundle extras, Bundle resultData) {
super.onResult(action, extras, resultData);
}
@Override
public void onError(String action, Bundle extras, Bundle data) {
super.onError(action, extras, data);
}
});
服务端实现onCustomAction,根据action类型返回相应的数据
@Override
public void onCustomAction(@NonNull String action, Bundle extras, @NonNull Result result) {
//分支判断
if (GET_LIST.equals(action)) {
Bundle bundle = new Bundle();
ArrayList list = new ArrayList<>();
//填充数据
bundle.putStringArrayList(LIST_NAMES, list);
result.sendResult(bundle);
}
}
播放控制
- 客户端
客户端通过getMediaController getTransportControls()来进行播放,暂停,上一首,下一首的控制。
文末
不管怎么样,不论是什么样的大小面试,要想不被面试官虐的不要不要的,只有刷爆面试题题做好全面的准备,当然除了这个还需要在平时把自己的基础打扎实,这样不论面试官怎么样一个知识点里往死里凿,你也能应付如流啊
小编将自己6年以来的面试经验和学习笔记都整理成了一个**937页的PDF,**以及我学习进阶过程中看过的一些优质视频教程。
其实看到身边很多朋友抱怨自己的工资很低,包括笔者也是一样的,其原因是在面试过程中没有给面试官一个很好的答案。所以笔者会持续更新面试过程中遇到的问题,也希望大家和笔者一起进步,一起学习。
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
望大家和笔者一起进步,一起学习。
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!