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

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

  • 相关阅读:
    省市区三级联动
    jeDate日期控件
    Juery返回Json数据格式,webForm中使用
    JS补充
    winfrom中上传文件保存在webFrom里面
    游标
    函数
    触发器
    Leetcode练习(Python):数组类:第106题:根据一棵树的中序遍历与后序遍历构造二叉树。 注意: 你可以假设树中没有重复的元素。
    Leetcode练习(Python):数组类:第105题:根据一棵树的前序遍历与中序遍历构造二叉树。 注意: 你可以假设树中没有重复的元素。
  • 原文地址:https://www.cnblogs.com/xxss0903/p/5871742.html
Copyright © 2020-2023  润新知