Problem with thread (how to do that with a Handler ?)

Put your problem here if it does not fit any of the other categories.

Problem with thread (how to do that with a Handler ?)

Postby Stam » Mon Nov 30, 2009 1:59 pm

Hi all,

I have a little problem with a Timer ;

here is my code :

Syntax: [ Download ] [ Hide ]
Using java Syntax Highlighting
  1.  
  2. timer = new Timer();
  3.  
  4. timer.schedule(new timerLaunch(), 1000);
  5.  
  6.  
  7.  
  8. class timerLaunch extends TimerTask {
  9.  
  10.                 public void run() {    
  11.  
  12.                         hideCard();
  13.  
  14.                         return;
  15.  
  16.                 }
  17.  
  18.  
  19.  
  20. private void hideCard()
  21.  
  22. {
  23.  
  24.         for (int cardId : alreadyShowedCard.values()) {
  25.  
  26.                 ImageView image = (ImageView) gridview.getChildAt(cardId);
  27.  
  28.                 image.setImageResource(R.drawable.cartedos);
  29.  
  30. }
  31.  
  32.  
Parsed in 0.031 seconds, using GeSHi 1.0.8.4


So, that method just doing :
'After 1 sec, I change all my imageResource'

It works, but when he do the first imageResource change, it goes in the Timer.class of java.util (that I don't see, because I don't have the source...)
And then it stop...

But I have no log and no error !

When I do something like this :

Syntax: [ Download ] [ Hide ]
Using java Syntax Highlighting
  1.  
  2. private void hideCard()
  3.  
  4. {
  5.  
  6.         for (int cardId : alreadyShowedCard.values()) {
  7.  
  8.                 ImageView image = (ImageView) gridview.getChildAt(cardId);
  9.  
  10.                 System.out.println("test");
  11.  
  12. }
  13.  
  14.  
Parsed in 0.032 seconds, using GeSHi 1.0.8.4


It's ok, so, it's the setImageResource who 'crash' my timer, but why... ?

If anyone can help me, or tell me how to do the java source while debuging, it will help a lot ! Thanks !
Last edited by Stam on Mon Nov 30, 2009 4:11 pm, edited 1 time in total.
Stam
Junior Developer
Junior Developer
 
Posts: 22
Joined: Wed Nov 25, 2009 1:49 pm
Location: Lille, France

Top

Postby Stam » Mon Nov 30, 2009 2:53 pm

Ok, I have some news, there is no log, but for test I put my setImageResource in a try/catch and I obtain that :

Only the original thread that created a view hierarchy can touch its views.

So, what can I do ? :x
Stam
Junior Developer
Junior Developer
 
Posts: 22
Joined: Wed Nov 25, 2009 1:49 pm
Location: Lille, France

Postby padde » Mon Nov 30, 2009 6:06 pm

Use AsyncTask or try to send messages within your runnable to a handler in your UI thread.
Both topics discussed about a million times already... search function is your friend ;)
padde
Master Developer
Master Developer
 
Posts: 443
Joined: Wed Apr 08, 2009 4:52 pm

Postby Stam » Tue Dec 01, 2009 10:19 am

Hi,

Yes I search for Handler solution etc.

But it ain't work :(

I do that :

Syntax: [ Download ] [ Hide ]
Using java Syntax Highlighting
  1.  
  2. final Handler mHandler = new Handler();
  3.  
  4.         final Runnable mUpdateResults = new Runnable() {
  5.  
  6.                 public void run() {
  7.  
  8.                         updateResultsInUi();
  9.  
  10.                 }
  11.  
  12.         };
  13.  
  14.  
  15.  
  16. // My treatment
  17.  
  18. private void updateResultsInUi() {
  19.  
  20.                 for (Integer imageId : alreadyShowedCard.values()) {
  21.  
  22.                         ImageView image = (ImageView) gridview.getChildAt(imageId);
  23.  
  24.                         try{
  25.  
  26.                         image.setImageResource(R.drawable.cartedos);
  27.  
  28.                         }catch(Exception e){
  29.  
  30.                                 e.printStackTrace();
  31.  
  32.                         }
  33.  
  34.                 }
  35.  
  36.         }
  37.  
  38.  
  39.  
  40. class timerLaunch extends TimerTask {
  41.  
  42.                 public void run() {
  43.  
  44.                         Thread t = new Thread() {
  45.  
  46.                                 public void run() {
  47.  
  48.                                         mHandler.post(mUpdateResults);
  49.  
  50.                                 }
  51.  
  52.                         };
  53.  
  54.                         t.start();
  55.  
  56.                 }
  57.  
  58.  
  59.  
  60. //My timer
  61.  
  62. timer = new Timer();
  63.  
  64. timer.schedule(new timerLaunch(), 1000);
  65.  
  66.  
Parsed in 0.037 seconds, using GeSHi 1.0.8.4


I have no bug, but the updateResultsInUi method is executing every 1s, and sur imageResource don't change...

Have you another solution ?
Stam
Junior Developer
Junior Developer
 
Posts: 22
Joined: Wed Nov 25, 2009 1:49 pm
Location: Lille, France

Postby padde » Tue Dec 01, 2009 10:38 am

Did you try to invalidate the imageview after changing the imageresource?
padde
Master Developer
Master Developer
 
Posts: 443
Joined: Wed Apr 08, 2009 4:52 pm

Postby Stam » Tue Dec 01, 2009 11:09 am

I try to do that :

Syntax: [ Download ] [ Hide ]
Using java Syntax Highlighting
  1.  
  2. gridview.invalidateViews();
  3.  
  4.  
Parsed in 0.034 seconds, using GeSHi 1.0.8.4


And it's ok !

Thanks a lot ;)

But I still have the problem that the thread call my method every 1s (the time of the timer)

I try to cancel the timer in my updateResultsInUi method but it won't work...

Have you any idea ? Thanks a lot ;)
Stam
Junior Developer
Junior Developer
 
Posts: 22
Joined: Wed Nov 25, 2009 1:49 pm
Location: Lille, France

Top

Postby padde » Tue Dec 01, 2009 12:05 pm

Well your TimerTask class is wrong.. you start it once and in there you create a new thread thats running basicly forever.

Try this:
Syntax: [ Download ] [ Hide ]
Using java Syntax Highlighting
  1.  
  2. class timerLaunch extends TimerTask {
  3.  
  4.     public void run() {
  5.  
  6.         mHandler.post(mUpdateResults);
  7.  
  8.     }
  9.  
  10. }
  11.  
  12.  
  13.  
  14. timer = new Timer();
  15.  
  16. timer.schedule(new timerLaunch(), 0, 1000);   // this will start the timer task periodical.
  17.  
  18.  
Parsed in 0.036 seconds, using GeSHi 1.0.8.4


If it helps.. here is a complete example.. just to show timertask stuff in combination with handler.. no imageview
stuff ;)

