Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Calling from wrong thread exception

I am trying to develop an application, that uses threads to implement slideshow. I am retrieving the image path from SQLite and displaying them on the ImageView. The problem, where I got struck is, I got confused and so I am unable to understand, from which thread I am calling images() method, where I am actually implementing the slideshow.

I got the Logcat as follows -

    09-03 13:47:00.248: E/AndroidRuntime(10642): FATAL EXCEPTION: Thread-151
09-03 13:47:00.248: E/AndroidRuntime(10642): android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
09-03 13:47:00.248: E/AndroidRuntime(10642):    at android.view.ViewRootImpl.checkThread(ViewRootImpl.java:5908)

09-03 13:47:00.248: E/AndroidRuntime(10642):    at com.example.fromstart.MainActivity.images(MainActivity.java:90)
09-03 13:47:00.248: E/AndroidRuntime(10642):    at com.example.fromstart.MainActivity$2.run(MainActivity.java:59)
09-03 13:47:00.248: E/AndroidRuntime(10642):    at java.lang.Thread.run(Thread.java:841)

MainActivity.java:

public class MainActivity extends Activity
{
    ImageView jpgView;
    TextView tv;

    //adapter mDbAdapter;   
    adapter info = new adapter(this);
    String path; 
    Handler smHandler = new Handler() 
    {
        public void handleMessage(Message msg) 
        {
            TextView myTextView = 
            (TextView)findViewById(R.id.textView1);
            myTextView.setText("Button Pressed");
        }
    };
    @Override
    protected void onCreate(Bundle savedInstanceState) 
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        jpgView = (ImageView)findViewById(R.id.imageView1);
        tv = (TextView) findViewById(R.id.textView1);
    }
    @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);


        final Runnable runnable = new Runnable() 
        {
                 public void run() 
                 {
                            images();
                 }
        };
        int delay = 1000; // delay for 1 sec.
        int period = 15000; // repeat every 4 sec.
        Timer timer = new Timer();
        timer.scheduleAtFixedRate(new TimerTask() 
        {
            public void run() 
            {
                smHandler.post(runnable);
            }
        }, delay, period);
        Thread mythread = new Thread(runnable);
        mythread.start();
        return true;
}
        public void handleMessage(Message msg) 
        {             
            String string = "sample";
            TextView myTextView = (TextView)findViewById(R.id.textView1);
            myTextView.setText(string);
        }
        public void images()
        {
            try
            {
                 for(int i=0;i<=20;i++)
                {
                     path = info.getpath();
                Bitmap bitmap = BitmapFactory.decodeFile(path);
                jpgView.setImageBitmap(bitmap);

                }
            }
            catch(NullPointerException er)
            {
                String ht=er.toString();
                Toast.makeText(getApplicationContext(), ht, Toast.LENGTH_LONG).show();
            }
         }
    }

I am a newbie to android, just now started working on Threads. If you find any mistakes in my code, please point out those and please suggest me, the right way to deal with this problem.

Thanks in advance.

UPDATE:

 public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    final Handler mHandler = new Handler();

    // Create runnable for posting
    runOnUiThread(new Runnable() 
    {
        public void run() 
        {
            images();
        }
    });
    int delay = 1000; // delay for 1 sec.
    int period = 15000; // repeat every 4 sec.
    Timer timer = new Timer();
    timer.scheduleAtFixedRate(new TimerTask() 
    {
        public void run() 
        {
            images();
        }
    }, delay, period);




}

public void images()
{
    try
    {

    Toast.makeText(getApplicationContext(), "1", Toast.LENGTH_LONG).show();
             path = info.getpath(); 
             Toast.makeText(getApplicationContext(), "2", Toast.LENGTH_LONG).show();
        Bitmap bitmap = BitmapFactory.decodeFile(path);
        Toast.makeText(getApplicationContext(), "3", Toast.LENGTH_LONG).show();
        jpgView.setImageBitmap(bitmap);
        Toast.makeText(getApplicationContext(), "4", Toast.LENGTH_LONG).show();

    }
    catch(NullPointerException er) 
   {
            String ht=er.toString();
            Toast.makeText(getApplicationContext(), ht, Toast.LENGTH_LONG).show();
    }
     }

}
like image 364
nki Avatar asked Sep 03 '13 18:09

nki


1 Answers

You cannot update/access ui from from a thread.

You have this

     public void run() 
     {
           images();
     }

And in images you have

    jpgView.setImageBitmap(bitmap);

You need to use runOnUiThread for updating ui.

    runOnUiThread(new Runnable() {

                    @Override
                    public void run() {
                      // do something
                    }
                });

TimerTask also runs on a different thread. So you have use a Handler for updati ui.

You can use a handler.

Edit:

Handler m_handler;
Runnable m_handlerTask ;  
m_handler = new Handler();   
m_handlerTask = new Runnable()
{
  @Override 
  public void run() { 

    // do something. call images() 
    m_handler.postDelayed(m_handlerTask, 1000);    

  }
  };
 m_handlerTask.run();

If you still wish to use a timer task use runOnUiThread

timer.scheduleAtFixedRate(new TimerTask() 
    {
        public void run() 
        {
              runOnUiThread(new Runnable() {

                    @Override
                    public void run() {
                      images();
                    }
                }); 

        }
    }, delay, period);
like image 64
Raghunandan Avatar answered Sep 29 '22 04:09

Raghunandan