当前位置: 首页 > 知识库问答 >
问题:

Android:启动结果的新活动时无响应线程

太叔经赋
2023-03-14

我是Android的新手,所以我正在制作一个涂色书应用程序,只是为了让自己熟悉Android编程。我已经广泛地查找了我的问题并实施了解决方案,但仍然没有进展。

我有一个活动“着色活动”,它调用了一个扩展表面视图的类“绘画视图”。我试图在一个单独的线程中更新画布。我在布局中也有一个按钮,将用户带到另一个活动中选择颜色。问题是,当html" target="_blank">用户选择颜色后返回时,画布变成空的,我不能再在画布上画画了。我想我不知何故在活动之间松动了线程,虽然线程在后台运行,但我无法访问它。

我在这个论坛上读到,我必须在线程类中实现pause()和resume()方法,基本上在我转到另一个活动时杀死线程,并在我返回时重新启动它。我还读到,我必须重写活动类中的onPause()和onResume()方法,并在onResume()中构造surfaceview,以便每次用户返回该活动时都构造它。

如果这没有多大意义,我很抱歉,因为我也迷路了。

我的“着色活动”:

package com.ali.coloryourself;

import android.app.Activity;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Toast;

public class ColoringActivity extends Activity {

private static final int COLOR_REQUEST_CODE = 100;
public static String file;
public static Bitmap bitmap;
BitmapFactory.Options options;
PaintView paintView;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_draw);

    Intent intent = getIntent();
    file = intent.getStringExtra("fileName");

//      paintView = (PaintView) findViewById(R.id.drawingSurface);


}

@Override
protected void onResume() {
    paintView = (PaintView) findViewById(R.id.drawingSurface);
    paintView.getThread().resume();
    super.onResume();
}

@Override
protected void onPause() {
    paintView.getThread().pause();
    super.onPause();
}

public void pickColor(View v) {
    paintView.getThread().pause();
    Intent colorIntent = new Intent(this, ColorPickerActivity.class);
    startActivityForResult(colorIntent, COLOR_REQUEST_CODE);
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if (resultCode != RESULT_CANCELED) {
        if (requestCode == COLOR_REQUEST_CODE) {
            int color = data.getIntExtra("Color", -1);
//              paintView.getPaint().setColor(color);
        }
    }

}

}

我的'PaintView'类:

package com.ali.coloryourself;

import android.R.color;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;

class PaintView extends SurfaceView implements SurfaceHolder.Callback {
private Paint paint = new Paint();
private Canvas canvas;
private PaintThread thread;
private Path path = new Path();

private Bitmap bitmap;

public PaintView(Context context, AttributeSet attrs) {
    super(context, attrs);

    SurfaceHolder holder = getHolder();
    holder.addCallback(this);

    paint.setColor(Color.WHITE);
    paint.setStyle(Paint.Style.STROKE);
    paint.setStrokeJoin(Paint.Join.ROUND);
    paint.setStrokeCap(Paint.Cap.ROUND);
    paint.setStrokeWidth(3);

    setThread(new PaintThread(holder));
}

class PaintThread extends Thread {
    private boolean mRun;
    private SurfaceHolder mSurfaceHolder;
    private int mMode;

    public static final int STATE_PAUSE = 2;
    public static final int STATE_RUNNING = 4;

    public PaintThread(SurfaceHolder surfaceHolder) {
        mSurfaceHolder = surfaceHolder;
    }

    @Override
    public void run() {
        while (mRun) {
            try {
                canvas = mSurfaceHolder.lockCanvas(null);
                if (mMode == STATE_RUNNING) {
                    if (bitmap == null) {
                        bitmap = Bitmap.createBitmap(1, 1,
                                Bitmap.Config.ARGB_8888);
                    }
                }
                doDraw(canvas);
                canvas.drawBitmap(bitmap, 0, 0, null);
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                if (canvas != null) {
                    mSurfaceHolder.unlockCanvasAndPost(canvas);
                }
            }
        }
    }

    private void doDraw(Canvas canvas) {
        canvas.drawPath(path, paint);
    }

    public void setRunning(boolean b) {
        mRun = b;
    }

    public void pause() {
            if (mMode == STATE_RUNNING)
                setState(STATE_PAUSE);
    }

    public void resume() {
        setState(STATE_RUNNING);
    }