Test.java
Syntax: [ Download ] [ Hide ]
Using java Syntax Highlighting
  1.  
  2. package de.padde.test;
  3.  
  4.  
  5.  
  6. import java.util.Timer;
  7.  
  8. import java.util.TimerTask;
  9.  
  10.  
  11.  
  12. import android.app.Activity;
  13.  
  14. import android.os.Bundle;
  15.  
  16. import android.os.Handler;
  17.  
  18. import android.util.Log;
  19.  
  20. import android.view.View;
  21.  
  22. import android.view.View.OnClickListener;
  23.  
  24. import android.widget.Button;
  25.  
  26.  
  27.  
  28. public class Test extends Activity {
  29.  
  30.     Timer mTimer;
  31.  
  32.     final Handler mHandler = new Handler();
  33.  
  34.    
  35.  
  36.     final Runnable mUpdateResults = new Runnable() {
  37.  
  38.         public void run() {
  39.  
  40.              Log.v("TEST", "PONG");
  41.  
  42.         }
  43.  
  44.     };    
  45.  
  46.    
  47.  
  48.     final class tt extends TimerTask {
  49.  
  50.         public void run() {
  51.  
  52.             Log.v("TEST", "PING");
  53.  
  54.             mHandler.post(mUpdateResults);
  55.  
  56.         }
  57.  
  58.     }
  59.  
  60.    
  61.  
  62.     public void onCreate(Bundle savedInstanceState) {
  63.  
  64.         super.onCreate(savedInstanceState);
  65.  
  66.         setContentView(R.layout.main);
  67.  
  68.        
  69.  
  70.         Button b1 = (Button) findViewById(R.id.start);
  71.  
  72.         Button b2 = (Button) findViewById(R.id.stop);
  73.  
  74.        
  75.  
  76.         b1.setOnClickListener(new OnClickListener() {
  77.  
  78.             public void onClick(View v) {
  79.  
  80.                 mTimer = new Timer();
  81.  
  82.                 mTimer.schedule(new tt(), 0, 1000);
  83.  
  84.             }
  85.  
  86.         });
  87.  
  88.        
  89.  
  90.         b2.setOnClickListener(new OnClickListener() {
  91.  
  92.             public void onClick(View v) {
  93.  
  94.                 mTimer.cancel();
  95.  
  96.                 mTimer.purge();
  97.  
  98.             }
  99.  
  100.         });
  101.  
  102.     }
  103.  
  104. }
  105.  
  106.  
Parsed in 0.042 seconds, using GeSHi 1.0.8.4


res/layout/main.xml
Syntax: [ Download ] [ Hide ]
Using xml Syntax Highlighting
  1.  
  2. <?xml version="1.0" encoding="utf-8"?>
  3.  
  4. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  5.  
  6.    android:orientation="vertical"
  7.  
  8.    android:layout_width="fill_parent"
  9.  
  10.    android:layout_height="fill_parent">
  11.  
  12.     <Button
  13.  
  14.        android:id="@+id/start"
  15.  
  16.        android:layout_width="wrap_content"
  17.  
  18.        android:layout_height="wrap_content"
  19.  
  20.        android:text="Start"
  21.  
  22.    />
  23.  
  24.     <Button
  25.  
  26.        android:id="@+id/stop"
  27.  
  28.        android:layout_width="wrap_content"
  29.  
  30.        android:layout_height="wrap_content"
  31.  
  32.        android:text="Stop"
  33.  
  34.    />
  35.  
  36. </LinearLayout>
  37.  
  38.  
