SetBackgroundResource()延迟了吗?

时间:2017-05-28 19:48:41

标签: java android xml android-layout

作为Audiogames套件应用程序的一部分,我在Android中为一个uni项目实现了Simon Says。我试图生成一个随机序列5(就像一个开始测试)按钮播放,除了一件事情之外它一切顺利:按钮不应该亮起来(当他们的时候生成序列中的种子)但是在生成结束时它们会一起点亮。

遵循我的Java和XML的完整代码(这是一个混乱和不完整的代码,所以我会指出那些令我不安的部分)

Java Source

package it.unimi.di.lim.audiogames;

import android.content.Intent;
import android.graphics.drawable.ColorDrawable;
import android.media.MediaPlayer;
import android.os.Build;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.TextView;

import java.util.LinkedList;
import java.util.Random;

public class Game2PlayActivity extends AppCompatActivity {

    private int mScore = 0;
    private LinkedList<Integer> temp = new LinkedList<>();

    private MediaPlayer mCMediaPlayer;
    private MediaPlayer mDMediaPlayer;
    private MediaPlayer mEMediaPlayer;
    private MediaPlayer mFMediaPlayer;

    private MediaPlayer.OnCompletionListener mCompletionListener = new MediaPlayer.OnCompletionListener() {
        @Override
        public void onCompletion(MediaPlayer mp) {
            releaseMediaPlayer(mp);
            turnOffButton(mp);
        }
    };

    private void releaseMediaPlayer(MediaPlayer mediaPlayer) {
        if (mediaPlayer != null) {
            mediaPlayer.release();
        }
    }

    private void turnOffButton(MediaPlayer mp) {
        Button mc_button = (Button) findViewById(R.id.c_button);
        Button md_button = (Button) findViewById(R.id.d_button);
        Button me_button = (Button) findViewById(R.id.e_button);
        Button mf_button = (Button) findViewById(R.id.f_button);
        if(mp == mCMediaPlayer) {
            mc_button.setBackgroundColor(getResources().getColor(R.color.game2_c_off));
        } else if (mp == mDMediaPlayer) {
            md_button.setBackgroundColor(getResources().getColor(R.color.game2_d_off));
        } else if (mp == mEMediaPlayer) {
            me_button.setBackgroundColor(getResources().getColor(R.color.game2_e_off));
        } else {
            mf_button.setBackgroundColor(getResources().getColor(R.color.game2_f_off));
        }
    }

    private void playButton(int i) {
        char j;
        if(i==0)
            j='0';
        else if(i==1)
            j='1';
        else if(i==2)
            j='2';
        else
            j='3';
        Button mc_button = (Button) findViewById(R.id.c_button);
        Button md_button = (Button) findViewById(R.id.d_button);
        Button me_button = (Button) findViewById(R.id.e_button);
        Button mf_button = (Button) findViewById(R.id.f_button);
        switch(j) {
            case '0':
                mc_button.setBackgroundResource(R.color.game2_c_on);
                //mCMediaPlayer = MediaPlayer.create(Game2PlayActivity.this, R.raw.c_sound);
                //mCMediaPlayer.start();
                //mCMediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
                 //   @Override
                 //   public void onCompletion(MediaPlayer mp) {
                 //       mCMediaPlayer.release();
                 //   }
                //});
                break;
            case '1':
                md_button.setBackgroundResource(R.color.game2_d_on);
                //mDMediaPlayer = MediaPlayer.create(Game2PlayActivity.this, R.raw.d_sound);
                //mDMediaPlayer.start();
                //mDMediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
                //    @Override
                //    public void onCompletion(MediaPlayer mp) {
                //        mDMediaPlayer.release();
                //    }
                //});
                break;
            case '2':
                me_button.setBackgroundResource(R.color.game2_e_on);
                //mEMediaPlayer = MediaPlayer.create(Game2PlayActivity.this, R.raw.e_sound);
                //mEMediaPlayer.start();
                //mEMediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
                //    @Override
                //    public void onCompletion(MediaPlayer mp) {
                //        mEMediaPlayer.release();
                //    }
                //});
                break;
            case '3':
                mf_button.setBackgroundResource(R.color.game2_f_on);
                //mFMediaPlayer = MediaPlayer.create(Game2PlayActivity.this, R.raw.f_sound);
                //mFMediaPlayer.start();
                //mFMediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
                //    @Override
                //    public void onCompletion(MediaPlayer mp) {
                //        mFMediaPlayer.release();
                //    }
                //});
                break;
        }
    }

