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

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

  • 相关阅读:
    『轉』windows文件的占用空间与文件大小
    『轉』asterisk入门连载二
    vm系統出現This Virtual Machine Appears To Be In Use的問題
    linux 7788
    鸿蒙开发板外设控制 之 实现按键“按下事件”和“释放事件”的通用框架(V0.0.1)
    【开发板试用报告】学习GPIO编程
    前言「HarmonyOS应用开发基础篇」
    【开发板试用报告】鸿蒙OS环境搭建及代码烧录
    动态设置和访问cxgrid列的Properties
    cxgrid导出excel
  • 原文地址:https://www.cnblogs.com/xxss0903/p/5871742.html
Copyright © 2011-2022 走看看