前言

简单记录一下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对象创建和连接的代码。

隐藏内容!
付费阅读后才能查看!
1
2
多个隐藏块只需支付一次

小结2

比较绕的,尤其重点关注参数的传入,到处都是回调参数。我只是走过过程,也不太会总结。

大部分时没必要这样纠结看,只要抓住重点就行。

对于MediaSession相关问题,主要涉及MediaSession,MediaSessionRecord,MediaSessionManager,MediaBrowserService这几个即可。

上面跟源码的比较随意,看到参数后才去看的

参考文章

  1. 《Android源码》

  2. MediaSession的简单使用

相关文章

暂无评论

none
暂无评论...