runnable集无法正常工作 - 处理程序

时间:2014-02-03 22:47:52

标签: java android runnable android-handler


我正在做一个应用程序,我必须显示一系列图片:序列如下:

  1. 红色X必须显示或多或少1000毫秒;
  2. 必须显示名为“屏幕截图”的图片,或多或少50 毫秒;
  3. 一个名为“噪音”的图像必须或多或少显示50 毫秒;
  4. “Noise”图像消失,为EditText腾出空间。
  5. EditText用于获取用户数据。

    我这样做的想法是使用一组runnable。这是代码:

    private void startThread0(){
        handler.postDelayed(new TaskCross(), 1000);
        handler.postDelayed(new TaskScreenshot(0), 2000);
        handler.postDelayed(new TaskNoise(), 2100);
        handler.postDelayed(new TaskEditText(), 3000);
    
        myEditText.setOnKeyListener(null);
    
        myEditText.setOnKeyListener(new View.OnKeyListener(){
            public boolean onKey(View v, int keyCode, KeyEvent event) {
                System.out.println("KEY ENTER!!!!!");
                if((keyCode == KeyEvent.KEYCODE_ENTER)) {
                    if(myEditText.getText().toString().equals("")){
                        Toast.makeText(getApplicationContext(), "Inserire un numero da 1 a 9", Toast.LENGTH_SHORT).show();
                        return false;
                    } else if (Integer.parseInt(myEditText.getText().toString()) >= 1 &&
                            Integer.parseInt(myEditText.getText().toString()) <= 9){
                        startThread1(1);
                        return true;
                    }
                }
                return false;
            }       
        });
    }
    
    private void startThread1(final int i){     
    
        if(i < length){
            handler.postDelayed(new TaskCross(), 1000);
            handler.postDelayed(new TaskScreenshot(i), 2000);
            handler.postDelayed(new TaskNoise(), 2100);
            handler.postDelayed(new TaskEditText(), 3000);
    
            myEditText.setOnKeyListener(null);
    
            myEditText.setOnKeyListener(new View.OnKeyListener(){
                public boolean onKey(View v, int keyCode, KeyEvent event) {
                    System.out.println("KEY ENTER!!!!!");
                    if((keyCode == KeyEvent.KEYCODE_ENTER)) {
                        if(myEditText.getText().toString().equals("")){
                            Toast.makeText(getApplicationContext(), "Inserire un numero da 1 a 9", Toast.LENGTH_SHORT).show();
                            return false;
                        } else if (Integer.parseInt(myEditText.getText().toString()) >= 1 &&
                                Integer.parseInt(myEditText.getText().toString()) <= 9){
                            startThread1(i+1);
                            return true;
                        }
                    }
                    return false;
                }       
            });
    
            if(i == length-1 && myEditText.getVisibility() == View.VISIBLE){            
                continueButton.setVisibility(View.VISIBLE);
            }
        }
    }
    

    int[] screenshots = {
               R.drawable.googleplaybooks2,
               R.drawable.aldiko1,
               R.drawable.chaton2,
               R.drawable.cinetrailer1,
               R.drawable.fanpage1
        };
    

    class TaskScreenshot implements Runnable{
    
            int j;
    
            public TaskScreenshot(int _i){
                this.j = _i;
            }
    
            @Override
            public void run() {
                System.out.println("Screenshot --> " + j);
                myEditText.setText("");
                myEditText.setVisibility(View.GONE);
                myImageFragment.getView().setVisibility(View.VISIBLE);
                myImageView.setImageResource(screenshots[j]);
                myImageView.getLayoutParams().width = LayoutParams.MATCH_PARENT;
                myImageView.getLayoutParams().height = LayoutParams.MATCH_PARENT;
            }
        }
    
        class TaskNoise implements Runnable{
    
            @Override
            public void run() {
                System.out.println("Noise");
                myImageView.setImageResource(R.drawable.noise);
                myImageView.getLayoutParams().width = LayoutParams.MATCH_PARENT;
                myImageView.getLayoutParams().height = LayoutParams.MATCH_PARENT;
            }
        }
    
        class TaskEditText implements Runnable{
    
            @Override
            public void run() {
                System.out.println("EditText");
                myEditText.setVisibility(View.VISIBLE);
                myImageFragment.getView().setVisibility(View.GONE);
                myEditText.requestFocus();
            }
        }
    
        class TaskCross implements Runnable{
    
            @Override
            public void run() {
                System.out.println("Cross");
                myEditText.setVisibility(View.GONE);
                myImageFragment.getView().setVisibility(View.VISIBLE);
                myImageView.getLayoutParams().width = 90;
                myImageView.getLayoutParams().height = 90;
                myImageView.setImageResource(R.drawable.cross300x300);
            }
        }
    

    现在,当我尝试执行线程时,这是logcat上的结果:

    Cross
    Screenshot --> 0
    Noise
    EditText
    
    Cross
    Cross
    Screenshot --> 1
    Screenshot --> 2
    Noise
    Noise
    EditText
    EditText
    
    Cross
    Cross
    Screenshot --> 3
    Screenshot --> 4
    Noise
    Noise
    EditText
    EditText
    

    因此,第一个screeshot是正确的,之后,其他屏幕截图一次显示两个。为什么? Handler的计时器有问题吗?
    谢谢!

1 个答案:

答案 0 :(得分:0)

您的Runnables正在执行似乎是主线程处理程序,而不是线程池。 Runnable只是一个用于委派任务执行的接口。

现在,我强烈建议大部分使用AnimationDrawable,而不是尝试重新发明轮子。

<animation-list android:oneshot="true">
    <item android:drawable="@drawable/cross300x300" android:duration="1000" />
    <item android:drawable="@drawable/googleplaybooks2" android:duration="50" />
    <item android:drawable="@drawable/aldiko1" android:duration="50" />
    <item android:drawable="@drawable/chaton2" android:duration="50" />
    <item android:drawable="@drawable/cinetrailer1" android:duration="50" />
    <item android:drawable="@drawable/fanpage1" android:duration="50" />
    <item android:drawable="@drawable/noise" android:duration="50" />
</animation-list>

您尚未发布其余视图和布局的设置方式,因此要说明将其与代码集成的最佳方式有点困难。但无论如何,您都可以使用AnimationDrawable.start()来开始动画。要转换到EditText,可以使用AnimationDrawable.getDuration()将延迟消息或Runnable发送到处理程序。或者你可以使用子类化。

希望这会让您开始为代码创建更好(更简单)的路径。