【问题标题】:Problem running android HelloTabWidget example - NullPointerException on addTab()运行 android HelloTabWidget 示例时出现问题 - addTab() 上的 NullPointerException
【发布时间】:2010-02-21 20:35:02
【问题描述】:

我已经尝试了Tab Layout example,并且我还修复了示例中的几个拼写错误(并将所有活动添加到清单中)。但是,当我在模拟器上运行它时,我在第一行得到一个 NullPointerException,上面写着

tabHost.addTab(spec);

所以我的问题当然是。导致此异常的示例有什么问题?我正在使用 Eclipse Galileo 并将目标包设置为 Android 1.5。到目前为止,我对 android 开发网站上的其他示例没有其他问题。

package com.example.hellotabwidget;

import android.app.TabActivity;
import android.content.Intent;
import android.content.res.Resources;
import android.os.Bundle;
import android.widget.TabHost;

public class HelloTabWidget extends TabActivity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) throws RuntimeException {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    Resources res = getResources(); // Resource object to get Drawables
    TabHost tabHost = getTabHost();  // The activity TabHost
    TabHost.TabSpec spec;  // Reusable TabSpec for each tab
    Intent intent;  // Reusable Intent for each tab

    // Create an Intent to launch an Activity for the tab (to be reused)
    //final Context context = getApplicationContext();
    intent = new Intent().setClass(this, ArtistsActivity.class);

    // Initialize a TabSpec for each tab and add it to the TabHost
    spec = tabHost.newTabSpec("artists").setIndicator("Artists",
            res.getDrawable(R.drawable.ic_tab_artists))
            .setContent(intent);
    tabHost.addTab(spec); //******** NullPointerException after running this line

    // Do the same for the other tabs
    intent = new Intent().setClass(this, AlbumsActivity.class);
    spec = tabHost.newTabSpec("albums").setIndicator("Albums",
            res.getDrawable(R.drawable.ic_tab_artists))
            .setContent(intent);
    tabHost.addTab(spec);

    intent = new Intent().setClass(this, SongsActivity.class);
    spec = tabHost.newTabSpec("songs").setIndicator("Songs",
            res.getDrawable(R.drawable.ic_tab_artists))
            .setContent(intent);
    tabHost.addTab(spec);

    tabHost.setCurrentTabByTag("artists");
}
}

main.xml:

<?xml version="1.0" encoding="utf-8"?>
<TabHost xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@android:id/tabhost"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<LinearLayout
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:padding="5dp">
    <TabWidget
        android:id="@android:id/tabs"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content" />
    <FrameLayout
        android:id="@android:id/tabcontent"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:padding="5dp" />
</LinearLayout>
</TabHost>

【问题讨论】:

  • 没有提到tabHost.setTab(spec); 的行,主要是因为该示例中没有使用setTab() 方法。事实上,我一般在 Android SDK 中都找不到。
  • 糟糕,这是这篇文章的错字,不是我的代码。我更新了我的问题并发布了更多代码。
  • 我后来重新审视了这个问题,发现它自己解决了。这一定是 SDK 中的一个错误,因为我在几个月后打开了该项目,它运行时没有任何问题。
  • 我遇到了同样的问题 - 检查您的模拟器配置以及它是否附加到调试器。

标签: android android-tabhost


【解决方案1】:

在你的清单中试试这个:

<activity android:name=".AlbumsActivity"  android:label="@string/app_name"></activity> 
    <activity android:name=".ArtistsActivity"  android:label="@string/app_name"></activity> 
    <activity android:name=".SongsActivity"  android:label="@string/app_name"></activity> 

