package zzx.lly.custom_view.view;import android.content.Context;import android.content.res.TypedArray;import android.graphics.Canvas;import android.graphics.Color;import android.graphics.Paint;import android.os.AsyncTask;import android.util.AttributeSet;import android.util.Log;import android.view.View;import zzx.lly.custom_view.R;public class Change_view extends View {    //process determine the stage of this view that should be draw    private int process;    private Paint mPaint1;    private int colorBegin;    private int colorEnd=0;    //在java代码则调用该构造方法    public Change_view(Context context) {        super(context);        init();    }    //在xml调用时调用    public Change_view(Context context, AttributeSet attrs) {        this(context, attrs, 0);        init();    }    //不会自动调用,一般是在第二个构造方法里面主动调用,如view有style属性时候    public Change_view(Context context, AttributeSet attrs, int defStyleAttr) {        super(context, attrs, defStyleAttr);        TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.Change_view);        colorBegin = a.getColor(R.styleable.Change_view_circle_color, Color.RED);        a.recycle();        colorEnd=colorBegin;        init();    }    public Change_view(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {        super(context, attrs, defStyleAttr, defStyleRes);    }    private void init() {        mPaint1 = new Paint();        mPaint1.setColor(colorEnd);        mPaint1.setStrokeWidth(5f);        mPaint1.setStyle(Paint.Style.FILL_AND_STROKE);    }    @Override    protected void onDraw(Canvas canvas) {        super.onDraw(canvas);        mPaint1.setColor(colorEnd);        int width = getWidth();        int height = getHeight();        int r = Math.min(width, height) / 2;        canvas.drawCircle(width / 2, height / 2, r, mPaint1);        Log.e("E", "draw");    }    @Override    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {        super.onMeasure(widthMeasureSpec, heightMeasureSpec);        int widthMode = MeasureSpec.getMode(widthMeasureSpec);        int widthSize = MeasureSpec.getSize(widthMeasureSpec);        int heightMode = MeasureSpec.getMode(heightMeasureSpec);        int heightSize = MeasureSpec.getSize(heightMeasureSpec);        int mWidth = 400;        int mHeight = 400;        if (widthMode == MeasureSpec.AT_MOST && heightMode == MeasureSpec.AT_MOST) {            setMeasuredDimension(mWidth, mHeight);        } else if (widthMode == MeasureSpec.AT_MOST) {            setMeasuredDimension(mWidth, heightSize);        } else if (heightMode == MeasureSpec.AT_MOST) {            setMeasuredDimension(widthSize, mHeight);        }    }    //接下来实现异步变换颜色,1,通过Async或者rxjava    class ColorChangeAsycTask extends AsyncTask<Void, Void, Void> {        @Override        protected void onPreExecute(){            super.onPreExecute();            colorEnd=colorBegin;        }        @Override //Result               params        protected Void doInBackground(Void... voids) {            while(true){                colorEnd-=20;                Log.e("E","colorChange");                if (colorEnd <= colorBegin/2) {                    colorEnd=colorBegin;                }                try {                    Thread.sleep(10);                } catch (InterruptedException e) {                    e.printStackTrace();                }                publishProgress();            }        }        @Override                    //Result        protected void onPostExecute(Void m) {            super.onPostExecute(m);        }        @Override                       //progress        protected void onProgressUpdate(Void... m) {            invalidate();        }    }    @Override//为了避免错误,我们在这里将Async new出来并实现,因为在构造方法中界面不一定初始完成    protected void onAttachedToWindow() {        Log.e("E", "beforeOnAttach");        super.onAttachedToWindow();        Log.e("E", "AfterOnAttach");        new ColorChangeAsycTask().execute();        Log.e("E", "onAttach");    }}

Log日志 |11-23 21:53:24.263 11194-11194/zzx.lly.custom_view E/E:
beforeOnAttach
AfterOnAttach 11-23 21:53:24.265 11194-11194/zzx.lly.custom_view E/E: onAttach 11-23 21:53:24.266 11194-11220/zzx.lly.custom_view E/E:
colorChange 11-23 21:53:24.276 11194-11220/zzx.lly.custom_view E/E:
colorChange 11-23 21:53:24.286 11194-11220/zzx.lly.custom_view E/E:
colorChange 11-23 21:53:24.297 11194-11220/zzx.lly.custom_view E/E:
colorChange 11-23 21:53:24.303 11194-11219/zzx.lly.custom_view E/GED:
Failed to get GED Log Buf, err(0) 11-23 21:53:24.307
11194-11220/zzx.lly.custom_view E/E: colorChange 11-23 21:53:24.317
11194-11220/zzx.lly.custom_view E/E: colorChange 11-23 21:53:24.328
11194-11220/zzx.lly.custom_view E/E: colorChange 11-23 21:53:24.331
11194-11194/zzx.lly.custom_view E/E: draw 11-23 21:53:24.338
11194-11220/zzx.lly.custom_view E/E: colorChange 11-23 21:53:24.348
11194-11220/zzx.lly.custom_view E/E: colorChange 11-23 21:53:24.358
11194-11220/zzx.lly.custom_view E/E: colorChange 11-23 21:53:24.369
11194-11220/zzx.lly.custom_view E/E: colorChange 11-23 21:53:24.379
11194-11220/zzx.lly.custom_view E/E: colorChange 11-23 21:53:24.389
11194-11220/zzx.lly.custom_view E/E: colorChange 11-23 21:53:24.400
11194-11220/zzx.lly.custom_view E/E: colorChange 11-23 21:53:24.410
11194-11220/zzx.lly.custom_view E/E: colorChange 11-23 21:53:24.417
11194-11194/zzx.lly.custom_view E/E: draw 11-23 21:53:24.420
11194-11220/zzx.lly.custom_view E/E: colorChange 11-23 21:53:24.428
11194-11194/zzx.lly.custom_view E/E: draw 11-23 21:53:24.431
11194-11220/zzx.lly.custom_view E/E: colorChange 11-23 21:53:24.441
11194-11220/zzx.lly.custom_view E/E: colorChange 11-23 21:53:24.445
11194-11194/zzx.lly.custom_view E/E: draw 11-23 21:53:24.451
11194-11220/zzx.lly.custom_view E/E: colorChange 11-23 21:53:24.461
11194-11194/zzx.lly.custom_view E/E: draw 11-23 21:53:24.462
11194-11220/zzx.lly.custom_view E/E: colorChange 11-23 21:53:24.472
11194-11220/zzx.lly.custom_view E/E: colorChange 11-23 21:53:24.478
11194-11194/zzx.lly.custom_view E/E: draw 11-23 21:53:24.482
11194-11220/zzx.lly.custom_view E/E: colorChange 11-23 21:53:24.493
11194-11220/zzx.lly.custom_view E/E: colorChange 11-23 21:53:24.494
11194-11194/zzx.lly.custom_view E/E: draw 11-23 21:53:24.503
11194-11220/zzx.lly.custom_view E/E: colorChange 11-23 21:53:24.511
11194-11194/zzx.lly.custom_view E/E: draw 11-23 21:53:24.513
11194-11220/zzx.lly.custom_view E/E: colorChange 11-23 21:53:24.524
11194-11220/zzx.lly.custom_view E/E: colorChange 11-23 21:53:24.527
11194-11194/zzx.lly.custom_view E/E: draw 11-23 21:53:24.534
11194-11220/zzx.lly.custom_view E/E: colorChange 11-23 21:53:24.544
11194-11194/zzx.lly.custom_view E/E: draw 11-23 21:53:24.544
11194-11220/zzx.lly.custom_view E/E: colorChange 11-23 21:53:24.555
11194-11220/zzx.lly.custom_view E/E: colorChange 11-23 21:53:24.560
11194-11194/zzx.lly.custom_view E/E: draw 11-23 21:53:24.565
11194-11220/zzx.lly.custom_view E/E: colorChange

问题是什么?

我们知道onAttachToWindow(以下简称ATW)发生在view被添加到屏幕,这个过程在是onResume之后,draw之前,所以我们这里可以看到先被打印的是关于ATW的内容,ATW开启异步改变颜色的线程,问题在于我们看到本来应当是打印一次colorChange会发生一次invalidate,invalidate应当要调用ondraw,但是显然,这里在一开始的时候,出现了多次colorChange,说明在ATW之后相当长的一段时间内,ondraw都不能被调用.当然后面有出现一两个colorChange对应一个ondraw的情况,这是因为我们的子线程速度太快了,如果sleep时间稍微长一点就不会出现这种情况了.
尝试一下

  colorEnd-=20;                Log.e("E","colorChange");                if (colorEnd <= colorBegin/2) {                    colorEnd=colorBegin;                }                try {                    Thread.sleep(50);                } catch (InterruptedException e) {                    e.printStackTrace();                }

我们在这里将原本10毫秒休息一次改为50毫秒休息一次,然后再看日志,可以看到,现在一开始不响应的colorChange少了(这是因为子线程运行次数减少),并且一次colorChange一定有一次draw响应,符合预期.

11-23 22:06:23.717 12076-12076/zzx.lly.custom_view E/E: beforeOnAttach
AfterOnAttach 11-23 22:06:23.720 12076-12076/zzx.lly.custom_view E/E: onAttach 11-23 22:06:23.722 12076-12256/zzx.lly.custom_view E/E:
colorChange 11-23 22:06:23.774 12076-12256/zzx.lly.custom_view E/E:
colorChange 11-23 22:06:23.780 12076-12255/zzx.lly.custom_view E/GED:
Failed to get GED Log Buf, err(0) 11-23 22:06:23.824
12076-12256/zzx.lly.custom_view E/E: colorChange 11-23 22:06:23.839
12076-12076/zzx.lly.custom_view E/E: draw 11-23 22:06:23.877
12076-12256/zzx.lly.custom_view E/E: colorChange 11-23 22:06:23.928
12076-12256/zzx.lly.custom_view E/E: colorChange 11-23 22:06:23.978
12076-12256/zzx.lly.custom_view E/E: colorChange 11-23 22:06:24.009
12076-12076/zzx.lly.custom_view E/E: draw 11-23 22:06:24.028
12076-12256/zzx.lly.custom_view E/E: colorChange 11-23 22:06:24.033
12076-12076/zzx.lly.custom_view E/E: draw 11-23 22:06:24.049
12076-12076/zzx.lly.custom_view E/E: draw 11-23 22:06:24.079
12076-12256/zzx.lly.custom_view E/E: colorChange 11-23 22:06:24.096
12076-12076/zzx.lly.custom_view E/E: draw 11-23 22:06:24.129
12076-12256/zzx.lly.custom_view E/E: colorChange 11-23 22:06:24.146
12076-12076/zzx.lly.custom_view E/E: draw 11-23 22:06:24.180
12076-12256/zzx.lly.custom_view E/E: colorChange 11-23 22:06:24.195
12076-12076/zzx.lly.custom_view E/E: draw 11-23 22:06:24.230
12076-12256/zzx.lly.custom_view E/E: colorChange 11-23 22:06:24.245
12076-12076/zzx.lly.custom_view E/E: draw 11-23 22:06:24.281
12076-12256/zzx.lly.custom_view E/E: colorChange 11-23 22:06:24.294
12076-12076/zzx.lly.custom_view E/E: draw 11-23 22:06:24.331
12076-12256/zzx.lly.custom_view E/E: colorChange 11-23 22:06:24.344
12076-12076/zzx.lly.custom_view E/E: draw 11-23 22:06:24.381
12076-12256/zzx.lly.custom_view E/E: colorChange 11-23 22:06:24.393
12076-12076/zzx.lly.custom_view E/E: draw 11-23 22:06:24.432
12076-12256/zzx.lly.custom_view E/E: colorChange 11-23 22:06:24.442
12076-12076/zzx.lly.custom_view E/E: draw 11-23 22:06:24.482
12076-12256/zzx.lly.custom_view E/E: colorChange 11-23 22:06:24.492
12076-12076/zzx.lly.custom_view E/E: draw 11-23 22:06:24.532
12076-12256/zzx.lly.custom_view E/E: colorChange 11-23 22:06:24.541
12076-12076/zzx.lly.custom_view E/E: draw 11-23 22:06:24.583
12076-12256/zzx.lly.custom_view E/E: colorChange 11-23 22:06:24.591
12076-12076/zzx.lly.custom_view E/E: draw 11-23 22:06:24.633
12076-12256/zzx.lly.custom_view E/E: colorChange 11-23 22:06:24.641
12076-12076/zzx.lly.custom_view E/E: draw 11-23 22:06:24.685
12076-12256/zzx.lly.custom_view E/E: colorChange 11-23 22:06:24.691
12076-12076/zzx.lly.custom_view E/E: draw 11-23 22:06:24.736
12076-12256/zzx.lly.custom_view E/E: colorChange 11-23 22:06:24.740
12076-12076/zzx.lly.custom_view E/E: draw 11-23 22:06:24.788
12076-12256/zzx.lly.custom_view E/E: colorChange 11-23 22:06:24.789
12076-12076/zzx.lly.custom_view E/E: draw 11-23 22:06:24.840
12076-12256/zzx.lly.custom_view E/E: colorChange 11-23 22:06:24.855
12076-12076/zzx.lly.custom_view E/E: draw 11-23 22:06:24.892
12076-12256/zzx.lly.custom_view E/E: colorChange 11-23 22:06:24.904
12076-12076/zzx.lly.custom_view E/E: draw 11-23 22:06:24.944
12076-12256/zzx.lly.custom_view E/E: colorChange 11-23 22:06:24.954
12076-12076/zzx.lly.custom_view E/E: draw 11-23 22:06:24.994
12076-12256/zzx.lly.custom_view E/E: colorChange 11-23 22:06:25.004
12076-12076/zzx.lly.custom_view E/E: draw 11-23 22:06:25.046
12076-12256/zzx.lly.custom_view E/E: colorChange 11-23 22:06:25.053
12076-12076/zzx.lly.custom_view E/E: draw 11-23 22:06:25.097
12076-12256/zzx.lly.custom_view E/E: colorChange 11-23 22:06:25.111
12076-12076/zzx.lly.custom_view E/E: draw 11-23 22:06:25.148
12076-12256/zzx.lly.custom_view E/E: colorChange 11-23 22:06:25.152
12076-12076/zzx.lly.custom_view E/E: draw 11-23 22:06:25.201
12076-12256/zzx.lly.custom_view E/E: colorChange 11-23 22:06:25.202
12076-12076/zzx.lly.custom_view E/E: draw 11-23 22:06:25.253
12076-12256/zzx.lly.custom_view E/E: colorChange 11-23 22:06:25.268
12076-12076/zzx.lly.custom_view E/E: draw 11-23 22:06:25.305
12076-12256/zzx.lly.custom_view E/E: colorChange 11-23 22:06:25.317
12076-12076/zzx.lly.custom_view E/E: draw 11-23 22:06:25.356
12076-12256/zzx.lly.custom_view E/E: colorChange 11-23 22:06:25.367
12076-12076/zzx.lly.custom_view E/E: draw 11-23 22:06:25.409
12076-12256/zzx.lly.custom_view E/E: colorChange 11-23 22:06:25.416
12076-12076/zzx.lly.custom_view E/E: draw 11-23 22:06:25.466
12076-12256/zzx.lly.custom_view E/E: colorChange 11-23 22:06:25.482
12076-12076/zzx.lly.custom_view E/E: draw

总结

我们这里其实要实现这个效果不应当在ATW开启,而是应当在onDraw中进行一个判断,如果是第一次draw则开启子线程.另外使用Async也很麻烦,在实际中可以用rxjava代替

更多相关文章

  1. android 自定义线程池ThreadPoolUtils工具类
  2. Android SDK Manager 更新失败的解决方法
  3. Android三种方法设置ImageView的图片
  4. Android进程与线程基本知识四
  5. 全志A64 Android7.1屏蔽使用按键进入安全模式的方法
  6. Android使用AttributeSet自定义控件的方法
  7. 让Android不播放关机动画,而是显示一个关机进度条的方法
  8. android下拉菜单spinner的使用方法

随机推荐

  1. 第8章 运用手机多媒体
  2. Android 数据存储 之 SQLite数据库详解
  3. Android FragmentManager BackStackRecor
  4. Android之利用正则表达式校验邮箱、手机
  5. android studio " Could not resolve com
  6. Android(安卓)ViewPager的简单使用
  7. Fragment实现android的设置界面切换效果
  8. Android精准的获取底部虚拟键盘的高度
  9. SmaterWeatherApi---签名加密和数据访问-
  10. android链接服务器获取图片三种方法。