Android之MediaPlayerService服务详解

原文:

Android开发之MediaPlayerService服务详解(一)


链接:http://www.cnblogs.com/pangblog/p/3243947.html

前面一节我们分析了Binder通信相关的两个重要类:ProcessState 和 IPCThreadState。ProcessState负责打开Binder
驱动,每个进程只有一个。而 IPCThreadState负责提供与Binder通信相关的接口,每个线程有一个。下面我们通过具体
示例MediaPlayerService来分析我们应用程序中怎么通过Binder通信的。


frameworks/base/media/mediaserver/main_mediaserver.cpp

int main(int argc, char*argv[])
{
	sp<ProcessState> proc(ProcessState)::self();	// 获得ProcessState在构造函数中打开binder驱动
	sp<IServiceManager> sm = defaultServiceManager();
	MediaPlayService::instantiate();
	ProcessState::self()->startThreadPool();
	IPCThreadState::self()->joinThreadPool();
}

1)获得ServiceManager的代理BpServiceManager

sp<IServiceManager> sm = defaultServiceManager();
sp<IServiceManager> defaultServiceManager()
{
	if(gDefaultServiceManager != NULL) return gDefaultServiceManager;
	{
		AutoMutex -l(gDefaultServiceManagerLock);
		if(gDefaultServiceManager == NULL)
			gDefaultServiceManager = interface_cast<IServiceManager>(
				ProcessState::self()->getContextObject(NULL));
	}
	return gDefaultServiceManager;
}

这里又是一个单例模式,每个进程只需要一个BpServiceManager代理,通过interface_cast获得。
首先看看ProcessState::self()->getContextObject(NULL)

sp<IBinder> ProcessState::getContextObject(const sp<IBinder>& caller)
{
	return getStrongProxyForHandle(0);
}

sp<IBinder> ProcessState::getStrongProxyForHandle(int32_t handle)	
{
	sp<IBinder> result;
	AutoMutex _l(mLock);
	handle_entry *e = lookupHandleLocked(handle);
	if( e != NULL) {
		IBinder* b = e->binder;
		if(b == NULL || !e->refs->attemptIncWeak(this)) {
			b = new BpBinder(handle);
			e->binder = b;
			if(b) e->refs = b->getWeakRefs();
			result = b;
		}else{
			result.force_set(b);
			e->refs->decWeak(this);
		}
	}
	return result;
}
struct handle_entry{
	IBinder* binder;
	RefBase::weakref_type* refs;
}

ProcessState::handle_entry* ProcessState::lookupHandleLocked()从数组mHandleToObject里面根据handle索引,查找
一个handle_entry结构体。然后根据传入的句柄handle这里为0,表示ServiceManager,new一个BpBinder
所以现在相当于:
gDefaultServiceManager = interface_cast<IServiceManager>(new BpBinder(0));

现在我们看看interface_cast是什么?

frameworks/base/include/binder/IInterface.h
template<typename INTERFACE>
inline sp<INTERFACE> interface_cast(const sp<IBinder>& obj)
{
	return INTERFACE::asInterface(obj);
}
等价于:
inline sp<IServiceManager> interface_cast(const sp<IBinder>& obj)
{
	return IServiceManager::asInterface(obj);
}
继续我们跟到IServiceManager里面去:
frameworks/base/include/binder/IServiceManager.h
class IServiceManager:public IInterface
{
public:
	DECLARE_META_INTERFACE(ServiceManager);// MLGB的又是宏!!!
	virtual status_t addService(const String16& name, const sp<IBinder>& service) = 0;
	virtual sp<IBinder> getService(const String16& name) const = 0;
}
#define DECLARE_META_INTERFACE(INTERFACE)				\
	static const android::String16 descriptor;			\
	static android::sp<I##INTERFACE> asInterface(			\
			const android::sp<android::IBinder>& obj);	\
	virtual const android::String16& getInterfaceDescriptor() const;\
	I##INTERFACE();							\
	virtual !I##INTERFACE();
替换之后就是:
	static const android::String16 descriptor;			
	static android::sp<IServiceManager> asInterface(			
			const android::sp<android::IBinder>& obj);	
	virtual const android::String16& getInterfaceDescriptor() const;
	IServiceManager();							
	virtual !IServiceManager();
都是一些函数声明,既然有声明的地方,肯定有实现的地方了。
#define IMPLEMENT_META_INTERFACE(INTERFACE, NAME)                       \
    const android::String16 I##INTERFACE::descriptor(NAME);             \
    const android::String16&                                            \
            I##INTERFACE::getInterfaceDescriptor() const {              \
        return I##INTERFACE::descriptor;                                \
    }                                                                   \
    android::sp<I##INTERFACE> I##INTERFACE::asInterface(                \
            const android::sp<android::IBinder>& obj)                   \
    {                                                                   \
        android::sp<I##INTERFACE> intr;                                 \
        if (obj != NULL) {                                              \
            intr = static_cast<I##INTERFACE*>(                          \
                obj->queryLocalInterface(                               \
                        I##INTERFACE::descriptor).get());               \
            if (intr == NULL) {                                         \
                intr = new Bp##INTERFACE(obj);                          \
            }                                                           \
        }                                                               \
        return intr;                                                    \
    }                                                                   \
    I##INTERFACE::I##INTERFACE() { }                                    \
    I##INTERFACE::~I##INTERFACE() { }                                   
继续替换:
{
    const android::String16 IServiceManager::descriptor(NAME);             
    const android::String16&                                            
           IServiceManager::getInterfaceDescriptor() const {              
        return IServiceManager::descriptor;                                
    }                                                                   
    android::sp<IServiceManager> IServiceManager::asInterface(                
            const android::sp<android::IBinder>& obj)   // 参数为new BpBinder(0)                
    {                                                                   
        android::sp<IServiceManager> intr;                                 
        if (obj != NULL) {                                              
            intr = static_cast<IServiceManager*>(                          
                obj->queryLocalInterface(                               
                        IServiceManager::descriptor).get());               
            if (intr == NULL) {                                         
                intr = new BpServiceManager(obj);     // 原来在这里new 了一个BpServiceManager对象                     
            }                                                           
        }                                                               
        return intr;                                                    
    }                                                                   
    IServiceManager::IServiceManager() { }                                    
    IServiceManager::~IServiceManager() { }                                   
}

总结:根据句柄handle 0 创建一个new BpBinder(0),根据这个BpBinder创建了一个BpServiceManager代理。

下面来看看BpServiceManager代理:

class BpServiceManager : public BpInterface<IServiceManager>
{
public:
	BpServiceManager(const sp<IBinder>& impl) : BpInterface<IServiceManager>(iml)
	{}
} 

这里BpInterface是一个模板类,表示这里BpServiceManager同时继承与BpInterface和IServiceManager类

template<typename INTERFACE>
class BpInterface : public INTERFACE, public BpRefBase
{
public: BpInterface(const sp<IBinder>& remote);
...
}
调用了基类BpInterface构造函数:
BpInterface<IServiceManager>::BpInterace(const sp<IBinder>& remote) : BpRefBase(remote)
{}
//这里的remote就是刚刚的new BpBinder(0)
BpRefBase::BpRefBase(const sp<IBinder>& o) : mRemote(o.get()),mRefs(NULL), mState(0)
{
}

 

2)添加服务 MediaPlayerService::instantiate();

frameworks/base/media/libmediaplayerservice/ibMediaPlayerService.cpp
void MediaPlayerService::instantiate()
{
	defaultServiceManager()->addService(String16("media.player"), new MediaPlayerService);
}

