-3

My problem: I actually want to set the visibility of my ImageView on random basis. I mean each Image View will be Visible randomly after few milliseconds but my my app unexpectedly crashes all the time. Though, I'm new to android development but good at Java J2SE. Please tell me what I'm doing is it a blunder or a mistake by chance? please! thanks in advance!

 package com.example.app;

 import java.util.Random;
 import android.os.Bundle;
 import android.app.Activity;
 import android.view.Menu;
 import android.view.View;
 import android.widget.Button;
 import android.widget.ImageView;
 import android.widget.TextView;

public class MainActivity extends Activity {
private Button b;
public ImageView I1;
public ImageView I2;
public ImageView I3;
public ImageView I4;
public TextView T;
public TextView s;
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

     I1=new ImageView(this);
     I1=(ImageView) findViewById(R.id.imag1);
     I1.setVisibility(View.INVISIBLE);

     I2=new ImageView(this);
     I2=(ImageView) findViewById(R.id.imag2);
     I2.setVisibility(View.INVISIBLE);

     I3=new ImageView(this);
     I3=(ImageView) findViewById(R.id.imag3);
     I3.setVisibility(View.INVISIBLE);

     I4=new ImageView(this);
     I4=(ImageView) findViewById(R.id.imag4);
     I4.setVisibility(View.INVISIBLE);

     T=(TextView)findViewById(R.id.time);
     s=(TextView)findViewById(R.id.score);

    Thread t=new Thread(new MyThread());
    t.start();
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.main, menu);
    return true;
}

private class MyThread implements Runnable{
    Random randomGenerator = new Random();
    int n;
    public void run(){

        while(true){
            n=randomGenerator.nextInt(8);

            if(n==1){
                I1.setVisibility(View.VISIBLE);

            }
            if(n==2){
                I2.setVisibility(View.VISIBLE);
            }

            if(n==3){
                I3.setVisibility(View.VISIBLE);
            }

            if(n==4){
                I4.setVisibility(View.VISIBLE);
            }
            try {
                Thread.currentThread().sleep(500);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                 e.getStackTrace();
            }
        }

    }




}
}

THE EDITED CODE:

  public ImageView I1;
  public ImageView I2;
  public ImageView I3;
  public ImageView I4;
  public TextView T;
  public TextView s;
  Random randomGenerator = new Random();
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

     I1=new ImageView(this);
     I1=(ImageView) findViewById(R.id.imag1);
     I1.setVisibility(View.INVISIBLE);

     I2=new ImageView(this);
     I2=(ImageView) findViewById(R.id.imag2);
    I2.setVisibility(View.INVISIBLE);

     I3=new ImageView(this);
     I3=(ImageView) findViewById(R.id.imag3);
    I3.setVisibility(View.INVISIBLE);

     I4=new ImageView(this);
     I4=(ImageView) findViewById(R.id.imag4);
     I4.setVisibility(View.INVISIBLE);

     T=(TextView)findViewById(R.id.time);
     s=(TextView)findViewById(R.id.score);


     runOnUiThread(new Runnable() //run on ui thread
      {
         int n;
           public void run(){ 
               while(true){

                n=randomGenerator.nextInt(4)+1;

                if(n==1){
                    I1.setVisibility(View.VISIBLE);

                }
                if(n==2){
                    I2.setVisibility(View.VISIBLE);
                }

                if(n==3){
                    I3.setVisibility(View.VISIBLE);
                }

                if(n==4){
                    I4.setVisibility(View.VISIBLE);
                }

            }
           }
       });
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.main, menu);
    return true;
}
Tech Nerd
  • 822
  • 1
  • 13
  • 39

3 Answers3

1

android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.

You must be getting an exception as above. You need to update ui on the UI thread. You are updating UI in the thread. Hence the exception and crash.

Inside your thread use runOnUiThread to update UI

      runOnUiThread(new Runnable() //run on ui thread
      {
           public void run() 
           { 
                 while(true){
                 n=randomGenerator.nextInt(8);

                 if(n==1){
                  I1.setVisibility(View.VISIBLE);
                 }
                 ....
                 }
           }
       });

Also remove this I1=new ImageView(this); since you are initializing as I1=(ImageView) findViewById(R.id.imag1);

Edit:

I would recommend using a Handler for this purpose

        int n;
    Handler m_handler;
    Runnable m_handlerTask ; 
    Random r; 

Declare the above as class variables;