Parsed in 0.003 seconds, using GeSHi 1.0.8.4
padde
Master Developer
Master Developer
 
Posts: 443
Joined: Wed Apr 08, 2009 4:52 pm

Postby Stam » Tue Dec 01, 2009 2:05 pm

Hi,

Thanks a lot for your response, now I understand the thread better ;)

For your example, it works, but when I try to cancel/purge my timer in my timerTask or my handler it doesn't work... I have to do a button like you, and it work...

Have you a solution ?

I try to not do a timer but a Thread.sleep(1000) but it doesn't work : my gridView wont dislpay image when the Thread is sleeping...
Stam
Junior Developer
Junior Developer
 
Posts: 22
Joined: Wed Nov 25, 2009 1:49 pm
Location: Lille, France

Postby padde » Tue Dec 01, 2009 2:56 pm

I need to see the code.. Thread.sleep sounds like you dont get what you should get out of my
example :)
If you do it right you can cancel/purge the timer from anywhere in the UI thread or wherever
you created the timer in the first place.
padde
Master Developer
Master Developer
 
Posts: 443
Joined: Wed Apr 08, 2009 4:52 pm

Postby Stam » Tue Dec 01, 2009 3:29 pm

Here is my code

Syntax: [ Download ] [ Hide ]
Using java Syntax Highlighting
  1.  
  2. // My timer have to start in 5s
  3.  
  4. timer = new Timer();
  5.  
  6. timer.schedule(new timerLaunch(), 5000);
  7.  
  8.  
  9.  
  10. // The task who start my Handler
  11.  
  12. class timerLaunch extends TimerTask {
  13.  
  14.         public void run() {
  15.  
  16.                 mHandler.post(mUpdateResults);
  17.  
  18.         }
  19.  
  20. }
  21.  
  22.  
  23.  
  24. //The method of the handler, who have to stop the timer at the end of the method
  25.  
  26. private void updateResultsInUi() {
  27.  
  28.         for (Integer imageId : alreadyShowedCard.values()) {
  29.  
  30.                 ImageView image = (ImageView) gridview.getChildAt(imageId);
  31.  
  32.                 image.setImageResource(R.drawable.cartedos);
  33.  
  34.                 gridview.invalidateViews();
  35.  
  36.         }
  37.  
  38.         timer.cancel();
  39.  
  40.         timer.purge();
  41.  
  42. }
  43.  
  44.  
Parsed in 0.037 seconds, using GeSHi 1.0.8.4


But the timer don't stop.

I can stop it with a button, like your example, but I can't in the method, don't know why...

Hope you can help me ^^
Stam
Junior Developer
Junior Developer
 
Posts: 22
Joined: Wed Nov 25, 2009 1:49 pm
Location: Lille, France

Postby padde » Tue Dec 01, 2009 3:44 pm

Well.. thats not enough.. i dont know where the code parts are located.
And i dont really get what you are trying to achieve. You start the timertask
just once.. because you use "timer.schedule(new timerLaunch(), 5000)" this
will start the timertask once after a delay of 5 seconds. The timer cancel itself
after that. And why you cancel it in the updateResultsInUi method? This will stop
the timertask after 1 run even if it would run periodical... to simply update your
imageviews once this hole thing is a bit of overkill.
So i need 2 things to help you further from here:

1. Complete codes not just parts (i dont need all classes etc. just the hole context of the problem)
2. Some description about what you trying to achieve with all the code you posted so far.
padde
Master Developer
Master Developer
 
Posts: 443
Joined: Wed Apr 08, 2009 4:52 pm

Postby Stam » Tue Dec 01, 2009 4:09 pm

Well, I think I understand...

I use a ImageAdapter (extands BaseAdapter) to set up my Image,

So, I have an Image List, and after the GetView, I do that :

Syntax: [ Download ] [ Hide ]
Using java Syntax Highlighting
  1.  
  2. // All my elements are displayed (I have the same number of element in my gridview and in my image list), I dispatch an event
  3.  
  4. if(gridview.getChildCount() == mThumbs.size()){
  5.  
  6.         finishListener.onFinish();
  7.  
  8. }
  9.  
  10.  
Parsed in 0.035 seconds, using GeSHi 1.0.8.4


And it's when this event is dispatch that I start my timer.

But, I think when I do image.setImageResource, or when I do the GridView.invalidateViews(), the GetView method is call, so I dispatch the event again, so start my timer again...
Stam
Junior Developer
Junior Developer
 
Posts: 22
Joined: Wed Nov 25, 2009 1:49 pm
Location: Lille, France

Top

Return to Other Coding-Problems

Who is online

Users browsing this forum: No registered users and 16 guests