android媒體架構之圖庫行為

來源:互聯網
上載者:User

建議用用在裝置休眠的時候第三方視頻播放器主動調用VideoView.suspend()方法

我們很多第三方播放器應用在休眠喚醒的時候處理的不是很棒,造成很多平台不能很好的相容,最進在公司就處理過此類問題。

預設情況下,當我們點擊power鍵的時候,我們用戶端播放器會和服務端中斷連線,此時服務端的Client會析構,當再次返回時會重新喚醒時服務端會重新建立服務端,讀取上次儲存的位置,開始播放或者待使用者確認後開始播放,這樣做會節約功耗,你不希望使用者用你產品後本來可以撐一天的手機,現在只能用半天了吧~

廢話少說,直接把圖庫的行為給大家看下:

 

SEP 1 .MovieActivity

 

    @Override    public void onPause() {        mPlayer.onPause();        super.onPause();    }

當點擊power鍵的時候,會調用movieActitivy的onPause方法

 

SEP 2. MoviePlayer

 

    public void onPause() {        mHasPaused = true;        mHandler.removeCallbacksAndMessages(null);        mVideoPosition = mVideoView.getCurrentPosition();        mBookmarker.setBookmark(mUri, mVideoPosition, mVideoView.getDuration());        mVideoView.suspend();        mResumeableTime = System.currentTimeMillis() + RESUMEABLE_TIMEOUT;    }

儲存狀態,儲存為書籤,調用VideoView的掛起方法,其真正調用的是VideoView的release方法

 

SEP 3 .ViewoView

 

    /*     * release the media player in any state     */    private void release(boolean cleartargetstate) {        if (mMediaPlayer != null) {            mMediaPlayer.reset();            mMediaPlayer.release();            mMediaPlayer = null;            mCurrentState = STATE_IDLE;            if (cleartargetstate) {                mTargetState  = STATE_IDLE;            }        }    }

 

SEP4.MediaPlay.java

 

 public void release() {        stayAwake(false);        updateSurfaceScreenOn();        mOnPreparedListener = null;        mOnBufferingUpdateListener = null;        mOnCompletionListener = null;        mOnSeekCompleteListener = null;        mOnErrorListener = null;        mOnInfoListener = null;        mOnVideoSizeChangedListener = null;        mOnTimedTextListener = null;        _release();    }    private native void _release();...  ...public void reset() {        stayAwake(false);        _reset();        // make sure none of the listeners get called anymore        mEventHandler.removeCallbacksAndMessages(null);    }    private native void _reset();

先說reset:

 

SEP5.android_media_MediaPlayer.cpp

 

// If exception is NULL and opStatus is not OK, this method sends an error// event to the client application; otherwise, if exception is not NULL and// opStatus is not OK, this method throws the given exception to the client// application.static void process_media_player_call(JNIEnv *env, jobject thiz, status_t opStatus, const char* exception, const char *message){    if (exception == NULL) {  // Don't throw exception. Instead, send an event.        if (opStatus != (status_t) OK) {            sp<MediaPlayer> mp = getMediaPlayer(env, thiz);            if (mp != 0) mp->notify(MEDIA_ERROR, opStatus, 0);        }    } else {  // Throw exception!        if ( opStatus == (status_t) INVALID_OPERATION ) {            jniThrowException(env, "java/lang/IllegalStateException", NULL);        } else if ( opStatus == (status_t) PERMISSION_DENIED ) {            jniThrowException(env, "java/lang/SecurityException", NULL);        } else if ( opStatus != (status_t) OK ) {            if (strlen(message) > 230) {               // if the message is too long, don't bother displaying the status code               jniThrowException( env, exception, message);            } else {               char msg[256];                // append the status code to the message               sprintf(msg, "%s: status=0x%X", message, opStatus);               jniThrowException( env, exception, msg);            }        }    }}

 

SEP6.MediaPlayer.cpp

void MediaPlayer::notify(int msg, int ext1, int ext2, const Parcel *obj){... ...// Allows calls from JNI in idle state to notify errors    if (!(msg == MEDIA_ERROR && mCurrentState == MEDIA_PLAYER_IDLE) && mPlayer == 0) {        ALOGV("notify(%d, %d, %d) callback on disconnected mediaplayer", msg, ext1, ext2);        if (locked) mLock.unlock();   // release the lock when done.        return;    }... ...}

 

再回頭看,release

 

SEP7.android_media_MediaPlayer.cpp

 

static voidandroid_media_MediaPlayer_release(JNIEnv *env, jobject thiz){    ALOGV("release");    decVideoSurfaceRef(env, thiz);    sp<MediaPlayer> mp = setMediaPlayer(env, thiz, 0);    if (mp != NULL) {        // this prevents native callbacks after the object is released        mp->setListener(0);        mp->disconnect();    }}

SEP8.MediaPlayer.cpp

 

void MediaPlayer::disconnect(){    ALOGV("disconnect");    sp<IMediaPlayer> p;    {        Mutex::Autolock _l(mLock);        p = mPlayer;        mPlayer.clear();    }    if (p != 0) {        p->disconnect();    }}

這裡的IMediaPlayer的指標指向的就是MdiaPlayerService::Client;智能指標clear就會調用其解構函式,然後斷開與服務端的串連

 

SEP9.MediaPlayerService.cpp

MediaPlayerService::Client::~Client(){    ALOGV("Client(%d) destructor pid = %d", mConnId, mPid);    mAudioOutput.clear();    wp<Client> client(this);    disconnect();    mService->removeClient(client);}void MediaPlayerService::Client::disconnect(){    ALOGV("disconnect(%d) from pid %d", mConnId, mPid);    // grab local reference and clear main reference to prevent future    // access to object    sp<MediaPlayerBase> p;    {        Mutex::Autolock l(mLock);        p = mPlayer;    }    mClient.clear();    mPlayer.clear();    // clear the notification to prevent callbacks to dead client    // and reset the player. We assume the player will serialize    // access to itself if necessary.    if (p != 0) {        p->setNotifyCallback(0, 0);#if CALLBACK_ANTAGONIZER        ALOGD("kill Antagonizer");        mAntagonizer->kill();#endif        p->reset();    }    disconnectNativeWindow();    IPCThreadState::self()->flushCommands();}

關閉和服務端的串連流程基本就是這樣的。返迴流程後續補上。

 

 

 

 

 

 

 

 

 

 

 

 

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.