androidandroid-tabhostactivitygroupandroid-tabactivity

How to remove all activities from ActivityGroup stack and load the first activity in current tab on tab click event


I created a project long ago using the TabActivity and ActivityGroup (deprecated now).

The question is may be simple but first I want to clarify the flow. I have 4 tabs in my Tabhost. I have used the following code to keep track of activity back stack.

MyActivityGroup.java

public class MyActivityGroup extends ActivityGroup {
    public static Stack<String> stack;

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    if (stack == null) {
        stack = new Stack<String>();
    }

    push("1stStackActivity", new Intent(this, Home.class));

}

@Override
public void finishFromChild(Activity child) {
    pop();
}

@Override
public void onBackPressed() {

    pop();

}

public void push(String id, Intent intent) {
    Window window = getLocalActivityManager().startActivity(id,
            intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP));
    if (window != null) {
        stack.push(id);
        setContentView(window.getDecorView());
    }
}

public void pop() {
    if (stack.size() == 1) {

        finish();
    }

    LocalActivityManager manager = getLocalActivityManager();
    manager.destroyActivity(stack.pop(), true);
    if (stack.size() > 0) {
        Intent lastIntent = manager.getActivity(stack.peek()).getIntent()
                .setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
        Window newWindow = manager.startActivity(stack.peek(), lastIntent);
        setContentView(newWindow.getDecorView());
    }
}
}

Note here:

push("1stStackActivity", new Intent(this, Home.class));

Home.class is my first activity to be loaded in my HOME TAB.

Here is a image which shows my flow and question also.

enter image description here

From Activity A when I click on a button (browse by see fig Activity A). I start new activity like this

Intent intent = new Intent();
            intent.setClass(getParent(), BookOverView.class);

            MyActivityGroup activityStack = (MyActivityGroup) getParent();
            activityStack.push("2ndStackActivity", intent);

This loads my Activity B on the current HOME TAB also also pushes the activity into the stack.

From Activity B when I click the any list item I'm starting a new activity in the same tab with the same code as above (3rdStackActivity). It start my Activity c; when I press back KEY it works fine (i.e From "Activity C" --> "ACTIVITY B" --> ACTIViTY A ).

QUESTION

While standing on activity C When I click the Home TAB (See in fig Activity C) it should come back to my 1st activity (i.e Activity A).

Here is my HOME TAB click event

getTabWidget().getChildAt(0).setOnClickListener(new OnClickListener() {

        @Override
        public void onClick(View v) {
            // TODO Auto-generated method stub

            if (getTabHost().getCurrentTab() == 0) {

                                    \\ Check If stack has at least more then one activity loaded.
                if (MyActivityGroup.stack.size() > 1) {

                                     //My code to clear the stack and load the 1st Activity goes here


                                     // I tried Here to clear my stack 
                                     // But not sccessfull



                }

            } else {

                getTabHost().setCurrentTab(0);

            }
        }
    });

I am having problems while trying to clear my Stack and start the first home class.

Here is my MainActivity.java which extends the TabActivity

public class MainActivity extends TabActivity {

Context context = MainActivity.this;

TabHost tabHost;
TabSpec spec;

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    tabHost = getTabHost();
    // Android tab
    tabHost.addTab(tabHost
            .newTabSpec("Home")
            .setIndicator("Home",
                    getResources().getDrawable(R.drawable.home))
            .setContent(
                    new Intent(this, MyActivityGroup.class)
                            .addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)));

    tabHost.addTab(tabHost
            .newTabSpec("Now Reading")
            .setIndicator("Now Reading",
                    getResources().getDrawable(R.drawable.now_reading))
            .setContent(
                    new Intent(this, NowReadingActivityGroup.class)
                            .addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)));

    tabHost.addTab(tabHost
            .newTabSpec("Favorites")
            .setIndicator("Favorites",
                    getResources().getDrawable(R.drawable.favorites))
            .setContent(
                    new Intent(this, FavoriteActivityGroup.class)
                            .addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)));

    tabHost.addTab(tabHost
            .newTabSpec("Profile")
            .setIndicator("Profile",
                    getResources().getDrawable(R.drawable.profile))
            .setContent(
                    new Intent(this, ProfileActivityGroup.class)
                            .addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)));

    tabHost.setCurrentTabByTag("Home");

    tabHost.setOnTabChangedListener(new OnTabChangeListener() {

        @Override
        public void onTabChanged(String tabId) {

            Toast.makeText(context, "Changed", Toast.LENGTH_SHORT).show();

        }
    });

}