Inside the activity onCrate() use a handler as below

          r= new Random();
        m_handler= new Handler();
        m_handlerTask = new Runnable()
        {
             @Override 
             public void run() {
                 n=r.nextInt(4)+1;
                    if(n==1){
                        I1.setVisibility(View.VISIBLE);
                        I2.setVisibility(View.INVISIBLE);
                        I3.setVisibility(View.INVISIBLE);
                        I4.setVisibility(View.INVISIBLE);

                    }
                    if(n==2){
                        I2.setVisibility(View.VISIBLE);
                        I1.setVisibility(View.INVISIBLE);
                        I3.setVisibility(View.INVISIBLE);
                        I4.setVisibility(View.INVISIBLE); 
                    }

                    if(n==3){
                        I3.setVisibility(View.VISIBLE);
                        I1.setVisibility(View.INVISIBLE);
                        I2.setVisibility(View.INVISIBLE);
                        I4.setVisibility(View.INVISIBLE); 
                    }

                    if(n==4){
                        I4.setVisibility(View.VISIBLE);
                        I1.setVisibility(View.INVISIBLE);
                        I3.setVisibility(View.INVISIBLE);
                        I2.setVisibility(View.INVISIBLE); 
                    }
                  m_handler.postDelayed(m_handlerTask, 50);
                      // 50 milli seconds. set this to desired number
             }
        };
        m_handlerTask.run();  

And remember to stop the handler when not required

          m_handler.removeCallbacks(m_handlerTask);
Raghunandan
  • 132,755
  • 26
  • 225
  • 256
  • where should I put this piece of code please help me I am new to android please help me I will be thankful to you please Sir – Tech Nerd May 10 '13 at 12:32
  • 1
    use the above inside the thread run method – Raghunandan May 10 '13 at 12:33
  • how can i run this I mean I have placed this in my main Thread and now how should i call this run method? – Tech Nerd May 10 '13 at 12:35
  • 1
    @JunaidHassan you start you thread as normally as you do just remember to update ui on the ui thread. just use the above inside the run method of your thread and run the app – Raghunandan May 10 '13 at 12:38
  • now the app is not responding at all! another crash ;( – Tech Nerd May 10 '13 at 12:41
  • 1
    post the logcat along with updated code under the heading edit. keep the old post in your question add a heading edit and update code along with logcat – Raghunandan May 10 '13 at 12:44
  • Sir I have edited my code the app runs fine now but it is showing a simple white screen and become unresponsive even on pressing any key i.e back key – Tech Nerd May 10 '13 at 12:50
  • and after a minute a dialogue box occurs saying Sorry! Activity app is not responding! – Tech Nerd May 10 '13 at 12:51
  • 1
    @JunaidHassan the while loop is the problem – Raghunandan May 10 '13 at 12:55
  • I have tried while(!Thread.currentThread().isInterrupted()) but still it wont work for me – Tech Nerd May 10 '13 at 12:58
  • 1
    @JunaidHassan check the edit above. i have tested the above edit code and it works on my samsung galaxy s3 first 50 milli seconds one image is visible rest all invisible. This is repeated every 50 milli seconds. Is this what you are looking for?? – Raghunandan May 10 '13 at 14:36
  • LOLS thanks for your help dear really God bless you for giving me the right paths and hints – Tech Nerd May 10 '13 at 14:52
1

I think you want full code. You can use timer. see the following code.

public class MainActivity extends Activity {

public ImageView I1;
public ImageView I2;
public ImageView I3;
public ImageView I4;
public TextView T;
public TextView s;
int n;
Timer t;
TimerTask task;

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

    I1 = (ImageView) findViewById(R.id.imag1);
    I1.setVisibility(View.INVISIBLE);

    I2 = (ImageView) findViewById(R.id.imag2);
    I2.setVisibility(View.INVISIBLE);

    I3 = (ImageView) findViewById(R.id.imag3);
    I3.setVisibility(View.INVISIBLE);

    I4 = (ImageView) findViewById(R.id.imag4);
    I4.setVisibility(View.INVISIBLE);

    T = (TextView) findViewById(R.id.time);
    s = (TextView) findViewById(R.id.score);
    startTimer();
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    getMenuInflater().inflate(R.menu.activity_main, menu);
    return true;
}

public void startTimer() {
    //Random randomGenerator = new Random();
    //n=randomGenerator.nextInt(8);
            final Random randomGenerator = new Random();

    t = new Timer();
    task = new TimerTask() { 

        @Override
        public void run() {
            runOnUiThread(new Runnable() {

                public void run() {
                    //n++;
                                            n=randomGenerator.nextInt(8);
                    if (n == 1) {
                        I1.setVisibility(View.VISIBLE);
                                                    I2.setVisibility(View.INVISIBLE);
                                                    I3.setVisibility(View.INVISIBLE);
                                                    I4.setVisibility(View.INVISIBLE);

                    }
                    if (n == 2) {
                        I1.setVisibility(View.INVISIBLE);
                                                    I2.setVisibility(View.VISIBLE);
                                                    I3.setVisibility(View.INVISIBLE);
                                                    I4.setVisibility(View.INVISIBLE);
                    }

                    if (n == 3) {
                        I1.setVisibility(View.INVISIBLE);
                                                    I2.setVisibility(View.INVISIBLE);
                                                    I3.setVisibility(View.VISIBLE);
                                                    I4.setVisibility(View.INVISIBLE);
                    }

                    if (n == 4) {
                        I1.setVisibility(View.INVISIBLE);
                                                    I2.setVisibility(View.INVISIBLE);
                                                    I3.setVisibility(View.INVISIBLE);
                                                    I4.setVisibility(View.VISIBLE);
                    }
                }
            });
        }
    };
    t.scheduleAtFixedRate(task, 0, 1000);
}
}

