1

I'm working on a project where I need to put a few activities under a Tab in Tabhost. I'm using custom tabgroupactivity example which i find somewhere over the internet, but now I have a little issue with finishing my activities. First here is the custom class code :

import java.util.ArrayList;

import android.app.Activity;
import android.app.ActivityGroup;
import android.app.LocalActivityManager;

import android.content.Intent;
import android.os.Bundle;
import android.view.KeyEvent;
import android.view.Window;

/*
 * The purpose of this Activity is to manage the activities in a tab.
 * Note: Child Activities can handle Key Presses before they are seen here.
 * @author Eric Harlow
 */
public class TabGroupActivity extends ActivityGroup {

    private ArrayList<String> mIdList;

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

    /*
     * This is called when a child activity of this one calls its finish method. 
     * This implementation calls {@link LocalActivityManager#destroyActivity} on the child activity
     * and starts the previous activity.
     * If the last child activity just called finish(),this activity (the parent),
     * calls finish to finish the entire group.
     */
  @Override
  public void finishFromChild(Activity child) {
      LocalActivityManager manager = getLocalActivityManager();
      int index = mIdList.size()-1;

      if(index < 1) {
              finish();
              return;
      } 
        manager.destroyActivity(mIdList.get(index), true);
        mIdList.remove(index);
        index--;
        String lastId = mIdList.get(index);
        Intent lastIntent = manager.getActivity(lastId).getIntent();
        Window newWindow = manager.startActivity(lastId, lastIntent);
        setContentView(newWindow.getDecorView());

  }

  /*
   * Starts an Activity as a child Activity to this.
   * @param Id Unique identifier of the activity to be started.
   * @param intent The Intent describing the activity to be started.
   * @throws android.content.ActivityNotFoundException.
   */
  public void startChildActivity(String Id, Intent intent) {     
      Window window = getLocalActivityManager().startActivity(Id,intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP));
      if (window != null) {
          mIdList.add(Id);
          setContentView(window.getDecorView()); 
      }    
  }

  /*
   * The primary purpose is to prevent systems before android.os.Build.VERSION_CODES.ECLAIR
   * from calling their default KeyEvent.KEYCODE_BACK during onKeyDown.
   */
  @Override
  public boolean onKeyDown(int keyCode, KeyEvent event) {
      if (keyCode == KeyEvent.KEYCODE_BACK) {
          //preventing default implementation previous to android.os.Build.VERSION_CODES.ECLAIR
          return true;
      }
      return super.onKeyDown(keyCode, event);
  }

  /*
   * Overrides the default implementation for KeyEvent.KEYCODE_BACK 
   * so that all systems call onBackPressed().
   */
  @Override
  public boolean onKeyUp(int keyCode, KeyEvent event) {
      if (keyCode == KeyEvent.KEYCODE_BACK) {
          onBackPressed();
          return true;
      }
      return super.onKeyUp(keyCode, event);
  }

  /*
   * If a Child Activity handles KeyEvent.KEYCODE_BACK.
   * Simply override and add this method.
   */
  @Override
  public void  onBackPressed () {
      int length = mIdList.size();
      if ( length >=1) {
          Activity current = getLocalActivityManager().getActivity(mIdList.get(length-1));
          current.finish();
      }
  }
}

So basically my problem is when I have 5 tabs in a tabhost. In first tab I have 3 child activities, let's call them Activity A, B and C. Here is a little information about connection between activities :

A --- can start -->B and C
B --- can start -->A and C
C --- can start -->A and B

and I'm starting them like this :

Intent previewMessage = new Intent(A.this, C.class);
previewMessage.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
TabGroupActivity parentActivity = (TabGroupActivity)getParent();
parentActivity.startChildActivity("ExpectSoon", previewMessage);

and here is the problem : When I start a few times A,B,C like A-->B-->C-->B-->C-->A-->C and etc. there is no problem...but when I press the back button I'm getting a NullPointerException on this line from my TagGroupActivity :

Intent lastIntent = manager.getActivity(lastId).getIntent();

and here is the LogCat output :