    public void setState(int mode) {
        synchronized (mSurfaceHolder) {
            mMode = mode;
        }
    }
}

public void surfaceChanged(SurfaceHolder holder, int format, int width,
        int height) {
    bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
}

@Override
public boolean onTouchEvent(MotionEvent event) {
    // Log.d("Touch", "I am touching");
    float eventX = event.getX();
    float eventY = event.getY();

    int action = event.getAction();

    switch (action) {
    case MotionEvent.ACTION_DOWN:
        path.moveTo(eventX, eventY);
        return true;
    case MotionEvent.ACTION_MOVE:
        path.lineTo(eventX, eventY);
        break;
    case MotionEvent.ACTION_UP:
        // nothing to do
        break;
    default:
        return false;
    }
    return true;
}

public void surfaceCreated(SurfaceHolder holder) {
    if (getThread().getState() == Thread.State.NEW) {
        getThread().setRunning(true);
        getThread().start();
    }
}

public void surfaceDestroyed(SurfaceHolder holder) {
    boolean retry = true;
    getThread().setRunning(false);
    getThread().resume();
    while (retry) {
        try {
            getThread().join();
            retry = false;
        } catch (InterruptedException e) {
        }
    }
}

public Paint getPaint() {
    return paint;
}

public void setPaint(int color) {
    this.paint.setColor(color);
}

public PaintThread getThread() {
    return thread;
}

public void setThread(PaintThread thread) {
    this.thread = thread;
}

}

我的“activity_draw.xml”

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >

 <Button
    android:id="@+id/button1"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignParentTop="true"
    android:layout_centerHorizontal="true"
    android:layout_marginTop="10dp"
    android:onClick="pickColor"
    android:text="Pick Color" />

<com.ali.coloryourself.PaintView
    android:id="@+id/drawingSurface"
    android:layout_width="match_parent"
    android:layout_height="match_parent" 
    android:layout_below="@+id/button1"
    android:layout_marginTop="10dp"/>

</RelativeLayout>

我知道我缺少一些非常基本的线程概念。我需要允许用户选择颜色并返回并能够继续绘制。我将非常感谢您的帮助。

共有1个答案

严永丰
2023-03-14

我想我已经找到了一个答案,尽管我不确定这是否是一种好的编程实践。我发现我的表面视图和线程是在创建“着色活动”后创建的,每次“着色活动”进入背景时都会销毁。但是,一旦重新启动并恢复了“着色活动”,就不会重新创建曲面视图和线程。所以我移动了以下行

setContentView(R.layout.activity_draw);

到onResume()方法,现在我每次都可以在画布上绘制。现在,我只需要保存画布,并在活动重新启动时重新加载它,以开始用户留下的颜色。

 类似资料:
  • 我想在Android上启动另一个活动,但出现以下错误: 请指定构造函数调用;分类器Page2没有伴随对象 实例化类后。我应该怎么做来纠正错误?我的代码:

  • 我写了一个程序的小例子,它应该在按下后开始运行多批次并行线程。这个过程只能启动一次,在一批线程完成后,它应该检查是否是退出的时候了。 所以例如,它可以像这样: -批处理1(10个线程)正在运行,在它<代码>stop_button被按下。完成批次1后,程序应该停止而不运行批次2并返回初始状态(再次具有启动此过程的选项)。 但是,在这个过程中,GUI似乎根本无法注册单击或任何东西。它只是看起来冻结了。

  • 问题内容: 我正在尝试构建一个android应用程序,此应用程序的主要功能之一是使其能够在手机启动时自动启动活动,我在手机上看到一些应用程序已经执行了此操作,因此任何帮助都将非常有用。我可以至少通过sdk对此进行更好的研究,谢谢! 问题答案: 您需要像这样实现BroadCastreceiver: 在清单中添加以下内容: 添加权限:

  • MainFormular.java 在Android.app.activity.performCreate(activity_main_formular 洛克卡特

  • 问题内容: 在添加异步任务之前,我已经对代码进行了一些更改,我的应用程序可以正常运行其远程服务器上的身份验证用户名和密码,但是在登录成功消息消失后​​无法启动其他活动。有人建议我现在添加一个异步任务,但是我输入正确的用户名和密码后它将停止工作。当我输入错误的用户名和密码时,其工作正常将显示错误的用户名密码消息。如果有人能够知道会出现什么错误,请帮助我。 码- 日志猫 QuestionnActivi

  • 当我尝试用Google Maps活动模板打开一个新项目时,我会遇到以下错误。 错误:(3)检索项的父项时出错:找不到与给定名称“Android:TextApparance.Material.Widget.Button.Inverse”匹配的资源。 我对此完全陌生,我试着看过类似的帖子,但我无法理解那里给出的解释。 这些错误出现在名为google_maps_api.xml的文件中