主线程的Thread.sleep冻结了应用程序,android

时间:2017-09-17 16:04:59

标签: android android-animation

所以我想模仿我的作业泡泡排序算法的过程。我想这样做的方法是 - 播放第一个淡出动画,然后停止我的for循环,等到动画完成,重新分配值,播放第二个动画,等到它完成并恢复for循环。我找到Thread.sleep()但最后我的应用程序冻结或屏幕是黑色的,直到所有动画完成。我已经进行了很多实验,所以我的代码看起来非常糟糕(抱歉)。

public class BubbleSort extends AppCompatActivity {

    Button element1;
    Button element2;
    Animation fadeIn;
    Animation fadeOut;
    int[] values;

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

        fadeIn = AnimationUtils.loadAnimation(getApplicationContext(),
                R.anim.fade_in);
        fadeOut = AnimationUtils.loadAnimation(getApplicationContext(),
                R.anim.fade_out);

    }


    public void onSort(View view){
        HashMap<Integer, Integer> indexes = sort();
        Set<Integer> keySet = indexes.keySet();
        Integer[] keys  =  keySet.toArray(new Integer[keySet.size()]);
        for (int key : keys) {
            initElements(key, indexes.get(key));
            element1.startAnimation(fadeOut);
            element2.startAnimation(fadeOut);
            try {
                Thread.sleep(2000);
                element1.startAnimation(fadeIn);
                element1.setText("" + values[key]);
                element2.startAnimation(fadeIn);
                element2.setText("" + values[indexes.get(key)]);
            } catch (Exception e) {
                Log.i("test", e.toString());
            }
        }
    }

    void initElements(int from, int to){
        switch (from){
            case 0:{
                element1 = (Button) findViewById(R.id.element_1);
                break;
            }
            case 1:{
                element1 = (Button) findViewById(R.id.element_2);
                break;
            }
            case 2:{
                element1 = (Button) findViewById(R.id.element_3);
                break;
            }
            case 3:{
                element1 = (Button) findViewById(R.id.element_4);
                break;
            }
            case 4:{
                element1 = (Button) findViewById(R.id.element_5);
                break;
            }
            case 5:{
                element1 = (Button) findViewById(R.id.element_6);
                break;
            }
            case 6:{
                element1 = (Button) findViewById(R.id.element_7);
                break;
            }
            case 7:{
                element1 = (Button) findViewById(R.id.element_8);
                break;
            }
            case 8:{
                element1 = (Button) findViewById(R.id.element_9);
                break;
            }
            case 9:{
                element1 = (Button) findViewById(R.id.element_10);
                break;
            }
            default:{
                element1 = null;
                break;
            }
        }

        switch (to){
            case 0:{
                element2 = (Button) findViewById(R.id.element_1);
                break;
            }
            case 1:{
                element2 = (Button) findViewById(R.id.element_2);
                break;
            }
            case 2:{
                element2 = (Button) findViewById(R.id.element_3);
                break;
            }
            case 3:{
                element2 = (Button) findViewById(R.id.element_4);
                break;
            }
            case 4:{
                element2 = (Button) findViewById(R.id.element_5);
                break;
            }
            case 5:{
                element2 = (Button) findViewById(R.id.element_6);
                break;
            }
            case 6:{
                element2 = (Button) findViewById(R.id.element_7);
                break;
            }
            case 7:{
                element2 = (Button) findViewById(R.id.element_8);
                break;
            }
            case 8:{
                element2 = (Button) findViewById(R.id.element_9);
                break;
            }
            case 9:{
                element2 = (Button) findViewById(R.id.element_10);
                break;
            }
            default:{
                element2 = null;
                break;
            }
        }
    }

    HashMap<Integer, Integer> sort(){
        HashMap<Integer, Integer> indexes = new HashMap<>();
        values = new int[10];
        boolean sorting = true;
        int loop = 1;
        Random random = new Random();

        for (int index = 0; index < values.length; index++){
            values[index] = random.nextInt(10);
        }

        int offset = 0;
        while (sorting){

            System.out.println("To sort:");
            for (int element : values)
                System.out.print(" " + element);
            System.out.println();

            sorting = false;
            for (int index = 0; index < values.length - 1 - offset; index++) {
                if (values[index] > values[index + 1]) {
                    int temp = values[index];
                    values[index] = values[index + 1];
                    values[index + 1] = temp;
                    sorting = true;
                    indexes.put(index, index + 1);
                }
            }

            System.out.println("Loop: " + loop);

            for (int element : values)
                System.out.print(" " + element);
            System.out.println();

            loop++;
            offset++;
        }
        return indexes;
    }
}

2 个答案:

答案 0 :(得分:1)

使用主线程中的Thread.sleep()导致应用冻结,使用动画回调如下:

fadeIn = AnimationUtils.loadAnimation(getApplicationContext(),
            R.anim.fade_in);
fadeIn.setAnimationListener(new Animation.AnimationListener() {
        @Override
        public void onAnimationStart(Animation animation) {

        }

        @Override
        public void onAnimationEnd(Animation animation) {

        }

        @Override
        public void onAnimationRepeat(Animation animation) {

        }
    });

答案 1 :(得分:0)

从不在主线程上使用Thread.sleep。主要线程是主线程(显然),因此在主线程上睡觉是Android操作系统看到的 A 折叠 N ot R esponding。

使用第二个线程可以睡觉。您可以使用新的Thread实例或使用AsyncTask。

同样适用于runOnUiThread(在不同线程的主线程上运行):从不使用Thread.sleep 。您的应用程序将获得ANR,因为您阻止主线程执行。如果要在继续

之前休眠2秒钟,请使用其他线程(you can read more about it here

自定义线程的一个示例是创建一个新类(尽管您也可以创建一个匿名类):

public class HelloThread extends Thread {
    boolean running;
    //Constructor to get variables. 
    public void run() {
        while(running){
            //While loop is optional, if you have for an instance a game thread you need a while-loop
            //to keep executing the code
        }
    }

    public void setRunning(boolean running){
        this.running = running;
    }

}

或者正如我之前所说,匿名课程:

Thread t = new Thread(){
    @Override
    public void run() {
        super.run();
        //It is harder to get variables into here though. Declare a "running" boolean
        //In the class if you want repetitive execution
    }
 };