Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/216.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 在onCreate()中访问视图的NullPointerException_Java_Android_Android Fragments_Nullpointerexception - Fatal编程技术网

Java 在onCreate()中访问视图的NullPointerException

Java 在onCreate()中访问视图的NullPointerException,java,android,android-fragments,nullpointerexception,Java,Android,Android Fragments,Nullpointerexception,这是一个常见于StackOverflow上的问题的典型问题 我正在学习一个教程。我使用向导创建了一个新活动。在我的activity onCreate中,当试图对使用findViewById获得的视图调用方法时,我得到了NullPointerException 创建时的活动: 布局XML片段_main.XML: 本教程可能已经过时,试图创建基于活动的UI,而不是向导生成的代码首选的基于片段的UI 该视图位于片段布局fragment_main.xml中,而不在活动布局activity_main.xm

这是一个常见于StackOverflow上的问题的典型问题

我正在学习一个教程。我使用向导创建了一个新活动。在我的activity onCreate中,当试图对使用findViewById获得的视图调用方法时,我得到了NullPointerException

创建时的活动:

布局XML片段_main.XML:


本教程可能已经过时,试图创建基于活动的UI,而不是向导生成的代码首选的基于片段的UI

该视图位于片段布局fragment_main.xml中,而不在活动布局activity_main.xml中。onCreate在生命周期中太早,无法在“活动”视图层次结构中找到它,因此返回null。在null上调用方法会导致NPE

首选的解决方案是将代码移动到片段onCreateView,在膨胀的片段布局根视图上调用findViewById:


作为旁注,片段布局最终将成为活动视图层次结构的一部分,并且只有在片段事务运行之后,才能通过activity findViewById发现。挂起的片段事务在onCreate之后在super.onStart中执行。

既然您已经在fragment\u main.xml中声明了您的视图,请将该段代码移动到片段的onCreateView方法中获取NPE的位置。
这应该可以解决问题。

同意,这是一个典型的错误,因为当人们开始开发Android时,往往不了解片段是如何工作的。为了减少混乱,我创建了一个简单的示例代码,我最初发布在上面,但我也发布在这里

一个例子如下:

public class ContainerActivity extends FragmentActivity implements ExampleFragment.Callback
{
    @Override
    public void onCreate(Bundle saveInstanceState)
    {
        super.onCreate(saveInstanceState);
        this.setContentView(R.layout.activity_container);
        if (saveInstanceState == null)
        {               
             getSupportFragmentManager().beginTransaction()
                .add(R.id.activity_container_container, new ExampleFragment())
                .addToBackStack(null)
             .commit();
        }
        getSupportFragmentManager().addOnBackStackChangedListener(new OnBackStackChangedListener()
        {
            public void onBackStackChanged()
            {
                int backCount = getSupportFragmentManager().getBackStackEntryCount();
                if (backCount == 0)
                {
                    finish();
                }
            }
        });
    }

    @Override
    public void exampleFragmentCallback()
    {
        Toast.makeText(this, "Hello!", Toast.LENGTH_LONG).show();
    }
}
activity_container.xml:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <FrameLayout
        android:id="@+id/activity_container_container"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

</RelativeLayout>
fragment_example.xml:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent" >

        <Button
            android:id="@+id/example_button_one"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_alignParentTop="true"
            android:layout_centerHorizontal="true"
            android:layout_marginTop="30dp"
            android:text="@string/hello" 
            android:layout_marginLeft="20dp"
            android:layout_marginRight="20dp"/>

        <Button
            android:id="@+id/example_button_two"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignLeft="@+id/example_button_one"
            android:layout_alignRight="@+id/example_button_one"
            android:layout_below="@+id/example_button_one"
            android:layout_marginTop="30dp"
            android:text="@string/hello" />

        <Button
            android:id="@+id/example_button_three"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignLeft="@+id/example_button_two"
            android:layout_alignRight="@+id/example_button_two"
            android:layout_below="@+id/example_button_two"
            android:layout_marginTop="30dp"
            android:text="@string/hello" />

</RelativeLayout>
这应该是一个有效的例子,它展示了如何使用一个活动来显示一个片段,并处理该片段中的事件。以及如何与包含活动进行通信。

尝试启动方法并使用

View view = getView().findViewById(R.id.something);
或者在onStart中使用getView.findViewById方法声明任何视图

声明anyView上的click listener.setOnClickListenerthis

在activity_main.xml中添加以下内容


在上述问题中发布的代码中存在一个问题: 您正在oncreate方法中使用R.layout.activity_main,但xml文件名为fragment_main.xml,这意味着您正在尝试获取fragment_main.xml文件的视图,该文件未显示,因此会出现空指针异常。更改代码如下:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.fragment_main);// your xml layout ,where the views are

    View something = findViewById(R.id.something);
    something.setOnClickListener(new View.OnClickListener() { ... }); // NPE HERE

    if (savedInstanceState == null) {
        getSupportFragmentManager().beginTransaction()
                .add(R.id.container, new PlaceholderFragment()).commit();
    }
}