defaultServiceManager()返回的是刚创建的BpServiceManager,调用add函数。
BpMediaPlayService作为服务代理端,那么BnMediaPlayerService一定是实现端,MediaPlayerService继承于
BnMediaPlayerService,实现了真正的业务函数。

来看看BpServiceManager的addService()函数:

virtual status_t addService(const String16& name, const sp<IBinder>& service)
{
	Parcel data, reply;
	data.writeInterfaceToken(IServiceManager.getInterfaceDescriptor());	// android.os.IServiceManager
	data.writeString16(name);	// media.player
	data.writeStrongBinder(service);	// 也就是MediaPlayerService
	status_t err = remote()->transact(ADD_SERVICE_TRANSACTION, data, &reply);
	return err == NO_ERROR ? reply.readInt32() : err;
}

这里remote()就是前面创建的BpBinder(0)对象。

status_t BpBinder::transact(uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
{
	IPCThreadState::self()->transact(mHandle, code, data, reply, flags);
}
status_t IPCThreadState::transact(int32_t handle, uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
{
	// 发送ADD_SERVICE_TRANSACTION请求
	writeTransactionData(BC_TRANSACTION, flags, handle, code, data, NULL);
	if(reply)	// 等待响应
		waitForResponse(NULL, reply);
}

status_t IPCThreadState::writeTransactionData(int32_t cmd, uint32_t binderFlags, int32_t handle, 
		uint32_t code, const Parcel& data, status_t *statusBuffer)
{
	// cmd	BC_TRANSACTION	应用程序向BINDER发送的命令
	binder_transaction_data tr;
	tr.target.handle = handle;	// 0
	tr.code = code;			// ADD_SERVICE_TRANSACTION
	tr.flags = binderFlags;
	// 把命令和数据一起发送到 Parcel mOut中
	mOut.writeInt32(cmd);
	mOut.write(&tr, sizeof(tr));
}
status_t IPCThreadState::waitForResponse(Parcel* reply, status_t *acquireResult)
{
	int32_t cmd;
	
	while(1) 
		talkWithDriver();
		cmd = mIn.readInt32();
		switch(cmd) {
			case BR_TRANSACTION_COMPLETE:
				...
				break;
		}
	{
	return err;
}
status_t IPCThreadState::talkWithDriver(bool doReceive)
{
	binder_write_read bwr;
	
	bwr.write_size = outAvail;
	bwr.write_buf = (long unsigned int)mOut.data();	// 写入mOut的数据
	bwr.read_size = mIn.dataCapacity;
	bwr.read_buffer = (long unsigned int)mIn.data();
	ioctl(mProcess->mDriverFD, BINDER_WRITE_READm &bwr);	// 把mOut写到Binder,并读取mIn数据
}


 

3)IPCThreadState::joinThreadPool(), ProcessState::self()->startThreadPool()
进入线程循环talkWithDriver 等待客户端Client请求,从Binder读取命令请求进行处理。

 

到现在为止MediaPlayerService的服务端已经向服务总管ServiceManager注册了,下面我们看看客户端是如何获得服务的代理并和服务端通信的。
我们以MediaPlayer的业务函数decode解析播放一个URL为例

sp<IMemory> MediaPlayer::decode(const char*url, uint32_t *pSampleRate, ...)
{
	sp<IMemory> p;
	const sp<IMediaPlayerService>& service = getMediaPlayerService();	// 获得BpMediaPlayerSerivce代理
	if(service != 0)
		p = service->decode(url, ....);
	return p;
}

这里我们主要分析getMediaPlayerService,客户端是如何向ServiceManager总管查询服务并获得代理的。

sp<IMediaPlayerService>& IMediaDeathNotifier::getMediaPlayerService()
{
	sp<IServiceManager> sm = defaultServiceManager(); // 生成一个BpServiceManager代理对象
	sp<IBinder> binder;
	do {
		binder = sm->getService(String16("media.player"));
		if(binder != 0)
			break;
		usleep(500000)
	} while(true);
	sMediaPlayerService = interface_cast<IMediaPlayerService>(binder);
	return sMediaPlayerService;
}

 

1)首先获得BpServiceManager的代理,然后调用getService()函数向服务总管ServiceManager查询服务。
frameworks/base/libs/binder/IServiceManager.cpp

class BpServiceManager : public BpInterface<IServiceManager>
{
public:
	virtual sp<IBinder> getService(const String16& name) const
	{
		for(n = 0; n < 5; n++) {
			sp<IBinder> svc = checkService(name);	// 调用checkService函数
			if(svc != NULL) return svc;
			sleep(1);
		}
		return NULL;
	}
	virtual sp<IBinder> checkService(const String16& name) const 
	{
		Parcel data, reply;
		data.writeInterfaceToken(IServiceManager::getInterfaceDescriptor());
		// 首先调用data.writeInt32(IPCThreadState::self()->getStrictModePolicy())
		// 然后再写入android.os.IServiceManager
		data.writeString16(name);	// 写入 media.player
		remote()->transact(CHECK_SERVICE_TRANSACTION, data, &reply);
		return reply.readStrongBinder();
	}
}

这里首先将请求打包成Parcel各式,然后调用remote()->transact()函数,前面我们分析过BpServiceManager::remote()返回
的就是前面new BpBinder(0)对应句柄为ServiceManager。继续去BpBinder中寻找实现代码:
frameworks/base/libs/binder/BpBinder.cpp

status_t BpBinder::transact(uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
{
	IPCThreadState::self()->transact(mHandle, code, data, reply, flags);
}

最后调用的IPCThreadState的transact()函数,IPCThreadState是专门提供通过Binder进程间通信的接口的。

status_t IPCTheadState::transact(int32_t handle, uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
{
	// 填充binder_transaction_data 结构体,写入到mOut中去
	writeTransactionData(BC_TRANSACTION, flags, handle, code, data, NULL);
	
	// 调用talkWithDriver() 将mOut写到Binder驱动,并从Binder驱动读取mIn数据
	waitForResponse(reply);
}

首先通过writeTransactionData函数来填充mOut结构体,mOut里面内容为:
 mOut.writeInt32(BC_TRANSACTION);
 mOut.write(&tr, sizeof(tr));
这里binder_transaction_data tr内容为:
 tr.target.handle = 0; // 表面是发往ServiceManager的
 tr.code = CHECK_SERVICE_TRANSACTION;
 tr.flags = 0;
tr.data内容为:
 data.writeInt32(IPCThreadState::self()->getStrictModePolicy() | STRICT_MODE_PENALTY_GATHER);
 data.writeString16("android.os.IServiceManager");
 data.writeString16("media.player");
根据前面Android开发之ServiceManager一章中我们分析,svcmgr_handler处理从句柄为0的Binder的请求:
strict_policy = bio_get_string32();
s = bio_get_string16(); // 就是上面的android.os.IServiceManager
s = bio_get_string16(); // 就是上面的 media.player
根据media.player遍历全局链表svclist找到相应的服务,调用bio_put_ref(reply, ptr) 返回目标Binder实体。


这个waitForResponse()函数是关键:

status_t IPCThreadState::waitForResponse(Parcel* reply)
{
	while(1) {
		talkWithDriver();	// 输入mOut 输出mIn
		cmd = mIn.readInt32();
		switch(cmd) {
		case BR_REPLY:	
		{
			binder_transaction_data tr;
			mIn.read(&tr, sizeof(tr));
			if(reply) {
			reply->ipcSetDataReference(reinterpret_cast<const uint8_t*>(tr.data.ptr.buffer),
			tr.data.size, reinterpret_cast<const size_t*>(tr.data.ptr.offsets), 
			tr.offsets_size/sizeof(sizt_t), freeBuffer, this);
			} else {
			err = *static_cast<const status_t*>(tr.data.ptr.buffer);
			freeBuffer(NULL, reinterpret_cast<const uint8_t*>(tr.data.ptr.buffer),
			tr.data.size, reinterpret_cast<const size_t*>(tr.data.ptr.offsets), 
			tr.offsets_size/sizeof(sizt_t), freeBuffer, this)
			}
		}
		}
	}
}
最后返回的是:return reply.readStrongBinder();进入到Parcel的readStrongBinder()函数
sp<IBinder> Parcel::readStrongBinder() const
{
	sp<IBinder> val;
	unflatten_binder(ProcessState::self(), *this, &val);
	return val;
}
status_t unflatten_binder(const sp<ProcessState>& proc, const Parcel& in, sp<IBinder>* out)
{
	const flat_binder_object* flat = in.readObject(false);
	if(flat) {
		switch(flat->type) {
			case BINDER_TYPE_BINDER:
				*out = static_cast<IBinder*>(flat->cookie);
				return finish_unflatten_binder(NULL, *flat, in);
			case BINDER_TYPE_HANDLE:
				*out = proc->getStrongProxyForHandle(flat->handle);
				return finish_unflatten_binder(static_cast<BpBinder*>(out->get()), *flat, in);
		}
	}
}

这里flat->type是BINDER_TYPE_HANDLE,所以调用ProcessState::getStrongProxyForHandle()函数

sp<IBinder> ProcessState::getStrongProxyForHandle(int32_t handle)
{
	sp<IBinder> result;
	
	handle_entry* e = lookupHandleLocked(handle);
	if(e != NULL) {
		IBinder* b = e->binder;
		if(b == NULL || !e->refs->attemptIncWeak(this)) {
			b = new BpBinder(handle);
			e->binder = b;
			if( b ) e->refs = e->getWeakRefs();
			result = b;
		} else {
			result.force_set(b);
			e->refs->decWeak(this);
		}
	}
	return result;
}

这里的handle就是ServiceManager内维护的MediaPlayerService对应的Binder句柄,这个ProcessState根据这个句柄
new 了一个BpBinder,并将其保存起来,这样下次需要从ServiceManager请求获取到相同句柄的时候就可以直接返回了。
最后根据这个返回的BpBinder获得MediaPlayerService的代理:
sMediaPlayerService = interface_cast<IMediaPlayerService>(binder);
根据前面ServiceManager一样,最后调用的是IMediaPlayerService的asInterface()宏函数

android::sp<IMediaPlayerService> IMediaPlayerService::asInterface(const android::sp<android::IBinder>& obj)
{
	android::sp<IMediaPlayerService> intr;
	if(obj != NULL ) {
		intr = static_cast<IMediaPlayerService>(
			obj->queryLocalInterface(IMediaPlayerService::descriptor).get);
			if (intr == NULL) {
				intr = new BpMediaPlayerService(obj);
			}
	}
	return intr;
}

 

这样我就获得了一个代理BpMediaPlayerService对象,它的remote()为BpBinder(handle),这个handle就是向服务总共ServiceManager
查询到的MediaPlayerService对应的Binder句柄。

   下一章我们分析,客户端如何通过这个BpServiceManager代理对象调用服务端MediaPlayerService的业务函数的?



原文二:Android的MediaPlayer分析

链接:http://www.byywee.com/page/M0/S846/846697.html

前段时候接到任务,商量一下MediaPlayer在Android体系中是如何实现的。到如今为止终于有些端倪了,在查询拜访代码时辰固然有些吃力,然则还算是有所得的。今天把本身对MediaPlayer的粗浅懂得拿出来,一来作为笔记备份;一来和大师分享。以下代码都是以Android4.2代码为根蒂根基的,迎接大师斧正,共同窗习。

  为了有一个完全的浏览代码的脉络和思路,我是以一个很是简单的Java应用法度开端。法度很是简单,代码如下:



1 MediaPlayer mediaPlayer = new MediaPlayer();

2 mediaPlayer.setDataSource("/sdcard/test.mp3");

3 mediaPlayer.prepare();

4 mediaPlayer.start();

5 mediaPlayer.stop();


 创建MediaPlayer对象


从第一行代码开端看:


MediaPlayer mediaPlayer = new MediaPlayer();
这行代码是在Java应用法度中,功能是新建一个对象。既然如此,我们就看看MediaPlayer这个类在Java层的机关函数,如下:


[/frameworks/base/media/java/android/media/MediaPlayer.java]



 1     public MediaPlayer() {

 2 

 3         Looper looper;

 4         if ((looper = Looper.myLooper()) != null) {

 5             mEventHandler = new EventHandler(this, looper);

 6         } else if ((looper = Looper.getMainLooper()) != null) {

 7             mEventHandler = new EventHandler(this, looper);

 8         } else {

 9             mEventHandler = null;

10         }

11 

12         /* Native setup requires a weak reference to our object.

13          * It""s easier to create it here than in C++.

14          */

15         native_setup(new WeakReference<MediaPlayer>(this));

16     }


在这个机关函数中,较为首要的就是native_setup(). 这个函数在之前的声明中包含native,申明这是一个native函数。也就是说native_setup()函数其实native层实现的。接下来我们要做的就是按照JNI找到这个函数是如何实现的。native函数实现地点的文件的文件名都是如下定名的,把包名中的"."调换为"_"+类名。所以我们要找文件就是android_media_MediaPlayer.cpp.在这个文件中我们有个首要的数组,如下:


【/frameworks/base/media/jni/android_media_MediaPlayer.cpp】



 1 static JNINativeMethod gMethods[] = {

 2     {

 3         "_setDataSource" 4         "(Ljava/lang/String;[Ljava/lang/String;[Ljava/lang/String;)V" 5void *)android_media_MediaPlayer_setDataSourceAndHeaders

 6     },

 7 

 8     {"setDataSource",       "(Ljava/io/FileDescriptor;JJ)V",    (void *)android_media_MediaPlayer_setDataSourceFD},

 9     {"_setVideoSurface",    "(Landroid/view/Surface;)V",        (void *)android_media_MediaPlayer_setVideoSurface},

10     {"prepare",             "()V",                              (void *)android_media_MediaPlayer_prepare},

11     {"prepareAsync",        "()V",                              (void *)android_media_MediaPlayer_prepareAsync},

12     {"_start",              "()V",                              (void *)android_media_MediaPlayer_start},

13     {"_stop",               "()V",                              (void *)android_media_MediaPlayer_stop},

14     {"getVideoWidth",       "()I",                              (void *)android_media_MediaPlayer_getVideoWidth},

15     {"getVideoHeight",      "()I",                              (void *)android_media_MediaPlayer_getVideoHeight},

16     {"seekTo",              "(I)V",                             (void *)android_media_MediaPlayer_seekTo},

17     {"_pause",              "()V",                              (void *)android_media_MediaPlayer_pause},

18     {"isPlaying",           "()Z",                              (void *)android_media_MediaPlayer_isPlaying},

19     {"getCurrentPosition",  "()I",                              (void *)android_media_MediaPlayer_getCurrentPosition},

20     {"getDuration",         "()I",                              (void *)android_media_MediaPlayer_getDuration},

21     {"_release",            "()V",                              (void *)android_media_MediaPlayer_release},

22     {"_reset",              "()V",                              (void *)android_media_MediaPlayer_reset},

23     {"setAudioStreamType",  "(I)V",                             (void *)android_media_MediaPlayer_setAudioStreamType},

24     {"setLooping",          "(Z)V",                             (void *)android_media_MediaPlayer_setLooping},

25     {"isLooping",           "()Z",                              (void *)android_media_MediaPlayer_isLooping},

26     {"setVolume",           "(FF)V",                            (void *)android_media_MediaPlayer_setVolume},

27     {"getFrameAt",          "(I)Landroid/graphics/Bitmap;",     (void *)android_media_MediaPlayer_getFrameAt},

28     {"native_invoke",       "(Landroid/os/Parcel;Landroid/os/Parcel;)I",(void *)android_media_MediaPlayer_invoke},

29     {"native_setMetadataFilter", "(Landroid/os/Parcel;)I",      (void *)android_media_MediaPlayer_setMetadataFilter},

30     {"native_getMetadata", "(ZZLandroid/os/Parcel;)Z",          (void *)android_media_MediaPlayer_getMetadata},

31     {"native_init",         "()V",                              (void *)android_media_MediaPlayer_native_init},

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

33     {"native_finalize",     "()V",                              (void *)android_media_MediaPlayer_native_finalize},

34     {"getAudioSessionId",   "()I",                              (void *)android_media_MediaPlayer_get_audio_session_id},

35     {"setAudioSessionId",   "(I)V",                             (void *)android_media_MediaPlayer_set_audio_session_id},

36     {"setAuxEffectSendLevel", "(F)V",                           (void *)android_media_MediaPlayer_setAuxEffectSendLevel},

37     {"attachAuxEffect",     "(I)V",                             (void *)android_media_MediaPlayer_attachAuxEffect},

38     {"native_pullBatteryData", "(Landroid/os/Parcel;)I",        (void *)android_media_MediaPlayer_pullBatteryData},

39     {"setParameter",        "(ILandroid/os/Parcel;)Z",          (void *)android_media_MediaPlayer_setParameter},

40     {"getParameter",        "(ILandroid/os/Parcel;)V",          (void *)android_media_MediaPlayer_getParameter},

41     {"native_setRetransmitEndpoint", "(Ljava/lang/String;I)I",  (void *)android_media_MediaPlayer_setRetransmitEndpoint},

42     {"setNextMediaPlayer",  "(Landroid/media/MediaPlayer;)V",   (void *)android_media_MediaPlayer_setNextMediaPlayer},

43 };


在这个数组中,第一列默示的是Java层中函数名,第二列是Java层函数对应的参数以及返回值类型,第三列就是对应在Native层的函数名。从这个数组中,我们可以找到native_setup(),对应的函数名是android_media_MediaPlayer_native_setup,接下来我们就看看这个函数的实现:


【/frameworks/base/media/jni/android_media_MediaPlayer.cpp】



 1 static void

 2 android_media_MediaPlayer_native_setup(JNIEnv *env, jobject thiz, jobject weak_this)

 3 {

 4     ALOGV("native_setup");

 5     sp<MediaPlayer> mp = new MediaPlayer();

 6     if (mp == NULL) {

 7         jniThrowException(env, "java/lang/RuntimeException", "Out of memory");

 8         return;

 9     }

10 

11     // create new listener and give it to MediaPlayer

12     sp<JNIMediaPlayerListener> listener = new JNIMediaPlayerListener(env, thiz, weak_this);

13     mp->setListener(listener);

14 

15     // Stow our new C++ MediaPlayer in an opaque field in the Java object.

16     setMediaPlayer(env, thiz, mp);

17 }


 在本文中,对于解析MediaPlayer流程较为首要的函数,我都邑用红色字体标识出来。这不是说没有标红的就不首要,在法度里没有无用的代码,只是对于我们此次的流程解析不太首要罢了。先看第5行 



sp<MediaPlayer> mp = new MediaPlayer();


这行代码的功能就是创建一个MediaPlayer类的对象,不过这个对象是Native层的对象,也就是说这个Native层的MediaPlayer类是应用C++代码实现的。我们先往下看下面一句较为首要的代码,然后在后头解析Native层MediaPlayer对象的机关函数。



16     setMediaPlayer(env, thiz, mp);


这行代码的功能就是把我们新创建的Native层的MediaPlayer对象保存到Java层。也就是说将来我们经由过程getMediaplayer()的时辰获取到的就是这个对象。接下来,我就开端解析Native层的MediaPlayer的机关函数,代码如下:



 1 MediaPlayer::MediaPlayer()

 2 {

 3     ALOGV("constructor");

 4     mListener = NULL;

 5     mCookie = NULL;

 6     mStreamType = AUDIO_STREAM_MUSIC;

 7     mCurrentPosition = -1;

 8     mSeekPosition = -1;

 9     mCurrentState = MEDIA_PLAYER_IDLE;

10     mPrepareSync = false;

11     mPrepareStatus = NO_ERROR;

12     mLoop = false;

13     mLeftVolume = mRightVolume = 1.0;

14     mVideoWidth = mVideoHeight = 0;

15     mLockThreadId = 0;

16     mAudioSessionId = AudioSystem::newAudioSessionId();

17     AudioSystem::acquireAudioSessionId(mAudioSessionId);

18     mSendLevel = 0;

19     mRetransmitEndpointValid = false;

20 }


在机关Native层的MediaPlayer对象的时辰,也会机关父类的对象。只不过在这些对象机关过程中,对于我们解析MediaPlayer流程并没有希罕首要的器材。然则我们要懂得的一点就是在MediaPlayer的父类IMediaDeathNotifier中有个很首要的办法getMediaPlayerService(),对于这个办法我们在之后的解析过程中还会用到,到时辰在具体介绍。


到这里为止,这一末节根蒂根基停止。总结一下,在MediaPlayer的初始化过程中,就是创建了MediaPlayer的对象。


首要的函数setDataSource()


 在写这篇blog之前,已经对MediaPlayer的流程有了可能的懂得。如今回头再看,发明这个函数真的很是首要。在这个函数中,MediaPlayer和MediaPlayerService建树了接洽,MediaPlayerService和Stagefright或者OpenCore也建树了接洽。 我们持续RFCD,在Java层,我们应用的办法如下: 



mediaPlayer.setDataSource("/sdcard/test.mp3");


在Java层这个函数代码如下:


【/frameworks/base/media/java/android/media/MediaPlayer.java】



 1     public void setDataSource(String path)

 2             throws IOException, IllegalArgumentException, SecurityException, IllegalStateException {

 3         setDataSource(path, nullnull);

 4     }

 5 调用setDataSource()的重载办法,之后的重载调用过程我们就略过,终极会调用到如下办法:

 6     public void setDataSource(FileDescriptor fd)

 7             throws IOException, IllegalArgumentException, IllegalStateException {

 8         // intentionally less than LONG_MAX

 9         setDataSource(fd, 0, 0 x7ffffffffffffffL);

10     }

11     public native void setDataSource(FileDescriptor fd, long offset, long length)

12             throws IOException, IllegalArgumentException, IllegalStateException;


 所以这个函数终极还是调用到类Native层。在之后的过程中,我们都邑跳过对于JNI层的寻找过程,直接进入Native层的MediaPlayer对象寻找响应的办法。在Native层中setDataSource()对应的代码如下:


【/frameworks/av/media/libmedia/mediaplayer.cpp】



 1 status_t MediaPlayer::setDataSource(int fd, int64_t offset, int64_t length)

 2 {

 3     ALOGV("setDataSource(%d, %lld, %lld)", fd, offset, length);

 4     status_t err = UNKNOWN_ERROR;

 5     const sp<IMediaPlayerService>& service(getMediaPlayerService());

 6     if (service != 0) {

 7         sp<IMediaPlayer> player(service->create(getpid(), this, mAudioSessionId));

 8         if ((NO_ERROR != doSetRetransmitEndpoint(player)) ||

 9             (NO_ERROR != player->setDataSource(fd, offset, length))) {

10             player.clear();

11         }

12         err = attachNewPlayer(player);

13     }

14     return err;

15 }


 上方这段代码重点处所有三个,都已经标示出来。先看第一个,getMediaPlayerService(),这个函数从其名字上看是获取MediaPlayerService。是以


 5     const sp<IMediaPlayerService>& service(getMediaPlayerService());

的功能就是获取MediaPlayerService并且把返回值赋值给service。关于getMediaPlayerService函数,我们在前面说过一次,这个办法是MediaPlayer的父类IMediaDeathNotifier的一个办法,关系到MediaPlayer和MediaPlayerService之间的通信。下面我们就看看这个办法的代码:
[/frameworks/av/media/libmedia/IMediaDeathNotifier.cpp]


 1 // establish binder interface to MediaPlayerService

 2 /*static*/const sp<IMediaPlayerService>&

 3 IMediaDeathNotifier::getMediaPlayerService()

 4 {

 5     ALOGV("getMediaPlayerService");

 6     Mutex::Autolock _l(sServiceLock);

 7     if (sMediaPlayerService == 0) {

 8         sp<IServiceManager> sm = defaultServiceManager();

 9         sp<IBinder> binder;

10         do {

11             binder = sm->getService(String16("media.player"));

12             if (binder != 0) {

13                 break;

14             }

15             ALOGW("Media player service not published, waiting...");

16             usleep(500000); // 0.5 s

17         } whiletrue);

18 

19         if (sDeathNotifier == NULL) {

20         sDeathNotifier = new DeathNotifier();

21     }

22     binder->linkToDeath(sDeathNotifier);

23     sMediaPlayerService = interface_cast<IMediaPlayerService>(binder);

24     }

25     ALOGE_IF(sMediaPlayerService == 0, "no media player service!?");

26     return sMediaPlayerService;

27 }


在getMediaPlayerService()函数中,重点内容有三处,不过都是为了最后获取MediaPlayerService办事的。第8行是获取ServiceManager;第11行是从ServiceManager中获取到我们所须要的一个对象,这个对象是BpBinder类型,为我们最后取得MediaPlayerService作筹办。第23行是获取MediaPlayerService,不过终极获得这个对象是BpMediaPlayerService类型。我们获取到得这个BpMediaPlayerService,这个对象的所有操纵终极都邑由真正的MediaPlayerService对象来完成,是以完全可以看做是MediaPlayerService。这个过程和Binder通信相干,不是我们此次商量的重点,这里不再赘述。


  到这里,我们解析完成了getMediaPlayerService办法,获得了返回值,并把它赋值给了service。接下来我们就要看看MediaPlayer应用这个service都做了些什么工作。从代码中看,统共有两件工作,分别是:


    1)按照过程ID,对象本身,AudioSessionId这三个参数,在server端创建了一个Player对象并返回给MediaPlayer端的player。这个Player也是具有过程间通信才能的。



 7         sp<IMediaPlayer> player(service->create(getpid(), this, mAudioSessionId));


    2)为server端的Player设置播放资料