This will work perfectly. I hope this will help you.

Gunaseelan
  • 14,415
  • 11
  • 80
  • 128
0

It is perfect ! 100%

        package com.example.abc;

          import java.util.Random;
        import java.util.Timer;
       import java.util.TimerTask;

      import android.os.Bundle;
      import android.app.Activity;
     import android.content.Intent;
     import android.view.Menu;
  import android.view.View;
  import android.widget.Button;
   import android.widget.TextView;

      public class Test extends Activity {


      public Button B;
      public Button B1;
        public TextView S;
          int count=0;

       Random randomGenerator = new Random();
      int n;
       int i;
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_test);


    B=new Button(this);
    B=(Button)findViewById(R.id.button1);
    B.setVisibility(View.INVISIBLE);

    B1=new Button(this);
    B1=(Button)findViewById(R.id.button2);
    B1.setVisibility(View.INVISIBLE);
    S=(TextView)findViewById(R.id.score);
        B.setOnClickListener(new View.OnClickListener() {

        @Override
        public void onClick(View arg0) {
            count+=1;
            S.setText(Integer.toString(count));
        }
    });
     B.setOnClickListener(new View.OnClickListener() {

@Override
public void onClick(View arg0) {
    count+=1;
    S.setText(Integer.toString(count));
}
   });
    runThread();

}

private void runThread() {

    new Thread() {
        public void run() {
            while ( i++ < 1200) {
                if(i==1200){
                    startActivity(new Intent(Test.this,Game.class));
                    break;
                }
                try {
                    runOnUiThread(new Runnable() {

                        @Override
                        public void run() {
                            n = randomGenerator.nextInt(4)+1;

                            if(n==2){
                                B.setVisibility(View.VISIBLE);

                                B1.setVisibility(View.INVISIBLE);
                            }
                            if(n==4){
                                B.setVisibility(View.INVISIBLE);
                                B1.setVisibility(View.VISIBLE);
                            }
                        }
                    });
                    Thread.sleep(50);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }.start();
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.test, menu);
    return true;
}
    }
Tech Nerd
  • 822
  • 1
  • 13
  • 39
  • Remember to stop the thread when not needed. It will keep running. Stop it in onPause() – Raghunandan May 10 '13 at 15:02
  • Ok tell me if it is possible that when press the back key the thread will stop or can i use system.exit command to come out. I mean is there any windowlistener like thing in android? – Tech Nerd May 10 '13 at 16:07
  • In your onPause() use this m_handler.postDelayed(m_handlerTask, 1000); For system.exit(0) i would not do that. reason check the link http://stackoverflow.com/questions/2033914/quitting-an-application-is-that-frowned-upon – Raghunandan May 10 '13 at 16:09
  • when you press back button activity is popped for the back stack and destroyed. Activity lifecycle. onPause()--->onStop()--->onDestroyed(). so use this in onPause() m_handler.removeCallbacks(m_handlerTask);. Sorry i posted this m_handler.postDelayed(m_handlerTask, 1000); in the above comment instead of m_handler.removeCallbacks(m_handlerTask); – Raghunandan May 10 '13 at 16:27