When using this class I get this strange exception. It is used to print out a nice timer display for my game, and is created when my main GameView class is created. The error gets thrown at line 26: super(s*1000,1000);
package tommedley.android.game;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.drawable.Drawable;
import android.os.CountDownTimer;
public class Timer extends CountDownTimer{
public static int MODE_COUNTING = 0;
public static int MODE_PAUSED = 1;
public static int MODE_FINISHED = 2;
private Canvas canvas;
private Context context;
private float xPos;
private float yPos;
private static int DIGIT_WIDTH = 50;
private static int DIGIT_HEIGHT = 70;
private int numDigits = 3;
private int seconds;
Drawable[] digitImgs;
private int mode;
public Timer(Canvas c, Context con, float x, float y, int digits, int s){
super(s*1000, 1000);
mode = MODE_COUNTING;
canvas = c;
context = con;
xPos = x;
yPos = y;
seconds = s;
numDigits = digits;
digitImgs = new Drawable[numDigits];
this.start();
}
public void draw(){
String reprNum = String.format("%0"+numDigits+"d", seconds);
for(int i = 0;i<numDigits;i++){
switch(reprNum.charAt(i)){
case '0':
digitImgs[i] = context.getResources().getDrawable(R.drawable.digit_0);
break;
case '1':
digitImgs[i] = context.getResources().getDrawable(R.drawable.digit_1);
break;
case '2':
digitImgs[i] = context.getResources().getDrawable(R.drawable.digit_2);
break;
case '3':
digitImgs[i] = context.getResources().getDrawable(R.drawable.digit_3);
break;
case '4':
digitImgs[i] = context.getResources().getDrawable(R.drawable.digit_4);
break;
case '5':
digitImgs[i] = context.getResources().getDrawable(R.drawable.digit_5);
break;
case '6':
digitImgs[i] = context.getResources().getDrawable(R.drawable.digit_6);
break;
case '7':
digitImgs[i] = context.getResources().getDrawable(R.drawable.digit_7);
break;
case '8':
digitImgs[i] = context.getResources().getDrawable(R.drawable.digit_8);
break;
case '9':
digitImgs[i] = context.getResources().getDrawable(R.drawable.digit_9);
break;
}
digitImgs[i].setBounds((int)xPos+DIGIT_WIDTH*i, (int)yPos, (int)xPos+DIGIT_WIDTH*(i+1), (int)yPos+DIGIT_HEIGHT);
digitImgs[i].draw(canvas);
}
}
@Override
public void onFinish() {
seconds = 0;
mode = MODE_FINISHED;
}
@Override
public void onTick(long millsLeft) {
seconds = (int)millsLeft / 1000;
}
public int getMode(){
return mode;
}
}
That is a bit strange -- I think you must be constructing this object on a thread other than the main thread?
I don't know if you're familiar with Handlers
and Loopers
, but they are Android's way of doing asynchronous operations on a thread. If you want to execute asynchronous operations on a thread, you use a Handler to do it. But before you can use a Handler you must prep the thread by creating a MessageQueue
, which is done by calling Looper.prepare()
.
If you look at the source for the CountDownTimer
class you'll notice that it creates a private Handler
instance. This member variable is created directly before the constructor executes, which is why the exception is being thrown at the call to super
.
So, all you need to do is call Looper.prepare()
before you construct the Timer. However , you do not need to do this if you construct the Timer on the main thread. The main thread of an Android process is automatically declared to be a looper (if you are already calling this on the main thread and are still getting this exception, then that is very strange indeed). As far as I can tell from the sparse javadocs, this class was meant to be used on the main thread, so that's what I would recommend doing. Your onTick
method seems light enough that it's not worth the overhead of an extra thread.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.