player->setDataSource(fd, offset, length)


我们开端看看第一件工作时如何完成的,以及在Server段创建player的时辰都做了那些工作。这个Create操纵终极会在Server端履行,所以我们就去MediaPlayerService段在这个过程中都做了些什么,代码如下:


[/frameworks/av/media/libmediaplayerservice/MediaPlayerService.cpp]



 1 sp<IMediaPlayer> MediaPlayerService::create(pid_t pid, const sp<IMediaPlayerClient>& client,

 2         int audioSessionId)

 3 {

 4     int32_t connId = android_atomic_inc(&mNextConnId);

 5 

 6     sp<Client> c = new Client(

 7             this, pid, connId, client, audioSessionId,

 8             IPCThreadState::self()->getCallingUid());

 9 

10     ALOGV("Create new client(%d)  pid %d, uid %d, ", connId, pid,

11          IPCThreadState::self()->getCallingUid());

12 

13     wp<Client> w = c;

14     {

15         Mutex::Autolock lock(mLock);

16         mClients.add(w);

17     }

18     return c;

19 }


从代码中,我们可以看出,在Server端,我们新建的对象是Client,是MediaPlayerService的内部类。然则这个Client履行了MediaPlayerService的绝大项目组操纵。同样我们将来传输过来的数据也都是会交给内部类Client进行处理惩罚的。到这里,在Server端的对象就创建完成了。