    private void createSequence(int i) {
        Random rand = new Random();
        for(int j = 0; j < i; j++) {
            int seed = rand.nextInt(4);
            temp.add(seed);
            playButton(seed);
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    @Override
    protected void onStop() {
        super.onStop();
        releaseMediaPlayer(mCMediaPlayer);
        releaseMediaPlayer(mDMediaPlayer);
        releaseMediaPlayer(mEMediaPlayer);
        releaseMediaPlayer(mFMediaPlayer);
    }

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

        Button mc_button = (Button) findViewById(R.id.c_button);
        Button md_button = (Button) findViewById(R.id.d_button);
        Button me_button = (Button) findViewById(R.id.e_button);
        Button mf_button = (Button) findViewById(R.id.f_button);

        if (Build.VERSION.SDK_INT >= 21) {
            Window window = this.getWindow();
            window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
            window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
            window.setStatusBarColor(this.getResources().getColor(R.color.game2Dark));
            window.setNavigationBarColor(this.getResources().getColor(R.color.game2Primary));
        }

        android.support.v7.app.ActionBar bar = getSupportActionBar();
        bar.setBackgroundDrawable(new ColorDrawable(getResources().getColor(R.color.game2Primary)));

        mc_button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                playButton(0);
                int check = temp.poll();
                if(check!=0) {
                    Intent gameOver = new Intent(Game2PlayActivity.this, Game2Activity.class);
                    gameOver.putExtra("score", mScore);
                    startActivity(gameOver);
                }
                if(temp.size() == 0) {
                    mScore++;
                    TextView score = (TextView) findViewById(R.id.game2_score);
                    score.setText(Integer.toString(mScore));
                }
            }
        });

        md_button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                playButton(1);
                int check = temp.poll();
                if(check!=1) {
                    Intent gameOver = new Intent(Game2PlayActivity.this, Game2Activity.class);
                    gameOver.putExtra("score", mScore);
                    startActivity(gameOver);
                }
                if(temp.size() == 0) {
                    mScore++;
                    TextView score = (TextView) findViewById(R.id.game2_score);
                    score.setText(Integer.toString(mScore));
                }
            }
        });

        me_button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                playButton(2);
                int check = temp.poll();
                if(check!=2) {
                    Intent gameOver = new Intent(Game2PlayActivity.this, Game2Activity.class);
                    gameOver.putExtra("score", mScore);
                    startActivity(gameOver);
                }
                if(temp.size() == 0) {
                    mScore++;
                    TextView score = (TextView) findViewById(R.id.game2_score);
                    score.setText(Integer.toString(mScore));
                }
            }
        });

        mf_button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                playButton(3);
                int check = temp.poll();
                if(check!=3) {
                    Intent gameOver = new Intent(Game2PlayActivity.this, Game2Activity.class);
                    gameOver.putExtra("score", mScore);
                    startActivity(gameOver);
                }
                if(temp.size() == 0) {
                    mScore++;
                    TextView score = (TextView) findViewById(R.id.game2_score);
                    score.setText(Integer.toString(mScore));
                }
            }
        });


        Button start_button = (Button) findViewById(R.id.game2_start_button);
        start_button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                createSequence(5);
            }
        });
    }
}

XML来源

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

    <TextView
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        android:text="@string/game2_score"
        android:textSize="16sp"
        android:padding="16dp"
        android:gravity="bottom"
        android:textAlignment="center" />

    <TextView
        android:id="@+id/game2_score"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1.2"
        android:text="0"
        android:textSize="48sp"
        android:padding="16dp"
        android:gravity="top"
        android:textAlignment="center" />

    <TextView
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="0.8"
        android:text="@string/game2_criteria"
        android:textSize="16sp"
        android:padding="16dp"
        android:gravity="bottom"
        android:textAlignment="center" />

    <Button
        android:id="@+id/game2_start_button"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        android:text="@string/game2_start"
        android:layout_marginTop="8dp"
        android:layout_marginLeft="64dp"
        android:layout_marginRight="64dp" />

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="2">

        <Button
            android:id="@+id/c_button"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:background="@color/game2_c_off"
            android:layout_margin="16dp"
            android:text="@string/game2_c" />

        <Button
            android:id="@+id/d_button"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:background="@color/game2_d_off"
            android:layout_margin="16dp"
            android:text="@string/game2_d" />

    </LinearLayout>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="2">

        <Button
            android:id="@+id/e_button"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:background="@color/game2_e_off"
            android:layout_margin="16dp"
            android:text="@string/game2_e" />

        <Button
            android:id="@+id/f_button"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:background="@color/game2_f_off"
            android:layout_margin="16dp"
            android:text="@string/game2_f" />

    </LinearLayout>

</LinearLayout>

----------------------------------------------- --------------------------------

所以基本上我要做的就是通过点击按钮&#34;开始&#34;来生成序列。这里是onClickListener(5仅用于测试目的)

Button start_button = (Button) findViewById(R.id.game2_start_button);
    start_button.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            createSequence(5);
        }
    });

这会触发createSequence()方法,如下所示

