5

The example is pretty straightforward: i want to let the user know about what the app is doing by just showing a text (canvas.drawText()). Then, my first message appears, but not the other ones. I mean, i have a "setText" method but it doesn't updates.

onCreate(Bundle bundle) {
    super.onCreate(bundle);
    setContentView(splash); // splash is the view class
    loadResources();
    splash.setText("this");
    boundWebService();
    splash.setText("that"):
    etc();
    splash.setText("so on");
}

The view's text drawing works by doing just a drawText in onDraw();, so setText changes the text but doesn't show it.

Someone recommended me replacing the view with a SurfaceView, but it would be alot of trouble for just a couple of updates, SO... how the heck can i update the view dinamically at runtime?

It should be quite simple, just showing a text for say 2 seconds and then the main thread doing his stuff and then updating the text...

Thanks!

Update:

I tried implementing handler.onPost(), but is the same story all over again. Let me put you the code:

public class ThreadViewTestActivity extends Activity {

Thread t;
Splash splash;

/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    splash = new Splash(this);
    t = new Thread(splash);
    t.start();

    splash.setTextow("OA");
    try { Thread.sleep(4000); } catch (InterruptedException e) { }
    splash.setTextow("LALA");
}       
}

And:

public class Splash implements Runnable {

Activity activity;
final Handler myHandler = new Handler();

public Splash(Activity activity) {
    this.activity=activity;
}   

@Override
public void run() {
    // TODO Auto-generated method stub

}

public synchronized void setTextow(final String textow) {
    // Wrap DownloadTask into another Runnable to track the statistics
    myHandler.post(new Runnable() {
        @Override
        public void run() {
            TextView t = (TextView)activity.findViewById(R.id.testo);
            t.setText(textow);
            t.invalidate(); 
        }                   
    });
}
}

Although splash is in other thread, i put a sleep on the main thread, i use the handler to manage UI and everything, it doesn't changes a thing, it only shows the last update.

ferostar
  • 7,074
  • 7
  • 38
  • 61

3 Answers3

6

I haven't hit this yet, but I think the usual pattern is to do lengthy initialization in a background thread, and use Handler.post() to update the UI. See http://developer.android.com/reference/android/widget/ProgressBar.html for a different, but possibly related, example.

Also see this answer, especially the first paragraph:

The problem is most likely that you are running the splash screen (some sort of Dialog such as ProgressDialog I assume) in the same thread as all the work being done. This will keep the view of the splash screen from being updated, which can keep it from even getting displayed to the screen. You need to display the splash screen, kick off an instance of AsyncTask to go download all your data, then hide the splash screen once the task is complete.

Update (based on your update and your comment): You are not supposed to update the UI in any thread except the one where your Activity is created. Why is it impossible for you to load your resources in a background thread?

Community
  • 1
  • 1
Dan Breslau
  • 11,472
  • 2
  • 35
  • 44
  • Thanks for answering! I know it must be something "handler related", but the thing is, i must do the loadResources() and the setText() in this way, i can't just put both inside a Handler and let the UI thread know what's up. – ferostar Dec 22 '10 at 20:00
1

First: onCreate is executed on main UI thread of application so no UI updates until you leave it. Basically you need one thread to execute long running tasks and some mechanism to push updates into the UI.
Most usual approach is to extend AsyncTask see this link for further info

Nikolay Ivanov
  • 8,897
  • 3
  • 31
  • 34
0

i suppose that your view is an extended view and you call onDraw for drawing the view, so, maybe the view isn´t 'refresh' their state, so try this

onCreate(Bundle bundle) {
    setContentView(splash); // splash is the view class

    loadResources();
    splash.setText("this");
    splash.invalidate();
    boundWebService();
    splash.setText("that"):
    splash.invalidate();
    etc();
    splash.setText("so on");
    splash.invalidate();
}
Franco
  • 7,385
  • 3
  • 27
  • 22
  • Tried it and it only shows the last one of them now (the "so on" text). – ferostar Dec 21 '10 at 20:32
  • well, now instead of drawing the first one the view also draw the last one, your operations (loadResources()...etc) run too fast? put a Log.i() entry on your draw method to see what text is drawing, i suppose the view is drawing all texts... – Franco Dec 21 '10 at 20:38
  • Nothing shows in logcat although i entered Log.i(splashText) inside onDraw. – ferostar Dec 21 '10 at 21:01