views:

47

answers:

1

I've got an TabActivity implementing TabContentFactory, which starts an AsyncTask in onCreate() to fetch the data for the tabs. When the AsyncTask has finished, onPostExecute() could directly update the UI-elements, right? Meaning, since that method runs in the UI-Thread no further thread-synchronization would be required when accessing UI-elements?

Anyway, the problem I have is that my UI-Thread calls createTabContent() in the TabActivity while the AsyncTask is still busy. I have to add at least one tab, or I get a NullPointerException. But how do I only add tabs when my AsyncTask has finished and the ProgressDialog has been dismissed?

I'd be glad if someone could help...

+1  A: 
When the AsyncTask has finished, onPostExecute() could directly update the 
UI-elements, right? Meaning, since that method runs in the UI-Thread no further 
thread-synchronization would be required when accessing UI-elements?

Right.

Anyway, the problem I have is that my UI-Thread calls createTabContent() in the
TabActivity while the AsyncTask is still busy.

If you need to update UI while AsyncTask is still running in background, then override AsyncTask.onProgressUpdate(..) and then call AsyncTask.publishProgress(..) from within the AsyncTask.doInBackground(..).

I have to add at least one tab, or I get a NullPointerException. But how do I 
only add tabs when my AsyncTask has finished and the ProgressDialog has been 
dismissed?

I don't understand this. Could you please explain in more detail?

Anyway, watch for this things:

  1. Start AsyncTask only after TabActivity is fully created. Start it from onPostCreate() instead of onCreate(). This might be a source of your NullPointerException.
  2. You can update any activities from UI thread within AsyncTask.onPostExecute(..)
  3. If you need to update UI while AsyncTask is still running in background, then call AsyncTask.publishProgress(..) from within the AsyncTask.doInBackground(..)
Peter Knego
Hi, thanks for the answer! You said I should start AsyncTask only after TabActivity is fully created - that's exactly my problem. I don't want to display any tab before AsyncTask has finished. :-/
cody
I forgot to explain: Everything works perfectly, I only want the UI-Thread to wait for the data. I considered to initialize the TabActivity with my 5 tabs containing one empty ScrollView each and then adding content to these in the AsyncTask.onPostExecute(..) . But I'm not sure if that would work...?
cody
It should work. You can add/change content at any time after widgets are initialized. For user convenience you should show ProgressBar and replace it with content after it's loaded. You can update progressively (tab after tab) as content is available. See point 3. above.
Peter Knego
Ok.. I tried and added 5 tabs. For each I called setContent(this), and simply returned a new ScrollView in createTabContent(). But the method is only called once until TabActivity is fully created. So I've only got one child in tabHost.getTabContentView(). :-/ Is it somehow possible to force the call of createTabContent(), so I could access the childs?
cody
I checked it and it seems that tab content can not be altered once tab is created. A single tab even canćt even be removed (only all tabs at once).
Peter Knego
But since you created tabs with ScrollView in them you just need to update contents of the this ScrollView. Just ScrollView.removeAllViews() and then ScrollView.AddView(..).
Peter Knego
It's a pitty. The only way to add ScrollViews to each of the 5 tabs is to use 5 same xml-elements or to use a TabContentFactory. As the xml solution means redundancy I'd rather use the Factory. But the createTabContent()-method is only called ONCE until my AsyncTask has finished, so there is no way to access any other as the first ScrollView...
cody
Here ia an example: http://developer.android.com/resources/samples/ApiDemos/src/com/example/android/apis/view/Tabs2.html
Peter Knego
Above example adds a few different TextViews. When data changes it should be possible to call tabHost.getTabWidget().getChildTabViewAt(int index) to get a particular TextView (in your case ScrollView), shouldn't it?
Peter Knego
Ok I'll try that...
cody
Ok thanks Peter, I think I finally made it... I checked for an existent ScrollView in createTabContent() and in the update-method which is used by the AsyncTask. I added the content directly to the ScrollViews and the view hierarchy looks good. The only problem now is that all ScrollViews lie above each other and are all visible at the same time, until I've clicked through all tabs... but that should be easy to solve.Thanks again! And have a nice evening ;)
cody
Only as addition: On startup I hide all tab content views except one simply with: contentView.setVisibility(View.GONE);
cody