Toast和ProgressBar能够在子线程中更新界面,和SurfaceView的不同的原因
1. Toast,先来看代码分析
Toast.makeText(context, "Toast的打印测试", Toast.LENGTH_SHORT).show(); // 使用Toast时的代码
进入makeText的源代码
public static Toast makeText(Context context, CharSequence text, @Duration int duration) { Toast result = new Toast(context); // 创建一个Toast LayoutInflater inflate = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); View v = inflate.inflate(com.android.internal.R.layout.transient_notification, null); // 获取Toast的布局View TextView tv = (TextView)v.findViewById(com.android.internal.R.id.message); // 拿到Toast上显示的TextView子控件,用来显示我们添加在Toast上面的文字
tv.setText(text); result.mNextView = v; result.mDuration = duration; return result; }
然后我们去查看初始化Toast的代码
public Toast(Context context) { mContext = context; // 付给这个Toast上下文 mTN = new TN(); // 创建一个TN(Transient Notification的缩写)对象,这个类中就封装了一个mHandler用来发送消息让UI线程处理Toast界面更新的
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); }
在TN中创建了一个mHandler,然后由一个show方法让这个handler发送消息
/** * schedule handleShow into the right thread */ @Override public void show() { if (localLOGV) Log.v(TAG, "SHOW: " + this); mHandler.post(mShow); // handler发送消息,是不是就是在这里通过发送handler发送消息得以让toast能够在子线程中也使用呢?初学,看到这里认为是这样的 }
所以从上面的代码可以看出Toast能够在子线程中处理也是因为有这个mHandler发送了消息到主线程中让主线程来处理更新UI的消息的
2. ProgressBar
ProgressBar pb = new ProgressBar(this); // 初始化一个ProgressBar
// 初始化pb最终调用的是
public ProgressBar(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes){
...
setMax(a.getInt(R.styleable.ProgressBar_max, mMax)); // 这里用设置最大值长度为例,设置progress调用的方法一样
setProgress(a.getInt(R.styleable.ProgressBar_progress, mProgress));
...
}
在setMax和setProgress这样需要操作界面的方法中调用了refreshProgress方法,传入了进度条的一些信息,比如长度等
refreshProgress(R.id.progress, mProgress, fromUser){
...
doRefreshProgress(id, progress, fromUser, true){
...
onProgressRefresh(scale, fromUser, progress){
scheduleAccessibilityEventSender(){
/*Causes the Runnable to be added to the message queue, to be run
* after the specified amount of time elapses.*/
postDelayed(mAccessibilityEventSender, TIMEOUT_SEND_ACCESSIBILITY_EVENT); // 最终调用了这个方法,根据注释可以知道这个方法是在ui线程中运行的也就解释了ProgressBar能够在子线程中更新界面的原因
}
}
...
}
...
}
3. SurfaceView因为特殊原因,还没理解,所以具体不写了
上面的总结肯定有不足,在目前情况下简单看了代码的理解,不知正确与否,不负责