-1

I'm having a bunch of textviews and buttons initially set as GONE in .xml and I'm setting up code to reveal them (make them VISIBLE) one by one in short intervals. If I use UI thread, I risk "Application not responding" (or "ANR") if the interval is longer then about 5s, but if I create new Thread then I must use

.getHandler().post(new Runnable() {
                    public void run() {
                        .setVisibility(View.VISIBLE);
                    }

which keeps going back to UI thread (in my understanding), so... what is the point then of having new Thread!?

Can someone explain and elaborate on this please :)

xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
<ScrollView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:id="@+id/sv"

        >

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical"
            >

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:background="@drawable/textview_background"
                android:text="Linija 1"
                android:id="@+id/tv1"
                android:visibility="gone"/>

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:background="@drawable/textview_background"
                android:text="Linija 2"
                android:id="@+id/tv2"
                android:visibility="gone"/>

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:background="@drawable/textview_background"
                android:text="Linija 3"
                android:id="@+id/tv3"
                android:visibility="gone"/>

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:background="@drawable/textview_background"
                android:text="Linija 4"
                android:id="@+id/tv4"
                android:visibility="gone"/>

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:background="@drawable/textview_background"
                android:text="Linija 5"
                android:id="@+id/tv5"
                android:visibility="gone"/>

            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:id="@+id/LL1"
                android:visibility="gone">

                <Button
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_weight="1"
                    android:id="@+id/btn1"
                    android:text="Btn1"/>

                <Button
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_weight="1"
                    android:id="@+id/btn2"
                    android:text="Btn2"/>

            </LinearLayout>

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:background="@drawable/my_textview_background"
                android:text="Linija 6"
                android:id="@+id/tv6"
                android:layout_gravity="end"
                android:visibility="gone"/>

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:background="@drawable/my_textview_background"
                android:text="Linija 7"
                android:id="@+id/tv7"
                android:layout_gravity="end"
                android:visibility="gone"/>

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:background="@drawable/textview_background"
                android:text="Linija 8"
                android:id="@+id/tv8"
                android:visibility="gone"/>

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:background="@drawable/textview_background"
                android:text="Linija 9"
                android:id="@+id/tv9"
                android:visibility="gone"/>

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:background="@drawable/textview_background"
                android:text="Linija 10"
                android:id="@+id/tv10"
                android:visibility="gone"/>

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:background="@drawable/textview_background"
                android:text="Linija 11"
                android:id="@+id/tv11"
                android:visibility="gone"/>

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:background="@drawable/textview_background"
                android:text="Linija 12"
                android:id="@+id/tv12"
                android:visibility="gone"/>

            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:id="@+id/LL2"
                android:visibility="gone">

                <Button
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_weight="1"
                    android:id="@+id/btn3"
                    android:text="Btn3"/>

                <Button
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_weight="1"
                    android:id="@+id/btn4"
                    android:text="Btn4"/>

            </LinearLayout>

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:background="@drawable/my_textview_background"
                android:text="Linija 13"
                android:id="@+id/tv13"
                android:layout_gravity="end"
                android:visibility="gone"/>

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:background="@drawable/my_textview_background"
                android:text="Linija 14"
                android:id="@+id/tv14"
                android:layout_gravity="end"
                android:visibility="gone"/>

</LinearLayout>



    </ScrollView>

</RelativeLayout>

test activity

@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.test_layout);
        Thread mainThread = new Thread(
                new Runnable() {
                    @Override
                    public void run() {
                        start_game();
                    }
                }
        );
        mainThread.start();
    }