接下来就是要做第二件工作了,就是在MediaPlayer中调用player->setDataSource();,这件事还是要在Server完成的,代码如下:


[/frameworks/av/media/libmediaplayerservice/MediaPlayerService.cpp]



 1 status_t MediaPlayerService::Client::setDataSource(int fd, int64_t offset, int64_t length)

 2 {

 3     ALOGV("setDataSource fd=%d, offset=%lld, length=%lld", fd, offset, length);

 4     struct stat sb;

 5     int ret = fstat(fd, &sb);

 6     if (ret != 0) {

 7         ALOGE("fstat(%d) failed: %d, %s", fd, ret, strerror(errno));

 8         return UNKNOWN_ERROR;

 9     }

10 

11     ALOGV("st_dev  = %llu", sb.st_dev);

12     ALOGV("st_mode = %u", sb.st_mode);

13     ALOGV("st_uid  = %lu", sb.st_uid);

14     ALOGV("st_gid  = %lu", sb.st_gid);

15     ALOGV("st_size = %llu", sb.st_size);

16 

17     if (offset >= sb.st_size) {

18         ALOGE("offset error");

19         ::close(fd);

20         return UNKNOWN_ERROR;

21     }

22     if (offset + length > sb.st_size) {

23         length = sb.st_size - offset;

24         ALOGV("calculated length = %lld", length);

25     }

26 

27     player_type playerType = MediaPlayerFactory::getPlayerType(this,

28                                                                fd,

29                                                                offset,

30                                                                length);

31     sp<MediaPlayerBase> p = setDataSource_pre(playerType);

32     if (p == NULL) {

33         return NO_INIT;

34     }

35 

36     // now set data source

37     setDataSource_post(p, p->setDataSource(fd, offset, length));

38     return mStatus;

39 }


 上方这段代码感化就是获取一个PlayerType,然后一这个PlayerType作为参数传递到setDataSource _pre(),在这个办法中按照playerType做一些工作。关于PlayerType是如何获取的,以及我们传入的文件test.mp3,对应什么类型的playerType,我就不再介绍了。之所以不介绍是因为牵扯到资料的一些特有的参数和属性断定的,我不太懂得。不过我们可以从代码中找到在Android中一共又几种如许的Type,如下:


/frameworks/av/include/media/MediaPlayerInterface.h



 1 enum player_type {

 2     PV_PLAYER = 1 3     SONIVOX_PLAYER = 2 4     STAGEFRIGHT_PLAYER = 3 5     NU_PLAYER = 4 6     // Test players are available only in the ""test"" and ""eng"" builds.

 7     // The shared library with the test player is passed passed as an

 8     // argument to the ""test:"" url in the setDataSource call.

 9     TEST_PLAYER = 510 };


一种有五种type,然则PV_PLAYER如同是从Android2.3之后就作废了,因为PVPlayer是和Opencore相干的,自从OpenCore从Android2.3中移出之后,这个type对应的Player就没有了。所以在Android4.2中只剩下


四种type了。这些type和他们对应的player都邑以键值对的情势放入一个数据布局中,以备后用。在后面我们在应用这些type的时辰,就会发明这些键值对是存放在sFactoryMap中的,而sFactoryMap 是tFactoryMap型的,


也就是就是KeyVector。貌似KeyVector是android定义的数据布局吧,类似Hashmap。而把这些type和player键值对添参加sFactorymap中过程如下:


[/frameworks/av/media/libmediaplayerservice/MediaPlayerFactory.cpp]



 1 void MediaPlayerFactory::registerBuiltinFactories() {

 2     Mutex::Autolock lock_(&sLock);

 3 

 4     if (sInitComplete)

 5         return;

 6 

 7     registerFactory_l(new StagefrightPlayerFactory(), STAGEFRIGHT_PLAYER);

 8     registerFactory_l(new NuPlayerFactory(), NU_PLAYER);

 9     registerFactory_l(new SonivoxPlayerFactory(), SONIVOX_PLAYER);

10     registerFactory_l(new TestPlayerFactory(), TEST_PLAYER);

11 

12     sInitComplete = true;

13 }


