android Toast和ProgressBar在子线程中更新

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因为特殊原因,还没理解,所以具体不写了

 

上面的总结肯定有不足,在目前情况下简单看了代码的理解,不知正确与否,不负责

 

posted @ 2016-09-14 13:14  乌拉小考  阅读(926)  评论(0)    收藏  举报