zoukankan      html  css  js  c++  java
  • 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因为特殊原因,还没理解,所以具体不写了

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

  • 相关阅读:
    ASCII,Unicode 和 UTF-8
    ASCII,Unicode 和 UTF-8
    043_JVM——JVM是什么鬼啊?他与操作系统是什么关系?
    042_杂谈——编程语言的发展
    042_线程——我们写的代码,为什么我从来没有线程呢?
    041_ssm——/与/*与*.do的区别?
    040_HTTP——为什么会有get与post两种请求?
    039_Servlet——SpringMVC中怎么不见Servlet呢?我们写的Controller都是普通类,Servlet藏到了那里?
    038_JVM——怎么查看对象的内存大小?
    037_JVM——java中的类加载器是怎么运行的?
  • 原文地址:https://www.cnblogs.com/xxss0903/p/5871742.html
Copyright © 2011-2022 走看看