目录
- 前言
- 正文
- MediaController.java
- MediaBrowser.java
- MediaBrowser.java
- MediaBrowserService.java
- MediaSession.java
- MediaSessionManager.java
- MediaSessionService.java
- MediaSessionRecord.java
- 小结1
- MediaSessionRecord.java
- MediaSession.java
- CallbackStub
- CallbackStub.onNext()
- dispatchNext()
- CallbackMessageHandler.handleMessage()
- CallbackMessageHandler
- setCallback(2)
- setCallback(1)
- 小结2
- 参考文章
前言
简单记录一下MediaController中skipToNext()源码分析,这里只是简单记录下一下,走个流程吧。记录于此,方便自己查阅。
mMediaController.getTransportControls().skipToNext();
流水账,勿喷!
正文
对于的使用,可以看参考文二。之前有简单记录一下,下面只是附上相关的代码片段。
mMediaController = new MediaController(MainActivity.this, mMediaBrowser.getSessionToken()); mMediaController.getTransportControls().skipToNext();
一上面代码为例,进行源码跟踪。
MediaController.java
frameworks\base\media\java\android\media\session\MediaController.java
MediaController()
public MediaController(@NonNull Context context, @NonNull MediaSession.Token token) { if (context == null) { throw new IllegalArgumentException("context shouldn't be null"); } if (token == null) { throw new IllegalArgumentException("token shouldn't be null"); } if (token.getBinder() == null) { throw new IllegalArgumentException("token.getBinder() shouldn't be null"); } //获取的是token中的Binder对象 mSessionBinder = token.getBinder(); //创建TransportControls对象 mTransportControls = new TransportControls(); mToken = token; mContext = context; }
TransportControls是内部类,里面主要封装了一下方法,skipToNext()等
getTransportControls()
public @NonNull TransportControls getTransportControls() { return mTransportControls; }
TransportControls.skipToNext()
public void skipToNext() { try { mSessionBinder.next(mContext.getPackageName()); } catch (RemoteException e) { Log.wtf(TAG, "Error calling next.", e); } }
这里的mSessionBinder就是MediaController构造函数中初始化的。
//通过MediaSession.Token的对象获取的 mSessionBinder = token.getBinder();
我们创建MediaController对象时传入的是mMediaBrowser.getSessionToken()。
下面跟一下,但先说结果。
mSessionBinder为MediaSessionRecord中的ControllerStub对象
MediaBrowser.java
\frameworks\base\media\java\android\media\browse\MediaBrowser.java
这里关注mMediaBrowser.getSessionToken()返回的是啥。
getSessionToken()
public @NonNull MediaSession.Token getSessionToken() { if (!isConnected()) { throw new IllegalStateException("getSessionToken() called while not connected (state=" + mState + ")"); } return mMediaSessionToken; }
onServiceConnected()中给mMediaSessionToken赋值的。
onServiceConnected()
private void onServiceConnected(final IMediaBrowserServiceCallbacks callback, final String root, final MediaSession.Token session, final Bundle extra) { mHandler.post(new Runnable() { @Override public void run() { if (!isCurrent(callback, "onConnect")) { return; } if (mState != CONNECT_STATE_CONNECTING) { Log.w(TAG, "onConnect from service while mState=" + getStateLabel(mState) + "... ignoring"); return; } mRootId = root; //这里赋值的, mMediaSessionToken = session; mExtras = extra; mState = CONNECT_STATE_CONNECTED; mCallback.onConnected(); //略 } }); }
而onServiceConnected()是在MediaBrowser.java中静态内部类ServiceCallbacks的onConnect()中调用的。
ServiceCallbacks
private static class ServiceCallbacks extends IMediaBrowserServiceCallbacks.Stub { private WeakReference<MediaBrowser> mMediaBrowser; ServiceCallbacks(MediaBrowser mediaBrowser) { mMediaBrowser = new WeakReference<MediaBrowser>(mediaBrowser); } //略 }
这里重点关注onConnect()
onConnect()
private static class ServiceCallbacks extends IMediaBrowserServiceCallbacks.Stub { private WeakReference<MediaBrowser> mMediaBrowser; ServiceCallbacks(MediaBrowser mediaBrowser) { mMediaBrowser = new WeakReference<MediaBrowser>(mediaBrowser); } @Override public void onConnect(String root, MediaSession.Token session, final Bundle extras) { MediaBrowser mediaBrowser = mMediaBrowser.get(); Log.d(TAG,"onConnect 1 mediaBrowser: "+ mediaBrowser); if (mediaBrowser != null) { mediaBrowser.onServiceConnected(this, root, session, extras); } } @Override public void onConnectFailed() { MediaBrowser mediaBrowser = mMediaBrowser.get(); if (mediaBrowser != null) { mediaBrowser.onConnectionFailed(this); } } //略 }
也就是上面的MediaSession.Token的变量session是从这里传入的,至于哪里传入的,就要看调用方法的地方了。
提前预告一下。ServiceCallbacks对象创建是在MediaServiceConnection.onServiceConnected()中,并传入到mServiceBinder的connect()中。
mServiceConnection = new MediaServiceConnection(); mServiceBinder.connect(mContext.getPackageName(), mRootHints, mServiceCallbacks);后面会介绍到的。
下面先看MediaBrowser的connect()了。
MediaBrowser.java
下面是MediaBrowser对象创建和连接的代码。
小结2
比较绕的,尤其重点关注参数的传入,到处都是回调参数。我只是走过过程,也不太会总结。
大部分时没必要这样纠结看,只要抓住重点就行。
对于MediaSession相关问题,主要涉及MediaSession,MediaSessionRecord,MediaSessionManager,MediaBrowserService这几个即可。
上面跟源码的比较随意,看到参数后才去看的
参考文章
《Android源码》
《