【讨论】:

    【解决方案2】:

    只想对这里发布的所有内容表示感谢。解决了我的问题(和这里的其他人一样)。让这个工作非常令人沮丧。他们确实应该更好地简化示例。

    尝试总结所需的更改。

    1. 添加 Ngetha 所说的 3 条活动线。
    2. 将所有 3 个活动类移动到单独的文件中。 我最终用于我的 SongsActivity.java 文件的示例(带有 Eclipse 错误建议)

      package com.example.HelloTabWidget;
      import android.app.Activity;
      import android.os.Bundle;
      import android.widget.TextView;
      public class SongsActivity extends Activity {
      public void onCreate(Bundle savedInstanceState) {
          super.onCreate(savedInstanceState);
          TextView textview = new TextView(this);
          textview.setText("This is the Songs tab");
          setContentView(textview);
      }
      }
      
    3. 我必须创建一个 res\drawable 目录并将所有图标放在那里,另外我为图标制作了 3 个 xml 文件,例如“ic_tab_songs.xml”

    【讨论】:

      【解决方案3】:

      我遇到了同样的问题。 我昨天开始了教程,这是唯一一个有问题的。

      空指针在第一次被调用时被抛出

      tabHost.addTab(spec);
      

      原来修复是在清单 XML 中

      <activity android:name=".MyTabActivity"
            android:label="@string/app_name"
            android:theme="@android:style/Theme.NoTitleBar">
          <intent-filter>
             <action android:name="android.intent.action.MAIN" />
              <category android:name="android.intent.category.LAUNCHER" />
          </intent-filter>
      </activity>
      
      
      <activity android:name=".DateActivity"  android:label="@string/app_name"></activity> 
      <activity android:name=".RandomNumActivity"  android:label="@string/app_name"></activity> 
      

      最后两个活动之前不存在,它会失败。我添加了它们(感谢上面 Ngetha 的建议!)并且效果很好。 对于教程的示例本身,您需要添加三个艺术家、专辑和歌曲活动

      我想我知道每个活动都需要在清单中列出,这是有道理的,我只是在按照 T 的示例时没有想到它。

      这是真的吗?所有活动都必须在清单中?

      【讨论】:

        【解决方案4】:

        您好,请执行以下步骤,我相信您的问题会解决:-

        创建一个类HelloTabWidget.java

        package com.pericent;             //this is package name
        import android.app.TabActivity;
        import android.content.Intent;
        import android.content.res.Resources;
        import android.os.Bundle;
        import android.util.Log;
        import android.widget.TabHost;
        
        public class HelloTabWidget extends TabActivity  {
        
        private String TAG="HelloTabWidget";
        
        public void onCreate(Bundle savedInstanceState) {
          super.onCreate(savedInstanceState);
          setContentView(R.layout.main);
        
          Resources res = getResources(); // Resource object to get Drawables
          TabHost tabHost = getTabHost();  // The activity TabHost
          TabHost.TabSpec spec;  // Resusable TabSpec for each tab
          Intent intent;  // Reusable Intent for each tab
        
          // Create an Intent to launch an Activity for the tab (to be reused)
          intent = new Intent().setClass(this,ArtistsActivity.class);
          Log.v(TAG,"---artist activity is called---");
        
          // Initialize a TabSpec for each tab and add it to the TabHost
          spec = tabHost.newTabSpec("artists").setIndicator("Artists",res.getDrawable(R.drawable.ic_tab_artists)).setContent(intent);
          tabHost.addTab(spec);
        
        
          // Do the same for the other tabs
          intent = new Intent().setClass(this,AlbumsActivity.class);
          Log.v(TAG,"---album activity is called---");
          spec = tabHost.newTabSpec("albums").setIndicator("Albums",res.getDrawable(R.drawable.ic_tab_albums)).setContent(intent);
          tabHost.addTab(spec);
        
          intent = new Intent().setClass(this, SongsActivity.class);
          Log.v(TAG,"---song activity is called---");
          spec = tabHost.newTabSpec("songs").setIndicator("Songs",res.getDrawable(R.drawable.ic_tab_songs)).setContent(intent);
          tabHost.addTab(spec);
        
          }
        
        }
        

        创建您的第二个活动:ArtistActivity.java

        package com.pericent;
        
        import android.app.Activity;
        import android.os.Bundle;
        import android.util.Log;
        import android.widget.TextView;
        
        public class ArtistsActivity extends Activity {
         private String TAG="ArtistsActivity";
            /** Called when the activity is first created. */
            @Override
              public void onCreate(Bundle savedInstanceState) {
                super.onCreate(savedInstanceState);
                TextView textview=new TextView(this);
                textview.setText("This is Artist Activity");
                setContentView(textview);
                Log.v(TAG,"---in artist activity---");
            }
        }
        

        创建您的第三个活动:AlbumsActivity.java

        package com.pericent;
        
        import android.R;
        import android.app.Activity;
        import android.os.Bundle;
        import android.util.Log;
        import android.widget.TextView;
        
        public class AlbumsActivity extends Activity{
            private String TAG="AlbumsActivity";
            @Override
            public void onCreate(Bundle savedInstance)
            {
                super.onCreate(savedInstance);
                TextView textview_album=new TextView(this);
                textview_album.setText("This is album activity");
                setContentView(textview_album);
                Log.v(TAG,"---in album activity---");
            }
        
        }
        

        创建您的第四个活动:SongsActivity.java

        package com.pericent;
        
        import android.R;
        import android.app.Activity;
        import android.os.Bundle;
        import android.util.Log;
        import android.widget.TextView;
        
        public class SongsActivity extends Activity{
            private String TAG="SongsActivity";
            @Override
            public void onCreate(Bundle savedInstance)
            {
                super.onCreate(savedInstance);
                TextView textview_song=new TextView(this);
                textview_song.setText("This is song activity");
                setContentView(textview_song);
                Log.v(TAG,"---in songs activity---");
            }
        
        }
        

        在 res/drawable 中创建一个文件夹 在此文件夹中创建 3 个 XML 文件: 这些文件的代码如下:-

        <?xml version="1.0" encoding="utf-8"?>
        <selector xmlns:android="http://schemas.android.com/apk/res/android">
            <!-- When selected, use grey -->
            <item android:drawable="@drawable/ic_tab_artists_grey"
                  android:state_selected="true" />
            <!-- When not selected, use white-->
            <item android:drawable="@drawable/ic_tab_artists_white" />
        </selector>
        

        在上面的 XML 代码中,我们使用了两张图片,以下是必须保存在同一个文件夹(res/drawable)中的图片。

        这是main.xml

        <?xml version="1.0" encoding="utf-8"?>
        <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:id="@+id/upper">
        <TabHost 
            android:id="@android:id/tabhost"
            android:layout_width="fill_parent"
            android:layout_height="fill_parent">
            <LinearLayout android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" android:padding="5dp">
            <HorizontalScrollView android:id="@+id/ScrollView01" android:layout_width="fill_parent" android:layout_height="wrap_content" android:fillViewport="true" android:scrollbars="none">
                   <TabWidget
                    android:id="@android:id/tabs"
                    android:layout_width="fill_parent"
                    android:layout_height="wrap_content" />
             </HorizontalScrollView>
                <FrameLayout
                    android:id="@android:id/tabcontent"
                    android:layout_width="fill_parent"
                    android:layout_height="fill_parent"
                    android:padding="5dp" />
            </LinearLayout>
        </TabHost>
        </LinearLayout>
        

        这是 AdroidManifest

        <?xml version="1.0" encoding="utf-8"?>
        <manifest xmlns:android="http://schemas.android.com/apk/res/android"
              package="com.pericent"
              android:versionCode="1"
              android:versionName="1.0">
            <application android:icon="@drawable/icon" android:label="@string/app_name">
               <activity android:name=".HelloTabWidget" android:label="@string/app_name" android:theme="@android:style/Theme.NoTitleBar" >
                  <intent-filter>
                        <action android:name="android.intent.action.MAIN" />
                         <category android:name="android.intent.category.LAUNCHER" />
                  </intent-filter>
               </activity>
               <activity android:name=".AlbumsActivity" android:label="@string/app_name"></activity>
               <activity android:name=".ArtistsActivity" android:label="@string/app_name"></activity>   
               <activity android:name=".SongsActivity" android:label="@string/app_name" ></activity>
            </application>
        </manifest> 
        

        我认为所有这些信息都会有所帮助,如果您有任何问题,请随时问我任何问题。我总是很乐意帮助任何人。

        【讨论】:

          【解决方案5】:

          您应该发布更多代码,以便我们做出更好的假设。尤其要确保在某处实例化 tabHost。

          【讨论】:

          • 通过查看代码我看不出有什么问题。你能发布异常的跟踪吗?
          • 没有关于异常的堆栈跟踪,也没有详细的消息。单击 stackState 字段会显示:“JDI 线程评估”遇到问题。异常处理异步线程队列。然后Details>>显示:Exception processing async thread queue Exception processing async thread queue org.eclipse.jdt.internal.debug.core.model.JDIObjectValue cannot be cast to org.eclipse.jdt.debug.core.IJavaArray
          【解决方案6】:

          您是否将您的活动放在 AndroidManifest.xml 中?您必须告诉应用程序您要显示的活动,否则您将得到的只是一个错误。

          例如,您可以将以下 xml 代码放入 元素中:

              <activity android:name=".ArtistsActivity"
                        android:label="@string/app_name">
                  <intent-filter>
                      <action android:name="android.intent.action.MAIN" />
                  </intent-filter>
              </activity>
          

          希望这会有所帮助。

          -Surya Wijaya Madjid

          【讨论】:

          • 谢谢,但我没有这个。太奇怪了,因为我已经成功运行了所有其他示例。
          【解决方案7】:

          这对我有用:

          我将此行更改为使用“艺术家” tabHost.setCurrentTabByTag("艺术家");

          然后加了一个“.”在TabAndroid(主要活动名称)前面添加了Ngetha建议的三个活动。

          </application>
          

          【讨论】:

            【解决方案8】:

            我刚开始为 Android 编程,我也遇到了这个问题。我不得不说我对此感到非常沮丧。做 Ngetha 的建议帮助了我,但我也不得不稍微编辑我的代码。我注意到的是,显然 Android 不喜欢子类活动。完全没有。我以为我可以通过封装所有内容来使我的代码更简洁,但这显然不行。我不得不将我的课程移动到单独的文件中。我希望这可以帮助其他遇到同样封装问题的新程序员。

            【讨论】:

            • 我正在使用 Eclipse。它迫使我将每个类放在一个单独的文件中。
            【解决方案9】:

            我遇到了同样的接线错误。

            试试这个:

            如果您使用 eclipse 删除错误,更改一些代码(以便应用程序重新编译)然后它应该可以正常工作。

            【讨论】:

              【解决方案10】:

              更好的是,如果您遇到此类错误,请尝试 Project > Clean 以重新生成自动生成的文件。

              【讨论】:

                【解决方案11】:

                已解决 从已启动的 Intent 返回时,我在 .addTab(spec) 之后收到了 nullPointerException。我在最初进入此活动时没有收到错误。

                我通过添加解决了它:

                TabHost tabHost = (TabHost) getTabHost(); tabHost.setCurrentTab(0); // 这停止了 nullPointerException ...... …… tabHost.addTab(spec);

                【讨论】:

                  【解决方案12】:

                  我也遇到了标签小部件教程的问题。

                  我只能解决阅读这篇 SO 帖子的问题,谢谢大家的回答。

                  回到教程.... android 开发团队可以改进他们的文档。

                  他们确实告诉我们将 XML 活动添加到清单中,他们只是没有很好地指定它.. 这是引用:

                  请注意,这不使用布局 文件。只需创建一个TextView,给它 一些文本并将其设置为内容。 为三个中的每一个复制这个 活动,并添加相应的 标记到 Android 清单文件。

                  【讨论】:

                    猜你喜欢
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 2010-11-14
                    • 2016-10-10
                    • 1970-01-01
                    相关资源
                    最近更新 更多