Android 2.1 NullPointerException with TabWidgets

I have a problem that I could not figure out, and this only happens on devices running <2.1. It works fine on Android 2.2. I have a synchronous task that displays a download dialog when it loads all tabs. Here is the code for TabActivity:

public class OppTabsView extends TabActivity { Dialog dialog; String errorText; boolean save; final int OPP_SAVE = 0; public static boolean edited; public void onCreate(Bundle icicle) { try { super.onCreate(icicle); new DoInBackground().execute(); } catch (Exception e) { Toast.makeText(this, "Error occured. Please try again later.", Toast.LENGTH_SHORT).show(); } } @Override protected void onResume() { super.onResume(); } @Override protected void onStop() { super.onStop(); } @Override protected void onPause() { super.onPause(); } public boolean onCreateOptionsMenu(Menu menu) { menu.add(0, OPP_SAVE, 0, "Test"); return true; } public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { case OPP_SAVE: save = true; new DoInBackground().execute(); return true; } return false; } public void LoadOpp() { handler.sendEmptyMessage(0); } public void SaveOpp() { DoStuff(); } public void LoadLayout() { setContentView(R.layout.view_opptabs); /* TabHost will have Tabs */ TabHost tabHost = (TabHost) findViewById(android.R.id.tabhost); /* * TabSpec used to create a new tab. By using TabSpec only we can able * to setContent to the tab. By using TabSpec setIndicator() we can set * name to tab. */ /* tid1 is firstTabSpec Id. Its used to access outside. */ TabSpec firstTabSpec = tabHost.newTabSpec("tid1"); TabSpec secondTabSpec = tabHost.newTabSpec("tid1"); TabSpec thirdTabSpec = tabHost.newTabSpec("tid1"); /* TabSpec setIndicator() is used to set name for the tab. */ /* TabSpec setContent() is used to set content for a particular tab. */ firstTabSpec.setIndicator("General", getResources().getDrawable(R.drawable.tab_moneybag)) .setContent(new Intent(this, OppTabGeneral.class)); secondTabSpec.setIndicator("Details", getResources().getDrawable(R.drawable.tab_papers)).setContent( new Intent(this, OppTabDetails.class)); thirdTabSpec.setIndicator("Contact", getResources().getDrawable(R.drawable.tab_contact)).setContent( new Intent(this, OppTabContact.class)); /* Add tabSpec to the TabHost to display. */ tabHost.addTab(firstTabSpec); tabHost.addTab(secondTabSpec); tabHost.addTab(thirdTabSpec); } private void do_update() { if (save) { SaveOpp(); } else { LoadOpp(); } } Handler handler = new Handler() { public void handleMessage(Message msg) { LoadLayout(); } }; private class DoInBackground extends AsyncTask<Void, Void, Void> implements DialogInterface.OnCancelListener { protected void onPreExecute() { String verb = "Connecting"; if (save) { verb = "Saving"; } dialog = ProgressDialog.show(OppTabsView.this, "", verb + ". Please Wait...", true, true, this); } protected Void doInBackground(Void... v) { do_update(); return null; } protected void onPostExecute(Void v) { dialog.dismiss(); } public void onCancel(DialogInterface dialog) { cancel(true); dialog.dismiss(); finish(); } } } 

Here is the stack trace from the error:

 java.lang.NullPointerException at android.widget.TabWidget.dispatchDraw(TabWidget.java:206) at android.view.ViewGroup.drawChild(ViewGroup.java:1529) at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1258) at android.view.ViewGroup.drawChild(ViewGroup.java:1529) at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1258) at android.view.ViewGroup.drawChild(ViewGroup.java:1529) at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1258) at android.view.View.draw(View.java:6538) at android.widget.FrameLayout.draw(FrameLayout.java:352) at android.view.ViewGroup.drawChild(ViewGroup.java:1531) at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1258) at android.view.ViewGroup.drawChild(ViewGroup.java:1529) at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1258) at android.view.View.draw(View.java:6538) at android.widget.FrameLayout.draw(FrameLayout.java:352) at com.android.internal.policy.impl.PhoneWindow$DecorView.draw(PhoneWindow.java:1830) at android.view.ViewRoot.draw(ViewRoot.java:1349) at android.view.ViewRoot.performTraversals(ViewRoot.java:1114) at android.view.ViewRoot.handleMessage(ViewRoot.java:1633) at android.os.Handler.dispatchMessage(Handler.java:99) at android.os.Looper.loop(Looper.java:123) at android.app.ActivityThread.main(ActivityThread.java:4363) at java.lang.reflect.Method.invokeNative(Native Method) at java.lang.reflect.Method.invoke(Method.java:521) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:860) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:618) at dalvik.system.NativeStart.main(Native Method) 

I tried to get through it, but the error seems to be coming from outside, not on a specific line. Any help is appreciated.

+4
source share
4 answers
 TabSpec firstTabSpec = tabHost.newTabSpec("tid1"); TabSpec secondTabSpec = tabHost.newTabSpec("tid1"); TabSpec thirdTabSpec = tabHost.newTabSpec("tid1"); 

Can I use the same tag for multiple TabSpec? I would try installing them correctly and see if it fixes it.

EDIT: OK, so my suggestion didn't fix it, but it makes sense to have unique tags.

Try this to see if this helps. Add a parameter to set the currently selected tab at the end of your LoadLayout () method, as shown below (see last line) ...

 /* Add tabSpec to the TabHost to display. */ tabHost.addTab(firstTabSpec); tabHost.addTab(secondTabSpec); tabHost.addTab(thirdTabSpec); tabHost.setCurrentTab(0); // <== Add this 

EDIT2: I found the source of TabWidget.java and line 206 (where the NullPointerException is thrown) ...

mBottomLeftStrip.setState(selectedChild.getDrawableState());

... There are three possible reasons for the exception that I see.

  • mBottonLeftStrip is null (unlikely)
  • selectedCHild is null (TabWidget should by default be a child of 0, and using tabHost.setCurrentTab () would ensure compliance anyway)
  • The result of selectedChild.getDrawableState() is null

The latter seems like a likely cause, but I'm not sure what might make it return null.

Try Google for “TabWidget.java source” - the second result on the grepcode.com page with line numbers, and you can see what it is trying to do at the exception point.

+1
source

There was the same problem with tabs populated from AsyncTask on 1.6 and 2.1. It seems that earlier versions do not like TabHost without any tabs. To solve this problem, I do not use TabActivity and create TabHost with all my hierarchy manually in the onPostExecute AsyncTask function.

+1
source

A simple solution is to set the tabWidget visibility in the expired in your layout

 <TabWidget android:id="@android:id/tabs" android:orientation="horizontal" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_weight="0" android:visibility="gone" /> 

Then, once you have defined your tabs, you can make it visible again:

 // Add tab content (here a fragment class) tabHost.addTab( tabHost.newTabSpec("tag1").setIndicator("Title"), contentFragment.class, null); // Set tabWidget visible again tabWidget.setVisibility(View.VISIBLE); 
+1
source

Inspired by one of the related TabHost answers:

 public class FixedTabHost extends FragmentTabHost { public FixedTabHost(Context context, AttributeSet attrs) { super(context, attrs); } @Override protected void dispatchDraw(Canvas canvas) { try { super.dispatchDraw(canvas); } catch (Exception ignored) {} } } 

Worked for me.

0
source

Source: https://habr.com/ru/post/1340098/


All Articles