@Override
protected void onStart() {
    // TODO Auto-generated method stub
    super.onStart();

    getTabWidget().getChildAt(0).setOnClickListener(new OnClickListener() {

        @Override
        public void onClick(View v) {
            // TODO Auto-generated method stub

            if (getTabHost().getCurrentTab() == 0) {

                if (MyActivityGroup.stack.size() > 1) {


                }

            } else {

                getTabHost().setCurrentTab(0);

            }
        }
    });

}



}

EDIT 2

I have done like this in my onTabClick event

        if (MyActivityGroup.stack.size() > 1) {

                    while (!MyActivityGroup.stack.isEmpty()) {
                        MyActivityGroup.stack.pop();
                    }

                    Intent homeIntent = new Intent();
                    homeIntent.setClass(MainActivity.this, Home.class);
                    MyActivityGroup activityStack = (MyActivityGroup) getCurrentActivity();

                    activityStack.push("HomeActivity", homeIntent);
                }

            } else {

                getTabHost().setCurrentTab(0);

            }

This loads my 1st activity and also clears my activity stack. But the problem is that now whenever change my tab to any other tab and come back to the home tab and press back button it crashes. Here is the log cat.

05-31 14:15:42.769: E/AndroidRuntime(550): FATAL EXCEPTION: main
05-31 14:15:42.769: E/AndroidRuntime(550): java.lang.NullPointerException
05-31 14:15:42.769: E/AndroidRuntime(550):  at my.islamic.books.lib.app.MyActivityGroup.pop(MyActivityGroup.java:120)
05-31 14:15:42.769: E/AndroidRuntime(550):  at my.islamic.books.lib.app.MyActivityGroup.finishFromChild(MyActivityGroup.java:30)
05-31 14:15:42.769: E/AndroidRuntime(550):  at android.app.Activity.finish(Activity.java:3259)
05-31 14:15:42.769: E/AndroidRuntime(550):  at android.app.Activity.onBackPressed(Activity.java:1920)
05-31 14:15:42.769: E/AndroidRuntime(550):  at android.app.Activity.onKeyUp(Activity.java:1898)
05-31 14:15:42.769: E/AndroidRuntime(550):  at android.view.KeyEvent.dispatch(KeyEvent.java:1280)
05-31 14:15:42.769: E/AndroidRuntime(550):  at android.app.Activity.dispatchKeyEvent(Activity.java:2078)
05-31 14:15:42.769: E/AndroidRuntime(550):  at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchKeyEvent(PhoneWindow.java:1663)
05-31 14:15:42.769: E/AndroidRuntime(550):  at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:789)
05-31 14:15:42.769: E/AndroidRuntime(550):  at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:789)
05-31 14:15:42.769: E/AndroidRuntime(550):  at com.android.internal.policy.impl.PhoneWindow$DecorView.superDispatchKeyEvent(PhoneWindow.java:1687)
05-31 14:15:42.769: E/AndroidRuntime(550):  at com.android.internal.policy.impl.PhoneWindow.superDispatchKeyEvent(PhoneWindow.java:1120)
05-31 14:15:42.769: E/AndroidRuntime(550):  at android.app.Activity.dispatchKeyEvent(Activity.java:2073)
05-31 14:15:42.769: E/AndroidRuntime(550):  at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchKeyEvent(PhoneWindow.java:1663)
05-31 14:15:42.769: E/AndroidRuntime(550):  at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:789)
05-31 14:15:42.769: E/AndroidRuntime(550):  at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:789)
05-31 14:15:42.769: E/AndroidRuntime(550):  at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:789)
05-31 14:15:42.769: E/AndroidRuntime(550):  at android.widget.TabHost.dispatchKeyEvent(TabHost.java:278)
05-31 14:15:42.769: E/AndroidRuntime(550):  at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:789)
05-31 14:15:42.769: E/AndroidRuntime(550):  at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:789)
05-31 14:15:42.769: E/AndroidRuntime(550):  at com.android.internal.policy.impl.PhoneWindow$DecorView.superDispatchKeyEvent(PhoneWindow.java:1687)
05-31 14:15:42.769: E/AndroidRuntime(550):  at com.android.internal.policy.impl.PhoneWindow.superDispatchKeyEvent(PhoneWindow.java:1120)
05-31 14:15:42.769: E/AndroidRuntime(550):  at android.app.Activity.dispatchKeyEvent(Activity.java:2073)
05-31 14:15:42.769: E/AndroidRuntime(550):  at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchKeyEvent(PhoneWindow.java:1663)
05-31 14:15:42.769: E/AndroidRuntime(550):  at android.view.ViewRoot.deliverKeyEventToViewHierarchy(ViewRoot.java:2560)
05-31 14:15:42.769: E/AndroidRuntime(550):  at android.view.ViewRoot.handleFinishedEvent(ViewRoot.java:2535)
05-31 14:15:42.769: E/AndroidRuntime(550):  at android.view.ViewRoot.handleMessage(ViewRoot.java:1867)
05-31 14:15:42.769: E/AndroidRuntime(550):  at android.os.Handler.dispatchMessage(Handler.java:99)
05-31 14:15:42.769: E/AndroidRuntime(550):  at android.os.Looper.loop(Looper.java:123)
05-31 14:15:42.769: E/AndroidRuntime(550):  at android.app.ActivityThread.main(ActivityThread.java:3683)
05-31 14:15:42.769: E/AndroidRuntime(550):  at java.lang.reflect.Method.invokeNative(Native Method)
05-31 14:15:42.769: E/AndroidRuntime(550):  at java.lang.reflect.Method.invoke(Method.java:507)
05-31 14:15:42.769: E/AndroidRuntime(550):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839)
05-31 14:15:42.769: E/AndroidRuntime(550):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597)
05-31 14:15:42.769: E/AndroidRuntime(550):  at dalvik.system.NativeStart.main(Native Method)