public void start_game () {

Button btn1 = (Button) findViewById(R.id.btn1);
        ... btn4

TextView tv1 = (TextView) findViewById(R.id.tv1);
        ... tv14

LinearLayout LL1 = (LinearLayout) findViewById(R.id.LL1);
        LinearLayout LL2 = (LinearLayout) findViewById(R.id.LL2);

 show_line(tv1, 1000);
        show_line(tv2, 1000);
        show_line(tv3, 1000);
        show_line(tv4, 1000);
        show_line(tv5, 1000);

        btnLL(LL1, btn1, btn2, tv6, tv7);

if (btn1.isPressed())        show_line(tv8, 1000);
        if (btn2.isPressed())        show_line(tv9, 1000);
        show_line(tv10, 1000);
        show_line(tv11, 1000);
        show_line(tv12, 1000);

public void show_line(final TextView tv, int duration) {
        if (x) x=false;
        viewArray[viewIndex++]= tv;
        try {
            Thread.sleep(duration);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        tv.getHandler().post(new Runnable() {
            public void run() {
                tv.setVisibility(View.VISIBLE);
            }
        });
    }

public void btnLL (final LinearLayout LL, Button btnLeft, Button btnRight, final TextView tvLeft, final TextView tvRight) {
        linearArray[llIndex++]=LL;      
        LL.getHandler().post(new Runnable() {
            public void run() {
                LL.setVisibility(View.VISIBLE);
            }
        });

        btnLeft.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {                
                LL.getHandler().post(new Runnable() {
                    public void run() {
                        LL.setVisibility(View.GONE);
                    }
                });
                tvLeft.getHandler().post(new Runnable() {
                    public void run() {
                        tvLeft.setVisibility(View.VISIBLE);
                    }
                });
                x = true;
                myViewArray[myViewIndex++]=tvLeft;
            }
        });

        btnRight.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                LL.getHandler().post(new Runnable() {
                    public void run() {
                        LL.setVisibility(View.GONE);
                    }
                });
                tvRight.getHandler().post(new Runnable() {
                    public void run() {
                        tvRight.setVisibility(View.VISIBLE);
                    }
                });
                x = true;
                myViewArray[myViewIndex++]=tvRight;
            }
        });
        while (!x){}
    }
Nemanja
  • 211
  • 6
  • 16

1 Answers1

1

This is clearly a case of a weird / bad design. You have just the 1 UI thread. If you need to update a lot of data on the UI at once, maybe you need to refresh the screen in intervals instead? IE have a post runnable that calls itself, have it delay 2 seconds, read your states and make the UI changes. If you find it useful I can write this up..


Update post more information..

