Call from an incorrect thread exception

I am trying to develop an application that uses streams to implement slide shows. I am extracting the image path from SQLite and displaying them on the ImageView. The problem that I got into is that I got confused, and therefore I can’t understand from which thread I am calling the images () method, where I actually implement the slide show.

I got 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 new to android, just now started to work on Threads. If you find errors in my code, indicate them and please offer me the correct way to solve 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(); } } } 
+4
source share
2 answers

You cannot update / access from the stream.

Do you have that

  public void run() { images(); } 

And in the images you have

  jpgView.setImageBitmap(bitmap); 

You need to use runOnUiThread to update ui.

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

TimerTask also works on another thread. This way you use the handler to update.

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 want to use the timer task, use runOnUiThread

 timer.scheduleAtFixedRate(new TimerTask() { public void run() { runOnUiThread(new Runnable() { @Override public void run() { images(); } }); } }, delay, period); 
+7
source

To update the user interface from any other thread, you should use

 runOnUiThread(<Runnable>); 

which will update your interface.

Example:

 runOnUiThread( new Runnable() { // do something on UI thread Update UI }); 
+3
source

Source: https://habr.com/ru/post/1500358/


All Articles