看看上方这两段代码还是有益处的,最起码让我们熟悉打听工作的来龙去脉。若是我们想要在Android中扩大,应用新的解码对象,可以直接持续MediaPlayerFactory类,然后在这里注册所须要的type就行了。


接着上方的说,假设我们mp3对应的时defaultType,也就是STAGEFRIGHT_PLAYER,那么这个数据就会作为setDataSource_pre()的参数应用。我们就看看这个函数是如何哄骗Type参数创建新的对象的,代码如下:


【/frameworks/av/media/libmediaplayerservice/MediaPlayerService.cpp】



 1 sp<MediaPlayerBase> MediaPlayerService::Client::setDataSource_pre(

 2         player_type playerType)

 3 {

 4     ALOGV("player type = %d", playerType);

 5 

 6     // create the right type of player

 7     sp<MediaPlayerBase> p = createPlayer(playerType);

 8     if (p == NULL) {

 9         return p;

10     }

11 

12     if (!p->hardwareOutput()) {

13         mAudioOutput = new AudioOutput(mAudioSessionId);

14         static_cast<MediaPlayerInterface*>(p.get())->setAudioSink(mAudioOutput);

15     }

16 

17     return p;

18 }


先申明一下,上方的红色代码都是很首要的,不过13和14行代码在setDataSource()临时还是用不上,要比及start()的时辰,和AudioFlinger建树接洽的时辰才干用到。如今先标识表记标帜下,有个印象。我们持续我们的工作,解析createPlayer()办法,代码如下:


/frameworks/av/media/libmediaplayerservice/MediaPlayerService.cpp



 1 sp<MediaPlayerBase> MediaPlayerService::Client::createPlayer(player_type playerType)

 2 {

 3     // determine if we have the right player type

 4     sp<MediaPlayerBase> p = mPlayer;

 5     if ((p != NULL) && (p->playerType() != playerType)) {

 6         ALOGV(" player");

 7         p.clear();

 8     }

 9     if (p == NULL) {

10         p = MediaPlayerFactory::createPlayer(playerType, this, notify);

11     }

12 

13     if (p != NULL) {

14         p->setUID(mUID);

15     }

16 

17     return p;

18 }


看红色代码标识的第10行代码,这里应用的设计模式中的--Factory模式,大师可以参考进修下。Android体系时一个如此重大错杂的体系,为了杰出的扩大性应用了很多设计模式。无论是进修策画机哪方面内容,Android源码都是一份不错的教材。还是持续看我们的任务,接着看代码,在MediaPlayerFactory::createPlayer()的代码如下:


[/frameworks/av/media/libmediaplayerservice/MediaPlayerFactory.cpp]



 1 sp<MediaPlayerBase> MediaPlayerFactory::createPlayer(

 2         player_type playerType,

 3         void* cookie,

 4         notify_callback_f notifyFunc) {

 5     sp<MediaPlayerBase> p;

 6     IFactory* factory;

 7     status_t init_result;

 8     Mutex::Autolock lock_(&sLock);

 9 

10     if (sFactoryMap.indexOfKey(playerType) < 0) {

11         ALOGE("Failed to create player object of type %d, no registered"

12               " factory", playerType);

13         return p;

14     }

15 

16     factory = sFactoryMap.valueFor(playerType);

17     CHECK(NULL != factory);

18     p = factory->createPlayer();

19 

20     if (p == NULL) {

21         ALOGE("Failed to create player object of type %d, create failed"22                playerType);

23         return p;

24     }

25 

26     init_result = p->initCheck();

27     if (init_result == NO_ERROR) {

28         p->setNotifyCallback(cookie, notifyFunc);

29     } else {

30         ALOGE("Failed to create player object of type %d, initCheck failed"

31               " (res = %d)", playerType, init_result);

32         p.clear();

33     }

34 

35     return p;

36 }


 
我们经由过程playerType获取到得是IFactory对象,然后应用这个对象进行createPlayer。对于这一点的懂得和Factory模式有关,若是不熟悉打听的话,抽出一点点时候看看Factory模式必然是会有益处的。按照

playerType,我们这里的factory应当是StageFrightPlayerFactory的对象,然后调用它的的createPlayer函数。createPlayer()的实现如下:
[/frameworks/av/media/libmediaplayerservice/MediaPlayerFactory.cpp]


1     virtual sp<MediaPlayerBase> createPlayer() {

2         ALOGV(" create StagefrightPlayer");

3         return new StagefrightPlayer();

4     }


从这里StageFrightPlayerFactory的createPlayer中我们获得的返回值是一个新的对象--StagefrightPlayer的实例。到这里,我们就算是进入stagefright了,我们代码查询拜访到这儿也根蒂根基将近停止了。
我们还是接着看看这个新的对象的机关办法,代码如下:
[/frameworks/av/media/libmediaplayerservice/StagefrightPlayer.cpp]


1 StagefrightPlayer::StagefrightPlayer()

2     : mPlayer(new AwesomePlayer) {

3     ALOGV("StagefrightPlayer");

4 

5     mPlayer->setListener(this);

6 }


在这个机关函数中,有个很轻易忽视的处所,就是机关函数的属性赋值的体式格式,在C++中经常应用,叫做机关函数的初始化列表。乍一看,这个机关函数什么也没有,其实重点内容就在机关函数的初始化列表中,在这里我们又
创建了一个对象AwesomPlayer. 我感觉我们进行到这儿,也可以告一段落了,因为我们已经接触到了Stagefright,再向下查询拜访代码的话就应当是零丁研究stagefright的工作了。今后,在查询拜访过stagefrigh后,我会
再补上一篇博客说说stagefright的。
  好了,骚年们,让我们像函数调用停止时一样,一步一步return吧,直到可以或许持续向下履行的处所。我们一向查询拜访到这儿,是在解析MediaPlayerService中要做的两件事中的第二件工作setDataSource()。我们方才停止