private void createSequence(int i) {
    Random rand = new Random();
    for(int j = 0; j < i; j++) {
        int seed = rand.nextInt(4);
        temp.add(seed);
        playButton(seed);
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

到目前为止一切都很好。我认为在糟糕的编程经验中失败的是PlayButton()方法

private void playButton(int i) {
    char j;
    if(i==0)
        j='0';
    else if(i==1)
        j='1';
    else if(i==2)
        j='2';
    else
        j='3';
    Button mc_button = (Button) findViewById(R.id.c_button);
    Button md_button = (Button) findViewById(R.id.d_button);
    Button me_button = (Button) findViewById(R.id.e_button);
    Button mf_button = (Button) findViewById(R.id.f_button);
    switch(j) {
        case '0':
            mc_button.setBackgroundResource(R.color.game2_c_on);
            //mCMediaPlayer = MediaPlayer.create(Game2PlayActivity.this, R.raw.c_sound);
            //mCMediaPlayer.start();
            //mCMediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
            //    @Override
            //    public void onCompletion(MediaPlayer mp) {
            //        mCMediaPlayer.release();
            //    }
            //});
            break;
        case '1':
            md_button.setBackgroundResource(R.color.game2_d_on);
            //mDMediaPlayer = MediaPlayer.create(Game2PlayActivity.this, R.raw.d_sound);
            //mDMediaPlayer.start();
            //mDMediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
            //    @Override
            //    public void onCompletion(MediaPlayer mp) {
            //        mDMediaPlayer.release();
            //    }
            //});
            break;
        case '2':
            me_button.setBackgroundResource(R.color.game2_e_on);
            //mEMediaPlayer = MediaPlayer.create(Game2PlayActivity.this, R.raw.e_sound);
            //mEMediaPlayer.start();
            //mEMediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
            //    @Override
            //    public void onCompletion(MediaPlayer mp) {
            //        mEMediaPlayer.release();
            //    }
            //});
            break;
        case '3':
            mf_button.setBackgroundResource(R.color.game2_f_on);
            //mFMediaPlayer = MediaPlayer.create(Game2PlayActivity.this, R.raw.f_sound);
            //mFMediaPlayer.start();
            //mFMediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
            //    @Override
            //    public void onCompletion(MediaPlayer mp) {
            //        mFMediaPlayer.release();
            //    }
            //});
            break;
    }
}

音频播放已注释,但用于工作正常。它完全是关于那些SetBackgroundResource调用的,它们不会立即执行,而是仅在CreateSequence方法中的for循环结束时执行。

如果有人想在Android Studio中实现整个项目(不推荐,因为它可能非常错误),这里是(25 MB):http://www.mediafire.com/file/2c86sbe3rkb231d/AudiogamesSuite.zip

提前致谢

----------------------------------------------- --------------------------------

编辑 - 由于Martin Pfeffer和一些谷歌搜索,管理解决它。这是更新后的代码

private void createSequence(final int i) {
        Thread t = new Thread(new Runnable() {
            public void run() {
                Random rand = new Random();
                for (int j = 0; j < i; j++) {
                    final int seed = rand.nextInt(4);
                    try {
                        runOnUiThread(new Runnable() {
                            @Override
                            public void run() {
                                temp.add(seed);
                                playButton(seed);
                            }
                        });
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        });
        t.setDaemon(true);
        t.start();
    }

1 个答案:

答案 0 :(得分:1)

synchronized说明符添加到方法中。

<击>
private synchronized void createSequence(int i) {
        // allow only one thread to be executed
}

<击> 修改:

刚看到你没有使用单独的线程..所以运行此代码以获得延迟:

new Handler().postDelayed(new Runnable(){
        public void run() {
          // do stuff             
      }}, 1000 * DELAY_IN_SECONDS);

编辑2:

我认为你正在寻找这样的东西:

import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.widget.TextView;

import java.util.concurrent.Callable;

public class MainActivity extends AppCompatActivity {

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

        new MyThread((TextView) findViewById(R.id.textView)).start();

    }


    class MyThread extends Thread implements Runnable {

        TextView textView;

        MyThread(TextView textView) {
            this.textView = textView;
        }

        @Override
        public void run() {
            for (int i = 0; i < 10; i++) {
                try {
                    sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                runOnMainUiThread(new Callable() {
                    @Override
                    public Object call() throws Exception {
                        textView.setText("" + System.currentTimeMillis());
                        return null;
                    }
                });

            }
        }

        void runOnMainUiThread(final Callable callable) {
            new Handler(Looper.getMainLooper()).post(new Runnable() {
                @Override
                public void run() {
                    try {
                        callable.call();
                    } catch (Exception e) {
                        Log.e("MyThread", "runOnMainUiThread: ", e);
                    }
                }
            });
        }
    }
}

如果您有任何疑问,请随时问:)