最近几天的工作安排

刚开始实习,进入公司所干的事儿虽然和以前没有太大区别,都是看代码调试代码,但是这是与以前所看过的代码都不一样,需要补充相关的基础理论知识,需要静下心来,慢慢学习和补充。
以下是未来几天需要学习的内容:
一、Android 源码中智能指针的分析
在Android 底层运行库层源码中,经常会碰到sp<T>,wp<T>这样的代码,这是Google编写的针对C++指针释放的一种机制,有点类似于JAVA或者C#中垃圾回收机制,当某个对象没有被别人引用后,系统会自动回收。C++一般使用delete回收资源,为什么要使用这种所谓的智能指针呢?原因有二:一是很多程序猿编写C++代码时,忘记释放new出来的对象,或者不知道什么时候该释放这个对象;二是对象已经释放,在其他地方再次引用,造成指针异常;
程序猿在编写程序的时候需要精心设计程序,以避免上面两种问题,例如需要书写很多代码来检查输入的对象是不是已经释放掉了,在释放资源的时候还得考虑是不是其他地方还用到这个对象的引用。在引入智能指针概念以后,这种问题就变得很简单了,程序猿不用担心自己的new出来的对象没有释放而造成内存泄露,也不用担心引用已经释放的对象的引用,这样大大提高了程序的编写效率,同时也提高了系统的稳定性。
说了这么多废话,Google是如何实现所谓的智能指针的呢?
关于智能指针的定义和实现在这两个文件中:

frameworks\base\include\utils\RefBase.h

frameworks\base\libs\utils\RefBase.cpp
关于如何实现就不那么详细的说了!这里仅仅说说实现原理。智能指针通过引用计数来实现智能的,即每个对象在new的时候都会有一个计数值,来记录这个对象被引用的次数,被引用一次,这个计数值加一,当不再使用这个引用时,这个计数值就减一,当计数值减到一的时候,表示这个对象没有被引用了,可以自动销毁了。但是在实际应用中,不会直接孤立的定义一个新的变量来记录一个对象的引用次数,而是将新指针与这个计数值整合到一块,这样还有一个问题就是每次引用的时候主动调用加一,不用的时候调用减一,还是无法解决忘记加一或者忘记减一的问题,问题又回到了原点。在android中,引用计数功能就放在Refbase这个类中,这个类来实现计数的统计,以及对象的销毁,而引用计数何时加减问题,是通过另外一个类sp(Strong Pointer)来实现,通过这个类的构造和析构来实现引用计数的加减,这样就解决了计数的加减问题。如果仅仅使用单一的引用计数无法解决循环引用的问题,比如对象A引用了对象B,而在对象B中又引用了对象A,那么当对象A和B就无法被自动销毁,因为当系统发现A该销毁时,发现A还被B(B从哪里来呀?A中引用B)中引用着,这样系统就无法回收A,同样的道理,也无法回收A,这样就会出现内存泄露的问题了。但是办法总是比问题多,有问题就有解决问题的办法,使用两种计数值:强引用计数和弱引用计数,当父对象引用子对象时就对子对象使用强引用计数,当子对象引用父对象时,就对父对象采用弱引用计数,当强对象引用计数为零,就不管弱对象引用计数是否为零,就强制收回资源,当一个对象只有弱引用计数时,如果要使用这个对象,就要把这个对象提升为强引用计数才可以使用。
这样说还是非常抽象,看看如何使用以后就知道上面的意思。

class RefBase
{//这个类是很sp的基类,里面有引用计数的管理的相关实现
public:
	void            incStrong(const void* id) const;
	void            decStrong(const void* id) const;

	void            forceIncStrong(const void* id) const;

	//! DEBUGGING ONLY: Get current strong ref count.
	int32_t         getStrongCount() const;

	class weakref_type
	{//这里来处理强弱引用的问题
	public:
		RefBase*            refBase() const;

		void                incWeak(const void* id);
		void                decWeak(const void* id);

		bool                attemptIncStrong(const void* id);

		//! This is only safe if you have set OBJECT_LIFETIME_FOREVER.
		bool                attemptIncWeak(const void* id);