Looking at this. Clearly this is the wrong tutorial for you. Honestly I am going to vote to close this question as I don't think it can be useful for others. That said your structure should look closer to.. Though maybe you are confused on how to do this at all... If you just want them to show and hide when a user presses a button.. get rid of the thread. You do not need threads at all to do this. To me this thread looks like you are writting a game and the game is constatntly cycling. If you are waiting for the user to press a button, that is accoplished by the listener. Writting a thread would not help...

  //HERE IS WHERE YOU DECLARE THE BUTTONS
    Button btn1; //... btn4
    TextView tv1; //... tv14
    LinearLayout LL1;
    LinearLayout LL2;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.test_layout);
        //HERE IS WHERE YOU SET YOUR BUTTONS
        btn1 = (Button) findViewById(R.id.btn1);
         tv1 = (TextView) findViewById(R.id.tv1);
         LL1 = (LinearLayout) findViewById(R.id.LL1);
         LL2 = (LinearLayout) findViewById(R.id.LL2);

        //SET CLICK HANDLERS HERE
        btnRight.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                LL.setVisibility(View.GONE);
                tvRight.setVisibility(View.VISIBLE);
                x = true;
                myViewArray[myViewIndex++] = tvRight;
            } );

            btnLeft.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    LL.getHandler().post(new Runnable() {
                        public void run() {
                            LL.setVisibility(View.GONE);
                        }
                    });
                    tvLeft.getHandler().post(new Runnable() {
                        public void run() {
                            tvLeft.setVisibility(View.VISIBLE);
                        }
                    });
                    x = true;
                    myViewArray[myViewIndex++]=tvLeft;
                }
            });

        Thread mainThread = new Thread(
                new Runnable() {
                    @Override
                    public void run() {
                        start_game();
                    }
                }
        );
        mainThread.start();
    }

    public void start_game () {
// guessing you would have a do while loop here?
        show_line(tv1, 1000);
        show_line(tv2, 1000);
        show_line(tv3, 1000);
        show_line(tv4, 1000);
        show_line(tv5, 1000);

        btnLL(LL1, btn1, btn2, tv6, tv7);

        if (btn1.isPressed()) show_line(tv8, 1000);
        if (btn2.isPressed()) show_line(tv9, 1000);
        show_line(tv10, 1000);
        show_line(tv11, 1000);
        show_line(tv12, 1000);
    }

    public void show_line(final TextView tv, int duration) {
        if (x) x=false;
        viewArray[viewIndex++]= tv;
        try {
            Thread.sleep(duration); // look into post delay runnables.... thread sleep no.
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        runOnUiThread(new Runnable() { // we are on background thread. use runOnUiThread
            @Override
            public void run() {
                tv.setVisibility(View.VISIBLE);
            }
        });

    }

    public void btnLL (final LinearLayout LL, Button btnLeft, Button btnRight, final TextView tvLeft, final TextView tvRight) {
        linearArray[llIndex++]=LL;
        runOnUiThread(new Runnable() { // we are on background thread. use runOnUiThread
            @Override
            public void run() {
                LL.setVisibility(View.VISIBLE);
            }
        });

    }
StarWind0
  • 1,554
  • 2
  • 17
  • 46
  • `.postDelayed(new Runnable() { public void run() { .setVisibility(View.VISIBLE); } }, 2000);` Something like this!? – Nemanja Jan 18 '17 at 19:38
  • @Nemanja Okay I need to know exactly what you are doing. Please post all the code.. The whole activity and the XML. do @ StarWind so I am notified. – StarWind0 Jan 23 '17 at 17:14
  • here it is. Pls note that this is my 1st android app, I just started to learn :) Idea is to have a point to point tutorial looking like a messaging app, and when user press button, LinearLayout with buttons dissapear and TextView with btn text appears. I know there is a better/smarter way to do this but I have no idea how to do this other than what I came up to. I see you are a senior so hopefully you can point me in the right way. Thx @StarWind – Nemanja Jan 25 '17 at 02:12
  • Oh yes I see issues. You are setting the reference for your views in a thread. That looks like the start of a game thread. You will set these calls once as member variables make them static final. Setting them over and over is not good. Yes I'm going to have to take a closer look at this. But to answer your question if you are setting the visibility of an item in a background thread you must use that runonui thread call. an android tutorial that has you using threads right off the bat is a very bad tutorial. Especially as we rarely use normal threads. – StarWind0 Jan 25 '17 at 15:50
  • @Nemanja I did the best I could. Do a different tutorial without threading. That is very advanced if you are new to Android. Start here https://developer.android.com/training/index.html – StarWind0 Jan 25 '17 at 19:44
  • Ok thx. And what about the fact that I preloaded all the views in xml and set them to GONE and revealing them in Activity later? I know I could write methods to add them 1 by 1 w/o xml but is there any other better (3rd+) way to do the same!? @StarWind - PS for some reason when I type @S I dont get autocomplete for your name here and if i do that at beginning of comment it get deleted!? – Nemanja Jan 25 '17 at 22:45
  • @Nemanja what exactly is the concern with having them gone? Setting them Gone then back to Visible will not be an issue. – StarWind0 Jan 25 '17 at 23:48
  • @Nemanja Also I see you are new to the site. It is customary to +1 and or accept questions that help :-) – StarWind0 Jan 26 '17 at 16:15
  • Again thx. Well the only concern was that there was some other "less nooby" way to do it :) This seemed like a logic and easy way, but I would like to know if that is what a senior would do? @StarWind – Nemanja Jan 29 '17 at 02:02
  • As a senior I would start with a simpler example ;-) go follow an example by vogella or that android link I gave you.. – StarWind0 Jan 29 '17 at 08:11