成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

ANdroid O MeidiaPlayer 深入理解(一)

chaos_G / 1064人閱讀

摘要:其中和最終都會(huì)在層調(diào)用到將音頻流寫入到對(duì)應(yīng)上。關(guān)于和的區(qū)別,這里就不細(xì)說(shuō)了,百度一大堆。繼續(xù)將創(chuàng)建的層的對(duì)象保存到層。最后感謝百度各位大師提供資料。

前言

android對(duì)于java層的音頻播放器提供了很多api,主要的有 AudioTrack、SoundPool、MediaPlayer(其實(shí)AudioPlayer和MediaPlayerAdapter也都是加了AudioFcus后對(duì)于MediaPlayer的二次封裝,關(guān)于AudioFocus有時(shí)間再詳細(xì)介紹)。
其中AudioTrack主要是播放pcm流,而soundPool主要播放一些短暫的聲音,比如touch音。MediaPlayer主要播放媒體音頻文件像.mp3文件等。其中SoundPool和MediaPlayer最終都會(huì)在native層調(diào)用到audioTrack將音頻流寫入到對(duì)應(yīng)devices上。
關(guān)于MediaPlayer和AudioTrack的區(qū)別,這里就不細(xì)說(shuō)了,百度一大堆。主要就是MediaPlayer會(huì)把.mp3等格式文件最終解析成pcm流輸出給audiotrack。關(guān)于MediaPlayer的Java層的各狀態(tài)轉(zhuǎn)化和各方法調(diào)用說(shuō)明,這里也不一一細(xì)說(shuō)了。度娘全是這玩意。
這里主要說(shuō)說(shuō)MediaPlayer關(guān)于native層的東東(本人java出生,對(duì)于c/c++等了解的難免疏漏,如有理解錯(cuò)誤,望各位大神不吝賜教,定虛心改正)。

MediaPlayer初始化

給大家提供一個(gè)免費(fèi)看源碼的網(wǎng)站(知道請(qǐng)略過(guò))http://androidxref.com/
言歸正傳,就從java層的MediaPlayer說(shuō)起吧。

構(gòu)造方法

MediaPlayer位于frameworks/base/media/java/android/media/下繼承PlayerBase。
其中PlayerBase的構(gòu)造方法如下:

    PlayerBase(@NonNull AudioAttributes attr, int implType) {
        if (attr == null) {
            throw new IllegalArgumentException("Illegal null AudioAttributes");
        }
        mAttributes = attr;
       mImplType = implType;
        mState = AudioPlaybackConfiguration.PLAYER_STATE_IDLE;
   };

MediaPlayer的構(gòu)造方法:

  public MediaPlayer() {
        super(new AudioAttributes.Builder().build(),
                AudioPlaybackConfiguration.PLAYER_TYPE_JAM_MEDIAPLAYER);

        Looper looper;
        if ((looper = Looper.myLooper()) != null) {
            mEventHandler = new EventHandler(this, looper);
        } else if ((looper = Looper.getMainLooper()) != null) {
            mEventHandler = new EventHandler(this, looper);
        } else {
            mEventHandler = null;
        }

        mTimeProvider = new TimeProvider(this);
        mOpenSubtitleSources = new Vector();

        /* Native setup requires a weak reference to our object.
         * It"s easier to create it here than in C++.
         */
        native_setup(new WeakReference(this));

        baseRegisterPlayer();
    }

可以看我們?cè)谑褂脮r(shí)MediaPlayer時(shí),通過(guò)new MediaPlayer的方式到實(shí)際都做了什么,著重關(guān)注下這幾個(gè)點(diǎn)
1.new AudioAttributes.Builder()//這個(gè)主要后面的audioPolicy會(huì)用到。
2.native_setup
3.baseRegisterPlayer注冊(cè)了一個(gè)player狀態(tài)回調(diào),這塊邏輯,感興趣的可以自己查下源碼,暫忽略掉,有時(shí)間細(xì)看再補(bǔ)上這塊吧,今天重點(diǎn)不是他。
重點(diǎn)說(shuō)2.native_setup,這步直接調(diào)用了jni方法,關(guān)于jni我了解不是很多,我主要做從事App開發(fā)的,底層的東東只能略知一二,說(shuō)的不對(duì)的,請(qǐng)多多指教。

 private native final void native_setup(Object mediaplayer_this);