您正试图访问onCreate中的UI元素,但现在访问它们还为时过早,因为可以在onCreateView方法中创建片段内视图。 onActivityCreated方法可以可靠地处理它们上的任何操作,因为在此状态下活动已完全加载。

我在调用findViewById onCreate和onCreateView方法后初始化侦听器时遇到了相同的NullPointerException

但是当我使用onActivityCreatedBundle savedInstanceState{…}时,它就工作了。因此,我可以访问GroupView并设置我的侦听器


我希望这会有所帮助。

尝试将访问视图转移到片段的onViewCreated方法,因为有时当您尝试在onCreate方法中访问视图时,它们在导致空指针异常时不会呈现

 @Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
    super.onViewCreated(view, savedInstanceState);
     View something = findViewById(R.id.something);
     something.setOnClickListener(new View.OnClickListener() { ... }); // NPE HERE

     if (savedInstanceState == null) {
           getSupportFragmentManager().beginTransaction()
            .add(R.id.container, new PlaceholderFragment()).commit();
    }
 }

视图某物在片段中,而不是在活动中,因此您必须在片段类中访问它,而不是在活动中访问它,如

在占位符fragment.class中


你必须记住重要的是: NullPointerException发生在您声明变量并尝试在为其赋值之前检索其值时。

使用或调用片段视图时,请使用onViewCreated方法

override fun onViewCreated(view: View?, savedInstanceState: Bundle?) {
    super.onViewCreated(view, savedInstanceState)
      View v = view.findViewById(R.id.whatever)
}

用于查找视图的最流行的库,几乎每个开发人员都使用它

正如我所能做的那样,他们的答案足以解释如何用适当的方法来寻找观点。但是,如果你是android开发者,每天都频繁地编写代码,那么你可以使用黄油刀,这可以节省大量查找视图的时间,而且你不需要为它编写代码,只需2-3个步骤,你就可以在毫秒内找到视图

在应用程序级渐变中添加依赖项:

添加黄油刀插件:

然后搜索Android ButterKnife Zelezny,安装插件,重启你的工作室,你就完成了

现在只需转到活动的Oncreate方法,右键单击布局名称,点击generate按钮并选择butterknife injection选项,您的视图引用将自动创建,如下所述:

    @BindView(R.id.rv_featured_artist)
    ViewPager rvFeaturedArtist;
    @BindView(R.id.indicator)
    PageIndicator indicator;
    @BindView(R.id.rv_artist)
    RecyclerView rvArtist;
    @BindView(R.id.nsv)
    NestedScrollingView nsv;
    @BindView(R.id.btn_filter)
    Button btnFilter;

此示例使用android-support-v4库进行FragmentActivity和support fragment manager。上提供了一个更完整的示例,尽管您应该使用Otto进行通信,而不是回调,对我来说,这很有用,因为我试图访问片段的onCreateView中的同级视图,其中片段声明为I
n xml。onCreateView中的同级视图仍然为空,因为父视图尚未完成膨胀,但在onStart中它们有:findViewById部分应该在onActivityCreated中。@Nepster可以,但不必。有时活动尚未附加到片段。@Nepster这就是为什么在rootView上调用findViewById而不是在activity上调用findViewById。
<fragment
    android:id="@+id/myFragment"
    android:name="packagename.MainActivity$PlaceholderFragment"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content" >
</fragment>
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.fragment_main);// your xml layout ,where the views are

    View something = findViewById(R.id.something);
    something.setOnClickListener(new View.OnClickListener() { ... }); // NPE HERE

    if (savedInstanceState == null) {
        getSupportFragmentManager().beginTransaction()
                .add(R.id.container, new PlaceholderFragment()).commit();
    }
}
 @Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
    super.onViewCreated(view, savedInstanceState);
     View something = findViewById(R.id.something);
     something.setOnClickListener(new View.OnClickListener() { ... }); // NPE HERE

     if (savedInstanceState == null) {
           getSupportFragmentManager().beginTransaction()
            .add(R.id.container, new PlaceholderFragment()).commit();
    }
 }
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View root = inflater.inflate(R.layout.fragment_main, container,
  false);

View something = root .findViewById(R.id.something);
something.setOnClickListener(new View.OnClickListener() { ... });

return root;
}
override fun onViewCreated(view: View?, savedInstanceState: Bundle?) {
    super.onViewCreated(view, savedInstanceState)
      View v = view.findViewById(R.id.whatever)
}
implementation 'com.jakewharton:butterknife:8.8.1'
annotationProcessor 'com.jakewharton:butterknife-compiler:8.8.1'
File -> Settings -> plugins-> 
    @BindView(R.id.rv_featured_artist)
    ViewPager rvFeaturedArtist;
    @BindView(R.id.indicator)
    PageIndicator indicator;
    @BindView(R.id.rv_artist)
    RecyclerView rvArtist;
    @BindView(R.id.nsv)
    NestedScrollingView nsv;
    @BindView(R.id.btn_filter)
    Button btnFilter;