1

So the thing is i want to imitate the process of bubble sort algorithm for my homework. The way i want to do this is - to play the first fade out animation, then stop my for loop, wait until the animation is done, reassign values, play the second animation, wait until it's done and resume the for loop. I found Thread.sleep() but in the end my app is freezing or the screen is black until all the animations are done. I have experimented a lot so my code looks pretty bad(sorry).

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;
    }
}
M.Mavini
  • 589
  • 8
  • 20
  • 1
    If you are making your main thread sleep, that means that your app will freeze ofcourse. – Yash Sep 17 '17 at 16:08

2 Answers2

1

Using Thread.sleep() from the main thread caused the app to freeze, Use animation callbacks as below:

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) {

        }
    });
Nabin Bhandari
  • 15,949
  • 6
  • 45
  • 59
0

Never use Thread.sleep on the main thread. The main thread is the main thread (obviously) so sleeping on the main thread is something the Android OS sees as an Application Not Responding if you sleep for too long. Generally, you should avoid blocking tasks on the main thread if you can.

Use a second thread to be able to sleep. You can either use a new Thread instance or use an AsyncTask.

Same applies to runOnUiThread (run on the main thread from a different thread): Never use Thread.sleep. Your app will get an ANR because you block the main thread from executing. Use a different thread (you can read more about it here) if you want to sleep for 2 seconds before continuing


An example of a custom thread is by creating a new class (though you can also create an anonymous class):

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;
    }

}

Or as I said earlier, anonymous class:

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
    }
 };
Zoe
  • 27,060
  • 21
  • 118
  • 148