本帖最后由 zgy441008825 于 2012-08-31 11:36:02 编辑

解决方案 »

  1.   

    这样在子线程和主线程之间交互的问题还真有点复杂。我还不知道这个是怎么回事,我建议, 把那个runnable去掉,写个函数。
    用一个for循环
     int t = 当前时间;
      for(int i = 0; i < 6; i++){
       sendMessageDelayed(Message,t + i *100);}
    这样就能依次延时100毫秒发消息,而且在UI线程。
    然后那边handleMessage里面调用mCanvas.drawRect(),全部在UI线程做试试。希望我的回答能给楼主帮助。
      

  2.   

    按照楼上的意思 改正这样的
    import java.util.Calendar;
    import android.annotation.SuppressLint;
    import android.content.Context;
    import android.graphics.Canvas;
    import android.graphics.Color;
    import android.graphics.Paint;
    import android.os.Handler;
    import android.os.Message;
    import android.util.DisplayMetrics;
    import android.view.View;public class Histogram extends View implements Runnable{ private int displayw = 0;
    private int displayy = 0;
    private static int cardinalX = 0; // 第一个矩形X轴基点
    private static int cardinalY = 0; // 第一个矩形Y轴基点
    private static int rectwidth = 30; // 矩形宽
    private static int rectheight = 15; // 矩形高
    private static int betweenrect = 2;
    int x_end, y_end, temp;
    Paint paint = new Paint();
    boolean flag = true;
    Canvas mCanvas; public Histogram(Context context) {
    super(context);
    DisplayMetrics dm = MainActivity.getdm();
    displayw = dm.widthPixels;
    displayy = dm.heightPixels;
    cardinalX = displayw - displayw / 5;
    cardinalY = displayy - displayy / 5;
    x_end = cardinalX + rectwidth;
    y_end = cardinalY + rectheight;
    temp = rectheight + betweenrect;
    paint.setAntiAlias(true);
    paint.setColor(Color.BLUE);

    // TODO Auto-generated constructor stub
    } @SuppressLint("DrawAllocation")
    @Override
    protected void onDraw(Canvas canvas) {
    // TODO Auto-generated method stub
    super.onDraw(canvas);

    mCanvas = canvas;
    this.run();
    } Handler mHandler = new Handler() {
    @Override
    public void handleMessage(Message msg) {
    // TODO Auto-generated method stub
    super.handleMessage(msg);

    switch(msg.what){
    case 0x01:{
    mCanvas.drawRect(cardinalX, cardinalY -= temp, x_end, y_end -= temp,paint);
    System.out.println(" "+mCanvas);
    }break;
    }
    }
    }; @Override
    public void run() {
    // TODO Auto-generated method stub
    for(int i = 0; i < 6; i++){
    mHandler.sendEmptyMessageDelayed(0x01,i*1000);
    }
    }}但是直接就看不到效果了  什么都没画出来  不过下面的System能正常的延时打印
      

  3.   

    这个VIEW implements Runnable我怎么感觉怪怪的。试过把implements Runnable删掉,然后把run()换个名字在onDraw()里面调用吗?仅是好奇
      

  4.   

     @Override
        protected void onDraw(Canvas canvas) {
            // TODO Auto-generated method stub
            super.onDraw(canvas);
            
            mCanvas = canvas; // Don't do this !!!
            this.run();
        }If you want to use the canvas elsewhere,
    extends your class from SurfaceView.
      

  5.   

    我把所有代码都贴出来吧
    MainActivityimport android.app.Activity;
    import android.os.Bundle;
    import android.util.DisplayMetrics;
    import android.view.ViewGroup;
    import android.view.ViewGroup.LayoutParams;public class MainActivity extends Activity {

    private static DisplayMetrics dm = new DisplayMetrics();
    private Histogram mHistogram;    @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);                        //覆盖父类的onCreate方法
            getWindowManager().getDefaultDisplay().getMetrics(dm);
            ViewGroup viewGroup=(ViewGroup)getLayoutInflater().inflate(R.layout.activity_main,null);
            mHistogram = new Histogram(this);        //将画布放置在两个按键下面
            viewGroup.addView(mHistogram,new LayoutParams(LayoutParams.FILL_PARENT,dm.heightPixels));
            setContentView(viewGroup);
        }
        
    public static DisplayMetrics getdm(){

    return dm;
    }}package com.zou.test;import android.content.Context;
    import android.graphics.Canvas;
    import android.graphics.Color;
    import android.graphics.Paint;
    import android.util.DisplayMetrics;
    import android.view.View;public class Histogram extends View{ private int displayw = 0;
    private int displayy = 0;
    private static int cardinalX = 0; // 第一个矩形X轴基点
    private static int cardinalY = 0; // 第一个矩形Y轴基点
    private static int rectwidth = 30; // 矩形宽
    private static int rectheight = 15; // 矩形高
    private static int betweenrect = 2;
    int x_end, y_end, temp;
    Paint paint = new Paint();
    boolean flag = true;
    Canvas mCanvas;
    HistogramThread myHistogramThread = null; public Histogram(Context context) {
    super(context);
    DisplayMetrics dm = MainActivity.getdm();
    displayw = dm.widthPixels;
    displayy = dm.heightPixels;
    cardinalX = displayw - displayw / 5;
    cardinalY = displayy - displayy / 5;
    x_end = cardinalX + rectwidth;
    y_end = cardinalY + rectheight;
    temp = rectheight + betweenrect;

    myHistogramThread = new HistogramThread(this);

    paint.setAntiAlias(true);
    paint.setColor(Color.BLUE);
    System.out.println("构造完成");
    } @Override
    protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);
    // mCanvas = canvas;
    // myHistogramThread.start();
    // System.out.println(canvas);

    for(int i=0; i<6; i++){
    canvas.drawRect(cardinalX, cardinalY -= temp, x_end, y_end -= temp,paint);
    try {
    Thread.sleep(500);
    } catch (InterruptedException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    }//这里加了sleep就不能显示 不加就可以
    }
    }

    //这个方法是在HistogramThread 中调用的 现在没用启动它 启动之后跟上面加了sleep的效果一样
    public void doDraw(){
    System.out.println("Histogram--重绘--"+mCanvas);
    mCanvas.drawRect(cardinalX, cardinalY -= temp, x_end, y_end -= temp,paint);
    System.out.println(cardinalX+" "+cardinalY+" "+" "+x_end+" "+y_end);
    }
    }
    HistogramThread public class HistogramThread extends Thread{ Histogram father; // WelcomeView对象的引用   
        int sleepSpan = 100; // 休眠时间   
        boolean flag; // 线程执行标志位   
      
        // 构造器:初始化主要的成员变量   
        public HistogramThread(Histogram father) {  
            this.father = father;
            this.flag = true;  
        }  
      
        // 方法:线程执行方法   
        public void run() {
            for(int i = 0; i < 6; i++){        
             System.out.println("Thread-------重绘");
             father.doDraw(); // 重新绘制屏幕   }
            }
        }
    }
    感觉只要有线程在绘图里面就不能显示了 但是绘图的方法还是会执行的 就是显示不出来
      

  6.   

    画一次重绘一次才会有效果- -~你只是画却没有重绘当然不行咯,另外这代码真是一团乱,既然是线程,又怎么会直接调用run()方法,这是违背java机制的……,直接调用run(),不是意味着在主线程中执行这个方法么?何来另起线程一说,这样根本无法让线程sleep嘛。给你改了一下,没做测试,自己试试吧package com.android.et_billing;import android.annotation.SuppressLint;
    import android.content.Context;
    import android.graphics.Canvas;
    import android.graphics.Color;
    import android.graphics.Paint;
    import android.os.Handler;
    import android.os.Message;
    import android.util.DisplayMetrics;
    import android.view.View;public class Histogram extends View implements Runnable{    private int displayw = 0;
        private int displayy = 0;
        private static int cardinalX = 0; // 第一个矩形X轴基点
        private static int cardinalY = 0; // 第一个矩形Y轴基点
        private static int rectwidth = 30; // 矩形宽
        private static int rectheight = 15; // 矩形高
        private static int betweenrect = 2;
        int x_end, y_end, temp;
        Paint paint = new Paint();
        boolean flag = true;
        Canvas mCanvas;    public Histogram(Context context) {
            super(context);
            displayw = dm.widthPixels;
            displayy = dm.heightPixels;
            cardinalX = displayw - displayw / 5;
            cardinalY = displayy - displayy / 5;
            x_end = cardinalX + rectwidth;
            y_end = cardinalY + rectheight;
            temp = rectheight + betweenrect;
            paint.setAntiAlias(true);
            paint.setColor(Color.BLUE);
            new Thread(this).start();  //启动线程,系统会自动调用run()方法,这样做才能使线程休眠
            
            // TODO Auto-generated constructor stub
        }    @SuppressLint("DrawAllocation")
        @Override
        protected void onDraw(Canvas canvas) {
            // TODO Auto-generated method stub
            super.onDraw(canvas);
            mCanvas = canvas;
        }    Handler mHandler = new Handler() {
            @Override
            public void handleMessage(Message msg) {
                // TODO Auto-generated method stub
                super.handleMessage(msg);
            }
        };    @Override
        public void run() {
            // TODO Auto-generated method stub
            
            for(int i = 0; i < 6; i++){
                mCanvas.drawRect(cardinalX, cardinalY -= temp, x_end, y_end -= temp,paint);
    //            invalidate();//错误重绘,这个方法只能在主线程中执行,要用他的话,就通过mHandler来与主线程通信吧
                postInvalidate();  //重绘画布,使用post方法,可以不用传到主线程中去更新界面
                 //注意:重绘画布,系统会调用onDraw(Canvas canvas)方法,所以你刚刚在onDraw()调用run()是不行的,重绘时会进入死循环
                try {
                    Thread.sleep(100);  
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }}
      

  7.   

    上面7楼的也不行啊 这样的话mCanvas就没有值了 是空的 我改成这样的也不行
    package com.zou.test;import android.annotation.SuppressLint;
    import android.content.Context;
    import android.graphics.Canvas;
    import android.graphics.Color;
    import android.graphics.Paint;
    import android.os.Handler;
    import android.os.Message;
    import android.util.DisplayMetrics;
    import android.view.View;public class Histogram extends View implements Runnable { private int displayw = 0;
    private int displayy = 0;
    private static int cardinalX = 0; // 第一个矩形X轴基点
    private static int cardinalY = 0; // 第一个矩形Y轴基点
    private static int rectwidth = 30; // 矩形宽
    private static int rectheight = 15; // 矩形高
    private static int betweenrect = 2;
    int x_end, y_end, temp;
    Paint paint = new Paint();
    boolean flag = true;
    Canvas mCanvas; public Histogram(Context context) {
    super(context); DisplayMetrics dm = MainActivity.getdm();
    displayw = dm.widthPixels;
    displayy = dm.heightPixels;
    cardinalX = displayw - displayw / 5;
    cardinalY = displayy - displayy / 5;
    x_end = cardinalX + rectwidth;
    y_end = cardinalY + rectheight;
    temp = rectheight + betweenrect;
    paint.setAntiAlias(true);
    paint.setColor(Color.BLUE);
    System.out.println("构造完成"); // TODO Auto-generated constructor stub
    } @Override
    protected void onDraw(Canvas canvas) {
    // TODO Auto-generated method stub
    super.onDraw(canvas);
    mCanvas = canvas;
    System.out.println("onDraw "+canvas+"  "+mCanvas);
    }

    public void startThread(){
    new Thread(Histogram.this).start(); // 启动线程,系统会自动调用run()方法,这样做才能使线程休眠
    } Handler mHandler = new Handler() {
    @Override
    public void handleMessage(Message msg) {
    // TODO Auto-generated method stub
    super.handleMessage(msg);
    switch (msg.what) {
    case 0x01: {
    // 注意:重绘画布,系统会调用onDraw(Canvas
    // canvas)方法,所以你刚刚在onDraw()调用run()是不行的,重绘时会进入死循环
    invalidate();// 错误重绘,这个方法只能在主线程中执行,要用他的话,就通过mHandler来与主线程通信吧
    postInvalidate(); //重绘画布,使用post方法,可以不用传到主线程中去更新界面
    System.out.println("绘图"+mCanvas);
    mCanvas.drawRect(cardinalX, cardinalY -= temp, x_end,y_end -= temp, paint);

    // postInvalidate(); //重绘画布,使用post方法,可以不用传到主线程中去更新界面
    }
    break;
    }
    }
    }; @Override
    public void run() {
    // TODO Auto-generated method stub for (int i = 0; i < 6; i++) {
    mHandler.sendEmptyMessageDelayed(0x01,i*2000);
    }
    }}
    然后在MainActivity里面实例化这个对象后调用了startThread()  也不行
      

  8.   

    上面的写错了一点 invalidate();// 错误重绘,这个方法只能在主线程中执行,要用他的话,就通过mHandler来与主线程通信吧
                    postInvalidate(); //重绘画布,使用post方法,可以不用传到主线程中去更新界面
    只调用了invalidate()这个