Solution

  • I have done like this in my HomeTab click event

    getTabWidget().getChildAt(0).setOnClickListener(new OnClickListener() {
    
            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub
    
                if (getTabHost().getCurrentTab() == 0) {
    
                    Log.i("not Null", "Not null");
    
                    if (MyActivityGroup.stack.size() > 1) {
    
                        while (!MyActivityGroup.stack.isEmpty()) {
                            MyActivityGroup.stack.pop();
                        }
    
                        Intent homeIntent = new Intent();
                        homeIntent.setClass(MainActivity.this, Home.class);
                        MyActivityGroup activityStack = (MyActivityGroup) getCurrentActivity();
    
                        activityStack.push("HomeActivity", homeIntent);
                    }
    
                } else {
    
                    getTabHost().setCurrentTab(0);
    
                }
    
            }
    
        });
    

    Also on tabchange listner I have to clear my activityGroup stack also. so i done I like this

    tabHost.setOnTabChangedListener(new OnTabChangeListener() {
    
            @Override
            public void onTabChanged(String tabId) {
    
                Toast.makeText(context, "Changed", Toast.LENGTH_SHORT).show();
                while (!MyActivityGroup.stack.isEmpty()) {
    
                    if (MyActivityGroup.stack.size()==1) {
                        break;
                    }
                    MyActivityGroup.stack.pop();
                }
    
    
            }
        });
    

    Huh finally I found my head ach pill :)