Question

I am attempting to expand my application by adding a TabHost and some tabs to navigate extra features. The current app basically searches a database. The current application workflow:

  1. App loads to a login screen
  2. User logs in
  3. User gets a search form and inputs data, presses "search"
  4. Search loads a list activity of results...

With the new tabs, there is a separate tab for searching. I want all the seach activities to remain inside that tab group. So I've created an activity group to handle all of these:

public class searchGroup extends ActivityGroup {        
    public static searchGroup group;
    private ArrayList<View> history;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
          super.onCreate(savedInstanceState);
          this.history = new ArrayList<View>();
          group = this;      
          View view = getLocalActivityManager().startActivity("search", new Intent(this,search.class).addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)).getDecorView();
          replaceView(view);
       }

    public void replaceView(View v) {               
        history.add(v);                
        setContentView(v);
    }

    public void back() {
        if(history.size() > 0) {
            history.remove(history.size()-1);
            setContentView(history.get(history.size()-1));
        }else {
            finish();
        }
    }

   @Override
    public void onBackPressed() {
       searchGroup.group.back();
        return;
    }
}

In my search activity's Search button onClickListener:

view = searchGroup.group.getLocalActivityManager().startActivity("search_results",new Intent(search.this, search_results.class).addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)).getDecorView();
searchGroup.group.replaceView(view);

This is where I get the crash:

02-11 13:43:49.481: E/AndroidRuntime(1165): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.myApp/com.myApp.search_results}: android.view.WindowManager$BadTokenException: Unable to add window -- token android.app.LocalActivityManager$LocalActivityRecord@40543360 is not valid; is your activity running?

However, if I uncomment a line from the search_result activity's onCreate:

new LoadSearches().execute();

no crash, but I get nothing obviously. LoadSearches() is an AsyncTask that does the heavy lifting of going out to the server and running the search string and then populating the returned data into the ListActivity in onPostExecute().

I don't quite understand why its crashing here and not normally when I switch activities. How should I tackle this? Is there a better way? I've read a little bit about Fragments but haven't done anything with it yet.

Was it helpful?

Solution

I have decided, after much pulling my hair out, to go with fragments. Some resources I found useful for converting my existing app to use Fragments and tabs:

Fragments in Android 2.2.1, 2.3, 2.0. Is this possible?

http://www.e-nature.ch/tech/?p=55

http://thepseudocoder.wordpress.com/2011/10/04/android-tabs-the-fragment-way/

I also had an issue with pass data between my activities. The way to pass data between activities using an intent/bundle doesn't really work the same but can modified slightly and still work.

The old way (passing data from Activity1 to Activity2):

Activity1

Intent myIntent = new Intent(search.this, search_results.class);
Bundle b = new Bundle();
b.putString("SEARCHSTRING", strSearch);
myIntent.putExtras(b);
startActivityForResult(myIntent, 0);

Activity2

Bundle b = getIntent().getExtras();
strSearch = b.getString("SEARCHSTRING");

Using fragments I had to create an initializer for Activity2:

public search_results newInstance(String strSearch){
  search_results f = new search_results();
  Bundle b = new Bundle();
  b.putString("SEARCHSTRING", strSearch);
  f.setArguments(b);        
  return f;     
}

using this, the new method using Fragments:

Avtivity1

Fragment newFragment = new search_results().newInstance(strSearch);
FragmentTransaction ft = getFragmentManager().beginTransaction();
ft.replace(R.id.realtabcontent, newFragment);
ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
ft.addToBackStack(null);
ft.commit();  

Activity2 (onCreateView)

Bundle b = getArguments();
strSearch = b.getString("SEARCHSTRING");

I hope this helps someone as it was difficult for me to find all this information in one spot.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top