解析的处所是:sp<MediaPlayerBase> p = setDataSource_pre(playerType);让我们先总结一下我们方才都做了哪些工作,其实挺简单的就是创建了一个对象StagefrightPlayer,并把这个对象保存到p中。StagefrightPlayer
对象在创建的过程中,我们也设置了一些参数,比如p->setAudioSink(),还创建了AwesomePlayer对象,保存在StagefrightPlayer对象中的mPlayer属性中。既然setDataSource_pre()已经查询拜访停止,那么我们就要开端下一步
操纵了,就是下面已经用红色代码标示出来的项目组:
[/frameworks/av/media/libmediaplayerservice/MediaPlayerService.cpp]


 1 status_t MediaPlayerService::Client::setDataSource(int fd, int64_t offset, int64_t length)

 2 {

 3 ...

 4     player_type playerType = MediaPlayerFactory::getPlayerType(this 5                                                                fd,

 6                                                                offset,

 7                                                                length);

 8     sp<MediaPlayerBase> p = setDataSource_pre(playerType);

 9 ...

10     // now set data source

11     setDataSource_post(p, p->setDataSource(fd, offset, length));

12     return mStatus;

13 }


 


 其实函数setDataSource_post()对于我们解析MediaPlayer流程的感化不太大,可能是要设置MediaPlayer的一些功能
的属,我们此次重点存眷的是这个办法中的第二个参数。由上方的解析,我们知道p指向的对象是一个StagefrightPlayer
对象,所以p->setDataSource()的实现,我们就应当去StagefrightPlayer类中寻找。找到响应的代码如下:
[/frameworks/av/media/libmediaplayerservice/StagefrightPlayer.cpp]


1 status_t StagefrightPlayer::setDataSource(int fd, int64_t offset, int64_t length) {

2     ALOGV("setDataSource(%d, %lld, %lld)", fd, offset, length);

3     return mPlayer->setDataSource(dup(fd), offset, length);

4 }



 


本来是应用StagefrightPlayer的属性mPlayer去实现的,前面我们也说到了stagefrightPlayer.mPlayer指向的是
AwesomePlayer.到这儿我们到此为止吧。
  到这里,在MediaPlayerService端的的setDataSource()的工作也停止了,总结一下就是:从Java应用法度中的
