#android #android-activity #surfaceview
#Android #android-активность #просмотр поверхности
Вопрос:
В настоящее время я запускаю действие из SurfaceView. Действие запускается нормально (отображает текст редактирования и кнопку внутри LinearLayout). Тем не менее, оно принудительно закрывается. Это выдает мне ошибки, указывающие ANR в com.thesis.sakurame (который является моим пакетом), а также причину: keyDispatchingTimedOut. Есть какие-либо подсказки относительно того, почему это? Ниже показаны четыре класса.
BoardThread.java:
public class BoardThread extends Thread {
private SurfaceHolder surfaceHolder;
private BoardView boardView;
private Vector<Blossom> blossomVector;
private int boxX;
private int boxY;
private int boxWidth;
private int boxHeight;
private boolean mrun =false;
private Iterator<Blossom> iterator;
private static final String TAG = "Debug";
public BoardThread(SurfaceHolder holder, BoardView boardView2,
Vector<Blossom> blossomVector1, Iterator<Blossom> dataIterator,
int box_x, int box_y, int boxW, int boxH) {
surfaceHolder = holder;
boardView=boardView2;
blossomVector = blossomVector1;
iterator = dataIterator;
boxX = box_x;
boxY = box_y;
boxW = boxWidth;
boxH = boxHeight;
}
public void startRunning(boolean run) {
mrun=run;
}
@Override
public void run() {
super.run();
Canvas canvas;
while (mrun) {
canvas=null;
try {
canvas = surfaceHolder.lockCanvas(null);
synchronized (surfaceHolder) {
//update position
//Position(blossomVector, boxX, boxY, boxWidth, boxHeight);
// draw flowers
boardView.onDraw(canvas);
}
} finally {
if (canvas != null) {
surfaceHolder.unlockCanvasAndPost(canvas);
}
}
}
}
private synchronized void Position(Vector<Blossom> blossomVector,int box_x, int box_y,
int boxWidth, int boxHeight)
{
//for(Blossom blossom: blossomVector)
iterator = blossomVector.iterator();
while (iterator.hasNext())
{
Blossom tempBlossom = iterator.next();
tempBlossom.UpdatePosition();
}
}
}
BoardView.java
public class BoardView extends SurfaceView implements SurfaceHolder.Callback{
Context mContext;
// thread initialization
private BoardThread thread;
Thread timer;
Thread timer2;
// box variables
Bitmap box =
(BitmapFactory.decodeResource
(getResources(), R.drawable.box));
private int box_x = 140;
private int box_y = 378;
private int boxWidth = box.getWidth();
private int boxHeight = box.getHeight();
// storage
private Vector<Blossom> blossomVector = new Vector<Blossom>();
Iterator<Blossom> dataIterator = blossomVector.iterator();
// counters
private int blossomNum = 0;
private String score;
private int currentScore = 0;
private int lives = 3;
boolean mode = false;
boolean game = false;
OutputStreamWriter out = null;
FileOutputStream fOut = null;
private static final String TAG = "Debug";
final Paint scorePaint = new Paint();
public BoardView(Context context){
super(context);
scorePaint.setColor(Color.BLACK);
scorePaint.setTextSize(12);
scorePaint.setTypeface(Typeface.MONOSPACE);
//surfaceHolder provides canvas that we draw on
getHolder().addCallback(this);
// controls drawings
thread = new BoardThread(getHolder(),this, blossomVector, dataIterator, box_x, box_y,
boxWidth, boxHeight);
timer2 = new Thread(){
public void run(){
while(game == false){
uiCallback.sendEmptyMessage(0);
try{
Thread.sleep(5000); // change to be random
}
catch (InterruptedException e){
e.printStackTrace();
}
}
}
};
timer = new Thread(){
public void run(){
//makes sure the player still has 3 lives left
while(game == false){
uiCallback.sendEmptyMessage(0);
try {
Thread.sleep(2000); // wait two seconds before drawing the next flower
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} //sleep for 2 seconds
}
}
};
timer.start();
timer2.start();
//intercepts touch events
setFocusable(true);
}
@Override
public void onDraw(Canvas canvas){
canvas.drawColor(Color.WHITE);
score = "SCORE: " currentScore;
//note: pay attention to order you draw things
//don't change order or else blossoms will fall
//on top of box, not "into" it.
//display the scoreboard
canvas.drawText(score,240,420,scorePaint);
// uses a synchronized method to prevent concurrent modification
DrawBlossoms(canvas);
canvas.drawBitmap(box, box_x, box_y, null);
}
@Override
public boolean onTouchEvent(MotionEvent event){
//handles movement of box
if(event.getAction() == MotionEvent.ACTION_DOWN){
if(event.getX() > box_x amp; event.getY() > box_y amp;
event.getX() < box_x boxWidth amp; event.getY() < box_y boxHeight)
{
mode = true;
}
}
if(event.getAction() == MotionEvent.ACTION_MOVE) {
if(event.getX() > box_x amp; event.getY() > box_y amp;
event.getX() < box_x boxWidth amp; event.getY() < box_y boxHeight)
{
mode = true;
}
if(mode == true){
box_x = (int)event.getX();
}
}
if(event.getAction() == MotionEvent.ACTION_UP){
mode = false;
}
invalidate();
return true;
}
@Override
public void surfaceChanged(SurfaceHolder holder,
int format, int width, int height ){
Log.v(TAG, "Surface Changed");
//somehow these don't seem to be working
}
@Override
public void surfaceCreated(SurfaceHolder holder){
thread.startRunning(true);
thread.start();
}
@Override
public void surfaceDestroyed(SurfaceHolder holder){
Log.v(TAG, "Surface Destroyed");
//somehow these don't seem to be working
}
private Handler uiCallback = new Handler(){
public synchronized void handleMessage(Message msg){
//add a new blossom to the blossom Vector!!
blossomVector.add(new Blossom(
(BitmapFactory.decodeResource
(getResources(), R.drawable.blossom))));
dataIterator = blossomVector.iterator();
blossomNum ;
Log.v(TAG, "Number of Blossoms =" blossomNum);
}
};
private synchronized void DrawBlossoms(Canvas c) // method to draw flowers on screen and test for collision
{
Canvas canvas = c;
dataIterator = blossomVector.iterator();
while (dataIterator.hasNext())
{
Blossom tempBlossom = dataIterator.next();
tempBlossom.Draw(canvas);
if (tempBlossom.hit(box_x,box_y, box_x boxWidth, box_y boxHeight, blossomVector) == true)
{
Log.v(TAG, "ITERATOR WORKS!");
dataIterator.remove();
currentScore = 100;
}
if (tempBlossom.dropped() == true)
{
dataIterator.remove();
Log.v(TAG, "Blossom dropped");
lives--;
}
if (lives == 0)
{
// stop the thread that makes blossoms
game = true;
Intent intent = new Intent(getContext(), HighScore.class);
getContext().startActivity(intent);
try {
thread.join();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
Board.java:
public class Board extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(new BoardView(this));
}
@Override
protected void onPause()
{
super.onPause();
finish();
}
}
HighScore.java:
public class HighScore extends Activity{
@Override
protected void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
LinearLayout l1 = new LinearLayout(this);
EditText edit = new EditText(this);
Button enter = new Button(this);
enter.setText("Enter");
l1.setOrientation(LinearLayout.VERTICAL);
l1.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT,
LayoutParams.WRAP_CONTENT));
edit.setText("Enter your name!");
edit.isInEditMode();
l1.setId(1);
l1.addView(edit);
l1.addView(enter);
setContentView(l1);
}
}
LogCat:
05-09 21:29:54.723: ERROR/ActivityManager(66): ANR in com.thesis.sakurame (com.thesis.sakurame/.HighScore)
05-09 21:29:54.723: ERROR/ActivityManager(66): Reason: keyDispatchingTimedOut
05-09 21:29:54.723: ERROR/ActivityManager(66): Load: 0.98 / 0.58 / 0.39
05-09 21:29:54.723: ERROR/ActivityManager(66): CPU usage from 9073ms to 72ms ago:
05-09 21:29:54.723: ERROR/ActivityManager(66): system_server: 15% = 7% user 7% kernel / faults: 127 minor
05-09 21:29:54.723: ERROR/ActivityManager(66): adbd: 6% = 0% user 5% kernel
05-09 21:29:54.723: ERROR/ActivityManager(66): thesis.sakurame: 5% = 3% user 1% kernel / faults: 175 minor
05-09 21:29:54.723: ERROR/ActivityManager(66): logcat: 2% = 0% user 1% kernel
05-09 21:29:54.723: ERROR/ActivityManager(66): re-initialized>: 1% = 1% user 0% kernel / faults: 18 minor
05-09 21:29:54.723: ERROR/ActivityManager(66): d.process.acore: 1% = 0% user 0% kernel / faults: 8 minor
05-09 21:29:54.723: ERROR/ActivityManager(66): id.defcontainer: 0% = 0% user 0% kernel / faults: 10 minor
05-09 21:29:54.723: ERROR/ActivityManager(66): d.process.media: 0% = 0% user 0% kernel / faults: 9 minor
05-09 21:29:54.723: ERROR/ActivityManager(66): qemud: 0% = 0% user 0% kernel
05-09 21:29:54.723: ERROR/ActivityManager(66): ndroid.launcher: 0% = 0% user 0% kernel / faults: 8 minor
05-09 21:29:54.723: ERROR/ActivityManager(66): com.svox.pico: 0% = 0% user 0% kernel / faults: 8 minor
05-09 21:29:54.723: ERROR/ActivityManager(66): ndroid.settings: 0% = 0% user 0% kernel / faults: 7 minor
05-09 21:29:54.723: ERROR/ActivityManager(66): com.android.mms: 0% = 0% user 0% kernel / faults: 8 minor
05-09 21:29:54.723: ERROR/ActivityManager(66): m.android.email: 0% = 0% user 0% kernel / faults: 8 minor
05-09 21:29:54.723: ERROR/ActivityManager(66): .quicksearchbox: 0% = 0% user 0% kernel / faults: 8 minor
05-09 21:29:54.723: ERROR/ActivityManager(66): m.android.music: 0% = 0% user 0% kernel / faults: 7 minor
05-09 21:29:54.723: ERROR/ActivityManager(66): re-initialized>: 0% = 0% user 0% kernel / faults: 7 minor
05-09 21:29:54.723: ERROR/ActivityManager(66): roid.alarmclock: 0% = 0% user 0% kernel / faults: 7 minor
05-09 21:29:54.723: ERROR/ActivityManager(66): android.protips: 0% = 0% user 0% kernel / faults: 7 minor
05-09 21:29:54.723: ERROR/ActivityManager(66): TOTAL: 37% = 15% user 21% kernel 0% irq 1% softirq
Комментарии:
1. вы должны опубликовать код и трассировку стека.
2. Хорошо, я только что отредактировал его, чтобы показать свой код.
3. Как насчет трассировки стека? Пожалуйста, покажите полный журнал logcat за время, предшествующее ошибке.
4. хорошо, я сделал это, но это не отформатировалось должным образом. Но это есть.
5. В logcat указано, что причиной ANR является ‘keyDispatchingTimedOut`. Если вы загуглите для этого, вы могли бы найти некоторую полезную информацию.