【问题标题】:using handler in android to create series of png's在android中使用处理程序创建一系列png
【发布时间】:2011-06-28 02:56:51
【问题描述】:

我正在尝试将图像放在屏幕上并每五秒更改一次。这不在 Activity 类中。对不起,如果是一个愚蠢的问题。这对我来说是一个巨大的学习曲线。

public class Panel extends SurfaceView implements SurfaceHolder.Callback {
  private Handler mHandler = new Handler();
  //stuff

  public void doDraw(Canvas canvas) {
        int counter = 0;
        canvas.drawColor(Color.BLACK);
        dot1.doDraw(getResources(), canvas, counter);
            mHandler.removeCallbacks(panelDraw);
                mHandler.postDelayed(panelDraw, 5000);
}

private Runnable panelDraw = new Runnable() {
       public void run() {

       }
};

(Panel->)mPanel.doDraw(canvas) 在另一个类中调用Panel 中列出的doDraw。这是一个循环。

据我所知,第一张图片没有停止五秒钟,并且由于其他代码,猫图片在屏幕上闪烁。我可以在 run() 中不放任何东西吗?我想把 dot1.doDraw(getResources(), canvas, counter) 放在那里,但我不能/不认为我可以提供 void run() 参数或 Runnable panelDraw 资源、画布、计数器参数。

感谢任何帮助。让我知道是否需要提供更多代码。


关于我的游戏的更多信息:小猫照片应该出现在屏幕上的随机位置。如果在规定的时间内没有点击当前的小猫图像,则游戏结束。这些图片最终持续

我听说如果你需要做很多绘图,你最好使用 SurfaceView,就像我非常密切关注的教程中一样:http://www.droidnova.com/2d-tutorial-series-part-v,848.html我的 Activity 类 (Scene1) 有 setContentView(new Panel(this)) ,所以我不知道如何把东西放在 Activity 类中,而这一切都放在 Panel 类中。如果 Activity 线程并没有真正做太多事情并将其全部交给 Panel,我应该将 ImageView 代码放在哪里?另外,如果我有一个处理运行的 ViewThread(公共类 ViewThread 扩展线程):

public void run() {
    Canvas canvas = null;
    while (mRun1) {
     do {
        canvas = mHolder.lockCanvas();
            if (canvas != null) {
               mPanel.doDraw(canvas);
               mRun1 = true;
               mRun1 = mPanel.get_run();
               mHolder.unlockCanvasAndPost(canvas);
            }
    } while (mRun1 == true);

点类有类似的东西:

public void firstRing(Resources res, Canvas canvas, int counter){
    Random rand = new Random();
        switch(counter) {
            case 0:  mBitmap = BitmapFactory.decodeResource(res,     
                         R.drawable.cat1_m);
                break;
            case 1:  mBitmap = BitmapFactory.decodeResource(res, 
                         R.drawable.cat2_m);
                break;
            case 2:  mBitmap = BitmapFactory.decodeResource(res,                   
                         R.drawable.cat2_m);
                break;
            case 3:  mBitmap = BitmapFactory.decodeResource(res,   
                         R.drawable.cat2_m);
                break;
            case 4:  mBitmap = BitmapFactory.decodeResource(res,                          
                         R.drawable.cat2_m);
                            break;
            case 5:  mBitmap = BitmapFactory.decodeResource(res, 
                         R.drawable.cat1_m);
                break;
        }
        mX = rand.nextInt((int)(Panel.mWidth - mBitmap.getWidth()));
        mY = rand.nextInt((int)(Panel.mHeight - mBitmap.getHeight()));
    canvas.drawBitmap(mBitmap, mX, mY, null);

 public void doDraw(Resources res, Canvas canvas, int counter) {
      firstRing(res, canvas, counter);
}

谢谢你的信息,巴里,虽然我有点困惑。我是尝试 ImageView 还是坚持使用 Handler(),虽然我不知道如何使用它并且它现在不工作?我需要 public void run() 中的东西吗?

【问题讨论】:

  • 我删除了我原来的答案,因为正如 rochdev 指出的那样,您永远不应该在非 UI 线程(基本上是您自己创建的任何线程)中使用视图。不过,简短的回答是使用 ImageView 和处理程序。我将尝试在下面的新答案中进行解释。

标签: android handler


【解决方案1】:

此代码应该比我上一个答案更好,但我还没有编译或测试它。即使它不起作用,它也会为您指明正确的方向。我假设您在某处有一个 Activity 子类,因此只需将我的代码复制到您的活动中即可。你的布局中应该有一个<ImageView> 标签。

下面的代码在Activity.onCreate()中创建了一个Handler,它运行在UI线程中,保证所有对Handler的调用也会在UI线程中运行。然后它调用showNextKittyImage() 来显示第一张图片。 showNextKittyImage()为ImageView设置Drawable资源id,5秒后调用Handler.sendEmptyMessageDelayed()调用handler。处理程序调用showNextKittyImage() 并重复循环。

ImageView 仍然比 SurfaceView 更可取,因为它旨在显示图像。您需要做的就是将 Drawable 资源 id 传递给它,而不是弄乱位图。如果你真的想要或需要用 SurfaceView 来做,那我帮不了你。

此代码也不会使小猫出现在随机位置。首先让它在一个位置工作,然后添加代码以在屏幕上随机移动 ImageView。如果您此时需要帮助,我强烈建议您发布一个新问题,因为您在一次发布时已经问了很多问题。

祝你好运,

巴里

public class KittyActivity extends Activity {

    Handler mHandler;
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        // Inflate your view
        setContentView(R.layout.YOUR_LAYOUT);

        // Create a handler ON THE UI THREAD
        mHandler = new Handler(Message result) {
            public void handleMessage(Message result) {
                showNextKittyImage();
            }
        };

        // Show the first kitty
        showNextKittyImage();
    }

    public void showNextKittyImage() {
        int kitty = getNextKitty();
        ImageView iv = findViewById(R.id.YOUR_IMAGE_VIEW_ID);
        iv.setImageResource(kitty);

        // OPTIONAL: Move the ImageView to a new random location

        mHandler.sendEmptyMessageDelayed(0, 5000);
    }


    private int getNextKitty() {
        // Your code to get the next kitty drawable id
    }
}

【讨论】:

  • 您不应该在工作线程上操作 ImageView。 “它违反了 UI 的单线程模型:Android UI 工具包不是线程安全的,必须始终在 UI 线程上进行操作”-developer.android.com/resources/articles/…。将 Handler 与 postDelayed(Runnable r, long delayMillis) 一起使用。
  • rochdev 你是绝对正确的。我的错。上面的新代码不应违反 UI 线程模型,因为 Handler 是在 onCreate() 中的 UI 线程中创建的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-07-24
  • 1970-01-01
  • 1970-01-01
  • 2015-10-08
  • 2020-12-20
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多