MediaPlayer的setDataSource()会传递到Native层中的MediaPlayer的setDataSource()去履行,而
MediaPlayer会把这个办法交给MediaPlayerservice去履行。MediaPlayerService的是应用stagefrightPlayer
实现的,最后,最后,我们的setdataSource还是交给了AwesomePlayer去履行了。这个流程把MediaPlayer和
MediaPlayerService之间的接洽建树起来,同时又把MediaPlayerService是如何应用stagefright实现的关系建树了
起来。到这里,我们的解析MediaPlayer的流程的目标也算是根蒂根基达到了。若是再持续解析MediaPlayer的话,我们可
以分为两个标的目标了,一个是解析stagefright是如何解码的;一个是解析MediaPlayer与AudioTrack,AudioFlinger
之间的关系了。由此看来,将来的任务和路子还是任重道远的。

  • 1
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
深入理解Android 卷1 不是扫描版的,是全版电子书的,非PDF,可编辑,各种阅览器以打开!包括书签和同步目录! 第1章 阅读前的准备工作 / 1 1.1 系统架构 / 2 1.1.1 Android系统架构 / 2 1.1.2 本书的架构 / 3 1.2 搭建开发环境 / 4 1.2.1 下载源码 / 4 1.2.2 编译源码 / 6 1.3 工具介绍 / 8 1.3.1 Source Insight介绍 / 8 1.3.3 Busybox的使用 / 11 1.4 本章小结 / 12 第2章 深入理解JNI / 13 2.1 JNI概述 / 14 2.2 学习JNI的实例:MediaScanner / 15 2.3 Java层的MediaScanner分析 / 16 2.3.1 加载JNI库 / 16 2.3.2 Java的native函数和总结 / 17 2.4 JNI层MediaScanner的分析 / 17 2.4.1 注册JNI函数 / 18 2.4.2 数据类型转换 / 22 2.4.3 JNIEnv介绍 / 24 2.4.4 通过JNIEnv操作jobject / 25 2.4.5 jstring介绍 / 27 2.4.6 JNI类型签名介绍 / 28 2.4.7 垃圾回收 / 29 2.4.8 JNI中的异常处理 / 32 2.5 本章小结 / 32 第3章 深入理解init / 33 3.1 概述 / 34 3.2 init分析 / 34 3.2.1 解析配置文件 / 38 3.2.2 解析service / 42 3.2.3 init控制service / 48 3.2.4 属性服务 / 52 3.3 本章小结 / 60 第4章 深入理解zygote / 61 4.1 概述 / 62 4.2 zygote分析 / 62 4.2.1 AppRuntime分析 / 63 4.2.2 Welcome to Java World / 68 4.2.3 关于zygote的总结 / 74 4.3 SystemServer分析 / 74 4.3.1 SystemServer的诞生 / 74 4.3.2 SystemServer的重要使命 / 77 4.3.3 关于 SystemServer的总结 / 83 4.4 zygote的分裂 / 84 4.4.1 ActivityManagerService发送请求 / 84 4.4.2 有求必应之响应请求 / 86 4.4.3 关于zygote分裂的总结 / 88 4.5 拓展思考 / 88 4.5.1 虚拟机heapsize的限制 / 88 4.5.2 开机速度优化 / 89 4.5.3 Watchdog分析 / 90 4.6 本章小结 / 93 第5章 深入理解常见类 / 95 5.1 概述 / 96 5.2 以“三板斧”揭秘RefBase、sp和wp / 96 5.2.1 第一板斧——初识影子对象 / 96 5.2.2 第二板斧——由弱生强 / 103 5.2.3 第三板斧——破解生死魔咒 / 106 5.2.4 轻量级的引用计数控制类LightRefBase / 108 5.2.5 题外话-三板斧的来历 / 109 5.3 Thread类及常用同步类分析 / 109 5.3.1 一个变量引发的思考 / 109 5.3.2 常用同步类 / 114 5.4 Looper和Handler类分析 / 121 5.4.1 Looper类分析 / 122 5.4.2 Handler分析 / 124 5.4.3 Looper和Handler的同步关系 / 127 5.4.4 HandlerThread介绍 / 129 5.5 本章小结 / 129 第6章 深入理解Binder / 130 6.1 概述 / 131 6.2 庖丁解MediaServer / 132 6.2.1 MediaServer的入口函数 / 132 6.2.2 独一无二的ProcessState / 133 6.2.3 时空穿越魔术-defaultServiceManager / 134 6.2.4 注册MediaPlayerService / 142 6.2.5 秋风扫落叶-StartThread Pool和join Thread Pool分析 / 149 6.2.6 你彻底明白了吗 / 152 6.3 服务总管ServiceManager / 152 6.3.1 ServiceManager的原理 / 152 6.3.2 服务的注册 / 155 6.3.3 ServiceManager存在的意义 / 158 6.4 MediaPlayerService和它的Client / 158 6.4.1 查询ServiceManager / 158 6.4.2 子承父业 / 159 6.5 拓展思考 / 162 6.5.1 Binder和线程的关系 / 162 6.5.2 有人情味的讣告 / 163 6.5.3 匿名Service / 165 6.6 学以致用 / 166 6.6.1 纯Native的Service / 166 6.6.2 扶得起的“阿斗”(aidl) / 169 6.7 本章小结 / 172 第7章 深入理解Audio系统 / 173 7.1 概述 / 174 7.2 AudioTrack的破解 / 174 7.2.1 用例介绍 / 174 7.2.2 AudioTrack(Java空间)分析 / 179 7.2.3 AudioTrack(Native空间)分析 / 188 7.2.4 关于AudioTrack的总结 / 200 7.3 AudioFlinger的破解 / 200 7.3.1 AudioFlinger的诞生 / 200 7.3.2 通过流程分析AudioFlinger / 204 7.3.3 audio_track_cblk_t分析 / 230 7.3.4 关于AudioFlinger的总结 / 234 7.4 AudioPolicyService的破解 / 234 7.4.1 AudioPolicyService的创建 / 235 7.4.2 重回AudioTrack / 245 7.4.3 声音路由切换实例分析 / 251 7.4.4 关于AudioPolicy的总结 / 262 7.5 拓展思考 / 262 7.5.1 DuplicatingThread破解 / 262 7.5.2 题外话 / 270 7.6 本章小结 / 272 第8章 深入理解Surface系统 / 273 8.1 概述 / 275 8.2 一个Activity的显示 / 275 8.2.1 Activity的创建 / 275 8.2.2 Activity的UI绘制 / 294 8.2.3 关于Activity的总结 / 296 8.3 初识Surface / 297 8.3.1 和Surface有关的流程总结 / 297 8.3.2 Surface之乾坤大挪移 / 298 8.3.3 乾坤大挪移的JNI层分析 / 303 8.3.4 Surface和画图 / 307 8.3.5 初识Surface小结 / 309 8.4 深入分析Surface / 310 8.4.1 与Surface相关的基础知识介绍 / 310 8.4.2 SurfaceComposerClient分析 / 315 8.4.3 SurfaceControl分析 / 320 8.4.4 writeToParcel和Surface对象的创建 / 331 8.4.5 lockCanvas和unlockCanvasAndPost分析 / 335 8.4.6 GraphicBuffer介绍 / 344 8.4.7 深入分析Surface的总结 / 353 8.5 SurfaceFlinger分析 / 353 8.5.1 SurfaceFlinger的诞生 / 354 8.5.2 SF工作线程分析 / 359 8.5.3 Transaction分析 / 368 8.5.4 关于SurfaceFlinger的总结 / 376 8.6 拓展思考 / 377 8.6.1 Surface系统的CB对象分析 / 377 8.6.2 ViewRoot的你问我答 / 384 8.6.3 LayerBuffer分析 / 385 8.7 本章小结 / 394 第9章 深入理解Vold和Rild / 395 9.1 概述 / 396 9.2 Vold的原理与机制分析 / 396 9.2.1 Netlink和Uevent介绍 / 397 9.2.2 初识Vold / 399 9.2.3 NetlinkManager模块分析 / 400 9.2.4 VolumeManager模块分析 / 408 9.2.5 CommandListener模块分析 / 414 9.2.6 Vold实例分析 / 417 9.2.7 关于Vold的总结 / 428 9.3 Rild的原理与机制分析 / 428 9.3.1 初识Rild / 430 9.3.2 RIL_startEventLoop分析 / 432 9.3.3 RIL_Init分析 / 437 9.3.4 RIL_register分析 / 444 9.3.5 关于Rild main函数的总结 / 447 9.3.6 Rild实例分析 / 447 9.3.7 关于Rild的总结 / 459 9.4 拓展思考 / 459 9.4.1 嵌入式系统的存储知识介绍 / 459 9.4.2 Rild和Phone的改进探讨 / 462 9.5 本章小结 / 463 第10章 深入理解MediaScanner / 464 10.1 概述 / 465 10.2 android.process.media分析 / 465 10.2.1 MSR模块分析 / 466 10.2.2 MSS模块分析 / 467 10.2.3 android.process.media媒体扫描工作的流程总结 / 471 10.3 MediaScanner分析 / 472 10.3.1 Java层分析 / 472 10.3.2 JNI层分析 / 476 10.3.3 PVMediaScanner分析 / 479 10.3.4 关于MediaScanner的总结 / 485 10.4 拓展思考 / 486 10.4.1 MediaScannerConnection介绍 / 486 10.4.2 我问你答 / 487 10.5 本章小结 / 488
第1章 阅读前的准备工作 1.1 系统架构 1.1.1 Android系统架构 1.1.2 本书的架构 1.2 搭建开发环境 1.2.1 下载源码 1.2.2 编译源码 1.3 工具介绍 1.3.1 Source Insight介绍 1.3.3 Busybox的使用 1.4 本章小结 第2章 深入理解JNI 2.1 JNI概述 2.2 学习JNI的实例:MediaScanner 2.3 Java层的MediaScanner分析 2.3.1 加载JNI库 2.3.2 Java的native函数和总结 2.4 JNI层MediaScanner的分析 2.4.1 注册JNI函数 2.4.2 数据类型转换 2.4.3 JNIEnv介绍 2.4.4 通过JNIEnv操作jobject 2.4.5 jstring介绍 2.4.6 JNI类型签名介绍 2.4.7 垃圾回收 2.4.8 JNI中的异常处理 2.5 本章小结 第3章 深入理解init 3.1 概述 3.2 init分析 3.2.1 解析配置文件 3.2.2 解析service 3.2.3 init控制service 3.2.4 属性服务 3.3 本章小结 第4章 深入理解zygote 4.1 概述 4.2 zygote分析 4.2.1 AppRuntime分析 4.2.2 Welcome to Java World 4.2.3 关于zygote的总结 4.3 SystemServer分析 4.3.1 SystemServer的诞生 4.3.2 SystemServer的重要使命 4.3.3 关于 SystemServer的总结 4.4 zygote的分裂 4.4.1 ActivityManagerService发送请求 4.4.2 有求必应之响应请求 4.4.3 关于zygote分裂的总结 4.5 拓展思考 4.5.1 虚拟机heapsize的限制 4.5.2 开机速度优化 4.5.3 Watchdog分析 4.6 本章小结 第5章 深入理解常见类 5.1 概述 5.2 以“三板斧”揭秘RefBase、sp和wp 5.2.1 第一板斧--初识影子对象 5.2.2 第二板斧--由弱生强 5.2.3 第三板斧--破解生死魔咒 5.2.4 轻量级的引用计数控制类LightRefBase 5.2.5 题外话-三板斧的来历 5.3 Thread类及常用同步类分析 5.3.1 一个变量引发的思考 5.3.2 常用同步类 5.4 Looper和Handler类分析 5.4.1 Looper类分析 5.4.2 Handler分析 5.4.3 Looper和Handler的同步关系 5.4.4 HandlerThread介绍 5.5 本章小结 第6章 深入理解Binder 6.1 概述 6.2 庖丁解MediaServer 6.2.1 MediaServer的入口函数 6.2.2 独一无二的ProcessState 6.2.3 时空穿越魔术-defaultServiceManager 6.2.4 注册MediaPlayerService 6.2.5 秋风扫落叶-StartThread Pool和join Thread Pool分析 6.2.6 你彻底明白了吗 6.3 服务总管ServiceManager 6.3.1 ServiceManager的原理 6.3.2 服务的注册 6.3.3 ServiceManager存在的意义 6.4 MediaPlayerService和它的Client 6.4.1 查询ServiceManager 6.4.2 子承父业 6.5 拓展思考 6.5.1 Binder和线程的关系 6.5.2 有人情味的讣告 6.5.3 匿名Service 6.6 学以致用 6.6.1 纯Native的Service 6.6.2 扶得起的“阿斗”(aidl) 6.7 本章小结 第7章 深入理解Audio系统 7.1 概述 7.2 AudioTrack的破解 7.2.1 用例介绍 7.2.2 AudioTrack(Java空间)分析 7.2.3 AudioTrack(Native空间)分析 7.2.4 关于AudioTrack的总结 7.3 AudioFlinger的破解 7.3.1 AudioFlinger的诞生 7.3.2 通过流程分析AudioFlinger 7.3.3 audio_track_cblk_t分析 7.3.4 关于AudioFlinger的总结 7.4 AudioPolicyService的破解 7.4.1 AudioPolicyService的创建 7.4.2 重回AudioTrack 7.4.3 声音路由切换实例分析 7.4.4 关于AudioPol

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值