		//! DEBUGGING ONLY: Get current weak ref count.
		int32_t             getWeakCount() const;

		//! DEBUGGING ONLY: Print references held on object.
		void                printRefs() const;

		//! DEBUGGING ONLY: Enable tracking for this object.
		// enable -- enable/disable tracking
		// retain -- when tracking is enable, if true, then we save a stack trace
		//           for each reference and dereference; when retain == false, we
		//           match up references and dereferences and keep only the 
		//           outstanding ones.

		void                trackMe(bool enable, bool retain);
	};

	weakref_type*   createWeak(const void* id) const;

	weakref_type*   getWeakRefs() const;

	//! DEBUGGING ONLY: Print references held on object.
	inline  void            printRefs() const { getWeakRefs()->printRefs(); }

	//! DEBUGGING ONLY: Enable tracking of object.
	inline  void            trackMe(bool enable, bool retain)
	{
		getWeakRefs()->trackMe(enable, retain);
	}

protected:
	RefBase();
	virtual                 ~RefBase();

	//! Flags for extendObjectLifetime()
	enum {
		OBJECT_LIFETIME_WEAK    = 0x0001,
		OBJECT_LIFETIME_FOREVER = 0x0003
	};

	void            extendObjectLifetime(int32_t mode);

	//! Flags for onIncStrongAttempted()
	enum {
		FIRST_INC_STRONG = 0x0001
	};

	virtual void            onFirstRef();
	virtual void            onLastStrongRef(const void* id);
	virtual bool            onIncStrongAttempted(uint32_t flags, const void* id);
	virtual void            onLastWeakRef(const void* id);

private:
	friend class weakref_type;
	class weakref_impl;

	RefBase(const RefBase& o);
	RefBase&        operator=(const RefBase& o);

	weakref_impl* const mRefs;
};
对sp就只用关心其构造函数和析构函数,因为在构造和析构时实现计数加减

template<typename T>
sp<T>::sp(T* other)
    : m_ptr(other)
{
    if (other) other->incStrong(this);
}

template<typename T>
sp<T>::sp(const sp<T>& other)
    : m_ptr(other.m_ptr)
{
    if (m_ptr) m_ptr->incStrong(this);
}
template<typename T>
sp<T>::~sp()
{
    if (m_ptr) m_ptr->decStrong(this);
}
下面看看如何使用智能指针以及该注意的问题:
1、智能指针使用必须满足一下两个条件:一是使用智能指针的类必须是继承Refbase这个基类;二是析构函数必须是虚析构函数;
2、使用sp<T> obj=new T() 或者sp<T> obja=objb;注意这里obj是一个sp对象,不是一个指针(不管前一种方式还是第二种方式,都调用了sp的构造函数,实现计数值加减),因此当这个对象生命周期结束后,就会自动调用析构函数,来析构这个对象。
3、不要使用delete来删除sp对象,一定要注意这里的obj是一个对象,而不是一个指针。
到这里,需要问到,T对象上那里去了,T对象被保存到sp对象中的成员变量中m_ptr;




二、Android中进程间通信Binder机制分析
进程间通信机制有多种方式,常见的有基于共享内存、管道、基于套接字进程间通信机制,在Android中使用Binder机制实现进程间通信,相对于基于Socket和管道等传统的进程间通信机制,Binder机制更加系统化,易用性更好,进程间通信就像函数调用一样,实现结构化参数和返回值的传递。Binder机制并不是新提出的概念,而是基于OpenBinder实现来的,为了避开OpenBinder的许可问题,Google重新开发了一套Binder实现,是基于Apache协议发布的。
实现Binder进程通信由:服务端、客户端、Binder驱动和ServiceManager四个组件组成,服务器和客户端当然就是进程间通信的两个进程。下图给出了这四个组件在框架层的关系图:



服务端和客户端都是通过给底层Binder驱动通信来间接实现进程间通信的。Binder驱动程序是整个Binder机制的核心。

三、Android中Camera系统架构分析
四、Android中Surface系统分析
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值