10-05 10:51:30.995: ERROR/AndroidRuntime(20377): java.lang.NullPointerException
10-05 10:51:30.995: ERROR/AndroidRuntime(20377):     at com.stampii.stampii.TabGroupActivity.finishFromChild(TabGroupActivity.java:49)
10-05 10:51:30.995: ERROR/AndroidRuntime(20377):     at android.app.Activity.finish(Activity.java:3420)
10-05 10:51:30.995: ERROR/AndroidRuntime(20377):     at com.stampii.stampii.TabGroupActivity.onBackPressed(TabGroupActivity.java:104)
10-05 10:51:30.995: ERROR/AndroidRuntime(20377):     at com.stampii.stampii.TabGroupActivity.onKeyUp(TabGroupActivity.java:89)
10-05 10:51:30.995: ERROR/AndroidRuntime(20377):     at android.view.KeyEvent.dispatch(KeyEvent.java:1527)
10-05 10:51:30.995: ERROR/AndroidRuntime(20377):     at android.app.Activity.dispatchKeyEvent(Activity.java:2210)
10-05 10:51:30.995: ERROR/AndroidRuntime(20377):     at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchKeyEvent(PhoneWindow.java:1779)
10-05 10:51:30.995: ERROR/AndroidRuntime(20377):     at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:811)
10-05 10:51:30.995: ERROR/AndroidRuntime(20377):     at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:811)
10-05 10:51:30.995: ERROR/AndroidRuntime(20377):     at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:811)
10-05 10:51:30.995: ERROR/AndroidRuntime(20377):     at android.widget.TabHost.dispatchKeyEvent(TabHost.java:278)
10-05 10:51:30.995: ERROR/AndroidRuntime(20377):     at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:811)
10-05 10:51:30.995: ERROR/AndroidRuntime(20377):     at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:811)
10-05 10:51:30.995: ERROR/AndroidRuntime(20377):     at com.android.internal.policy.impl.PhoneWindow$DecorView.superDispatchKeyEvent(PhoneWindow.java:1812)
10-05 10:51:30.995: ERROR/AndroidRuntime(20377):     at com.android.internal.policy.impl.PhoneWindow.superDispatchKeyEvent(PhoneWindow.java:1160)
10-05 10:51:30.995: ERROR/AndroidRuntime(20377):     at android.app.Activity.dispatchKeyEvent(Activity.java:2205)
10-05 10:51:30.995: ERROR/AndroidRuntime(20377):     at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchKeyEvent(PhoneWindow.java:1779)
10-05 10:51:30.995: ERROR/AndroidRuntime(20377):     at android.view.ViewRoot.deliverKeyEventToViewHierarchy(ViewRoot.java:2758)
10-05 10:51:30.995: ERROR/AndroidRuntime(20377):     at android.view.ViewRoot.handleFinishedEvent(ViewRoot.java:2730)
10-05 10:51:30.995: ERROR/AndroidRuntime(20377):     at android.view.ViewRoot.handleMessage(ViewRoot.java:1999)
10-05 10:51:30.995: ERROR/AndroidRuntime(20377):     at android.os.Handler.dispatchMessage(Handler.java:99)
10-05 10:51:30.995: ERROR/AndroidRuntime(20377):     at android.os.Looper.loop(Looper.java:150)
10-05 10:51:30.995: ERROR/AndroidRuntime(20377):     at android.app.ActivityThread.main(ActivityThread.java:4293)
10-05 10:51:30.995: ERROR/AndroidRuntime(20377):     at java.lang.reflect.Method.invokeNative(Native Method)
10-05 10:51:30.995: ERROR/AndroidRuntime(20377):     at java.lang.reflect.Method.invoke(Method.java:507)
10-05 10:51:30.995: ERROR/AndroidRuntime(20377):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:849)
10-05 10:51:30.995: ERROR/AndroidRuntime(20377):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:607)
10-05 10:51:30.995: ERROR/AndroidRuntime(20377):     at dalvik.system.NativeStart.main(Native Method)

Any ideas how to solve that problem?

Android-Droid
  • 14,365
  • 41
  • 114
  • 185
  • check manager.getActivity(lastId).getIntent() is null or not?????? – Samir Mangroliya Oct 05 '11 at 08:03
  • yes it is, that's why it's throwin me a NullpointerException on that line, but I don't know how to fix that, that's why I'm asking this question here – Android-Droid Oct 05 '11 at 08:15
  • Nullpointer exception never thrown because you access null object or null variable and its value is needed in your code so....I am study about this error but when this error occure?? and when you call this activity may be your intent are wrong to startactivity... – Samir Mangroliya Oct 05 '11 at 08:23
  • I'm getting the error when I start pressing back button...not the firts time.Actually I want to clear the history of these activities and when I press back button on Activity C or B or A I want to finish the parent activity.But now when I press back button it's returning to the previous activity (A->B) and when I press it again it's crashing.I've tried to modify `finishFromChild` method,but it didn't work. – Android-Droid Oct 05 '11 at 08:29
  • OMG!!! onbackpressed() is method that called when you press back button ....so write this method and try to call intent,,,,,,,,,,,and also finish current activity............. – Samir Mangroliya Oct 05 '11 at 08:35

3 Answers3

4

I got the same problem.

But after debugging, I came to know that the line

parentActivity.startChildActivity(STRING_ID, intent);

is responsible for NullPointerException.

Thats because, you might be using same STRING_ID for starting multiple child activities. So when onBackPressed, the intent(s) with STRING_ID gets removed from the list.

The way you should call startChildActivity is

 parentActivity.startChildActivity(UNIQUE_STRING_ID, intent);

UNIQUE_STRING_ID must be different

Girish Nair
  • 5,148
  • 5
  • 40
  • 61
Kartik Domadiya
  • 29,868
  • 19
  • 93
  • 104
  • thank you .i am using STRING_ID as system current time in millisecound.tabgroup.startChildActivity(""+System.currentTimeMillis(), i); – Hemantvc Apr 25 '13 at 11:46
0

I think you have to start it like this

Intent intent = new Intent(A.this,B.class);
            TabGroupActivity parent=(TabGroupActivity)getParent();

            parent.startChildActivity("msg",intent);
Newts
  • 1,354
  • 14
  • 23
0
    Intent check= new Intent(getParent(),abcintent.class);
    TabGroupActivity parentActivity = (TabGroupActivity)getParent();
parentActivity.startChildActivity("abcActiivty", check);
Megha
  • 1,581
  • 2
  • 18
  • 33