jni的加載主要通過(guò) System.loadLibrary來(lái)實(shí)現(xiàn)的:

    static {
        System.loadLibrary("media_jni");
        native_init();
    }

在/frameworks/base/media/jni/android_media_MediaPlayer.cpp目錄下,這樣就走到了C++部分。
通過(guò)JNINativeMethod gMethods[]方法知道native_setup會(huì)調(diào)到android_media_MediaPlayer_native_setup方法。

    {"native_setup",        "(Ljava/lang/Object;)V",            (void *)android_media_MediaPlayer_native_setup},

其中:

static void
android_media_MediaPlayer_native_setup(JNIEnv *env, jobject thiz, jobject weak_this)
{
    ALOGV("native_setup");
    sp mp = new MediaPlayer();
    if (mp == NULL) {
        jniThrowException(env, "java/lang/RuntimeException", "Out of memory");
        return;
    }

    // create new listener and give it to MediaPlayer
    sp listener = new JNIMediaPlayerListener(env, thiz, weak_this);
    mp->setListener(listener);

    // Stow our new C++ MediaPlayer in an opaque field in the Java object.
    setMediaPlayer(env, thiz, mp);
}

Ok分析下sp mp = new MediaPlayer(); native層的mediaplayer也有了,創(chuàng)建了一個(gè)C++的mediaPlayer對(duì)象。
繼續(xù):setMediaPlayer(env, thiz, mp)將創(chuàng)建的Native層的MediaPlayer對(duì)象保存到Java層。也就是說(shuō)將來(lái)我們通過(guò)getMediaplayer()的時(shí)候獲取到的就是這個(gè)對(duì)象。

總結(jié)

到此MediaPlayer就創(chuàng)建完成了,通過(guò)java代碼 new MediaPlayer()開始,一直到native層創(chuàng)建native層的MediaPlayer,并將native層的MediaPlayer返回到j(luò)ava層,供java層調(diào)用。
其實(shí)整個(gè)MediaPlayer在運(yùn)行的時(shí)候,可以大致上分成Client和Server兩個(gè)部分,它們分別在兩個(gè)進(jìn)程中運(yùn)行,它們之間使用Binder機(jī)制實(shí)現(xiàn)IPC通訊,但Client端分一個(gè)在java層的MediaPlayer和native層的MediaPlayer。
最后感謝百度各位大師提供資料。

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/77219.html

相關(guān)文章

  • 好文章必讀 - 收藏集 - 掘金

    摘要:方法即為收集器,它接收高階函數(shù)和的后端掘金年的第一天,我坐在獨(dú)墅湖邊,寫下這篇文章。正因如此,所以最全系列教程后端掘金是從版本開始引入的一個(gè)新的,可以替代標(biāo)準(zhǔn)的。 設(shè)計(jì)模式之單例模式 - 掘金前言 作為一個(gè)好學(xué)習(xí)的程序開發(fā)者,應(yīng)該會(huì)去學(xué)習(xí)優(yōu)秀的開源框架,當(dāng)然學(xué)習(xí)的過(guò)程中不免會(huì)去閱讀源碼,這也是一個(gè)優(yōu)秀程序員的必備素養(yǎng),在學(xué)習(xí)的過(guò)程中很多人會(huì)遇到的障礙,那就是設(shè)計(jì)模式。很多優(yōu)秀的框架會(huì)運(yùn)...

    FrozenMap 評(píng)論0 收藏0
  • SegmentFault 技術(shù)周刊 Vol.22 - 進(jìn)擊的 Google I/O 2017

    摘要:谷歌表示,與搜索并列,是谷歌機(jī)器學(xué)習(xí)技術(shù)最重要的產(chǎn)品服務(wù)載體。谷歌宣布了基于機(jī)器學(xué)習(xí)技術(shù)的全面升級(jí),很可能是其誕生以來(lái)的最大升級(jí)。在去年的大會(huì)上,谷歌宣布了其第一代。 showImg(https://segmentfault.com/img/bVNTKT?w=900&h=385); Google I/O Google I/O 是由 Google 舉行的網(wǎng)絡(luò)開發(fā)者年會(huì),討論的焦點(diǎn)是用 G...

    darkbaby123 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<