前言:在最近的面试过程中,有一次偶然的问到了候选者的Toast的源码的问题,我发现很多人基本上对Toast怎么使用了然于心,但是它的原理却是不怎么关注,所以我今天打算写篇文章来介绍一下Toast的源码原理,希望给那些想要了解Toast原理的同学看看。
这篇文章只是从解析源码的角度给大家分析Toast的,所以可能枯燥一点,请用点耐心开始看吧。。。
由于懒得大量的手敲资料了,所以这篇文章引用了一些其他文章的资料,在此先表示万分感谢!!!
我们平时对Toast的常规调用就是:
Toast.makeText(this,"meng",Toast.LENGTH_LONG).show();
从咱们的调用开始,我们先来看看makeText()方法的源码:
public static Toast makeText(Context context, CharSequence text, @Duration int duration) {
Toast result = new Toast(context);
LayoutInflater inflate = (LayoutInflater)
context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View v = inflate.inflate(com.android.internal.R.layout.transient_notification, null);
TextView tv = (TextView)v.findViewById(com.android.internal.R.id.message);
tv.setText(text);
result.mNextView = v;
result.mDuration = duration;
return result;
}
对于这里的Toast的makeText的实现,首先,第一行代码,Toast result = new Toast(context),去调用Toast的构造方法来初始化了一个Toast,是怎么初始化的呢?
大家来看看Toast构造方法的代码是怎么样的:
public Toast(Context context) {
mContext = context;
mTN = new TN();
mTN.mY = context.getResources().getDimensionPixelSize(
com.android.internal.R.dimen.toast_y_offset);
mTN.mGravity = context.getResources().getInteger(
com.android.internal.R.integer.config_toastDefaultGravity);
}
从上面的源码中我们可以看到,Toast的初始化需要上下文,这也是我们在调用Toast的时候,都必须获取上下文的原因。然后新建了一个mTN对象,mTN是一个binder对象,用于IPC。
在这部分代码实现中,这个TN的初始化操作主要是进行了Window布局元素的创建,具体的逻辑请看下面的代码:
TN() {
// XXX This should be changed to use a Dialog, with a Theme.Toast
// defined that sets up the layout params appropriately.
final WindowManager.LayoutParams params = mParams;
params.height = WindowManager.LayoutParams.WRAP_CONTENT;
params.width = WindowManager.LayoutParams.WRAP_CONTENT;
params.format = PixelFormat.TRANSLUCENT;
params.windowAnimations = com.android.internal.R.style.Animation_Toast;
params.type = WindowManager.LayoutParams.TYPE_TOAST;
params.setTitle("Toast");
params.flags = WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON
| WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
| WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
}
在完成了Toast的初始化之后,我们接着跳出到