findViewById()方法有时仅返回null(大部分时间都正常工作)

时间:2016-06-13 05:18:49

标签: android

我在这里遇到一个非常奇怪的问题。在我的fragment中,在我inflate之后,layoutfindViewById()方法有时会返回null。但这个问题根本不可复制。我从Crashlytics获得这些崩溃报告。此次崩溃也发生在其中一名QA成员身上,但之后他也无法重现这个问题。

这是我片段的代码

      @Override
 public View onCreateView(LayoutInflater inflater, ViewGroup container,
                           Bundle savedInstanceState) {
    View customView= inflater.inflate(R.layout.custom_view, container, false);
    ImageView back= (ImageView) customView.findViewById(R.id.back);

    //Throwing Null Pointer Exception for the below line.
    back.someFunc();
    return customView;
 }

XML文件:

  <?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
                xmlns:app="http://schemas.android.com/apk/res-auto"
                android:id="@+id/topics_parent"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:orientation="vertical"
                android:background="?attr/default_background">

    <ImageView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:layout_alignParentRight="true"
        android:layout_marginRight="@dimen/back_to_top_margin_right"
        android:layout_marginBottom="@dimen/back_to_top_margin_bottom"
        android:src="@drawable/back"
        android:visibility="gone"
        android:id="@+id/back"/>

    <LinearLayout
        android:id="@+id/error_parent"
        android:layout_width="match_parent"
        android:background="?attr/default_background"
        android:orientation="vertical"
        android:layout_height="match_parent">
    </LinearLayout>

    <ProgressBar
        android:id="@+id/progressbar"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"/>
</RelativeLayout>

崩溃日志

    Fatal Exception: java.lang.RuntimeException: Unable to start activity ComponentInfo{com.myapp/com.myapp.news.activities.NewsHomeActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.ImageView.setOnClickListener(android.view.View$OnClickListener)' on a null object reference
       at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2316)
       at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2376)
       at android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:3928)
       at android.app.ActivityThread.access$900(ActivityThread.java:147)
       at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1287)
       at android.os.Handler.dispatchMessage(Handler.java:102)
       at android.os.Looper.loop(Looper.java:135)
       at android.app.ActivityThread.main(ActivityThread.java:5253)
       at java.lang.reflect.Method.invoke(Method.java)
       at java.lang.reflect.Method.invoke(Method.java:372)
       at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899)
       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)
Caused by java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.ImageView.setOnClickListener(android.view.View$OnClickListener)' on a null object reference
       at com.myapp.news.fragments.TopicsGroupFragment.onCreateView(TopicsGroupFragment.java:157)
       at android.app.Fragment.performCreateView(Fragment.java:2053)
       at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:894)
       at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:1067)
       at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:1049)
       at android.app.FragmentManagerImpl.dispatchActivityCreated(FragmentManager.java:1869)
       at android.app.Activity.performCreateCommon(Activity.java:5970)
       at android.app.Activity.performCreate(Activity.java:5977)
       at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1105)
       at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2269)
       at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2376)
       at android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:3928)
       at android.app.ActivityThread.access$900(ActivityThread.java:147)
       at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1287)
       at android.os.Handler.dispatchMessage(Handler.java:102)
       at android.os.Looper.loop(Looper.java:135)
       at android.app.ActivityThread.main(ActivityThread.java:5253)
       at java.lang.reflect.Method.invoke(Method.java)
       at java.lang.reflect.Method.invoke(Method.java:372)
       at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899)
       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)

很难弄清楚为什么findViewById()为该视图返回null。

注意:我有很多ImageView resources,其ID为back,但它们都在不同的XML文件中。

8 个答案:

答案 0 :(得分:5)

可能是因为在OnCreateView中视图未完全创建。尝试使用以下代码:

/*---------- WHEN THIS FRAGMENT VIEW IS CREATING --------------------------*/
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    return inflater.inflate(getLayoutId(), container, false);
}

/*---------- WHEN FRAGMENT VIEW IS CREATED --------------------------*/
@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
    super.onViewCreated(view, savedInstanceState);
    ImageView back = (ImageView) view.findViewById(R.id.back);
    back.someFunc();
}

答案 1 :(得分:1)

  

将自定义视图分配给findviewbyId。当您在Layout中充气customView时。

View customView= inflater.inflate(R.layout.custom_view, container, false);
ImageView back= (ImageView) customView.findViewById(R.id.back);
  

将您的Multiple image resources ID更改为所有人的唯一身份。

例如backback1back2等。

答案 2 :(得分:1)

可能是因为你过早称呼它。

等到onFinishInflate()。这是一个示例项目,演示了访问其内容的自定义View。

When to use T-SQL or SSIS for ETL

答案 3 :(得分:1)

使用OnCreateView设置片段的布局,并使用onActivityCreated为您的视图创建对象,如下面的代码。

public class test extends Fragment
{
    View view;

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState)
    {
        return view = inflater.inflate(R.layout.fragment_page, container, false);
    }

    @Override
    public void onActivityCreated(@Nullable Bundle savedInstanceState)
    {
        super.onActivityCreated(savedInstanceState);

        ImageView back= (ImageView) view.findViewById(R.id.back);
    }
}

答案 4 :(得分:1)

您正在以名为 customView 的变量夸大您的视图,并且您正在使用 topicsView 视图进行Imageview,这就是您获得Nullpointer异常的原因。

 Lets See the full code.       


    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup  container,
                       Bundle savedInstanceState) {
    View customView= inflater.inflate(R.layout.custom_view, container, false);
    ImageView back= (ImageView) customView.findViewById(R.id.back);

    back.someFunc();
    return customView;

}

答案 5 :(得分:0)

当您使用topicsView查找其ID时,您正在将视图扩展到customView ....

将topicView更改为customView

ImageView back= (ImageView) customView.findViewById(R.id.back);

答案 6 :(得分:0)

当您在名为customView的变量中夸大视图时,您正在使用topicsView视图进行Imageview,这是错误的。

这是完整的代码

    @Override
 public View onCreateView(LayoutInflater inflater, ViewGroup container,
                           Bundle savedInstanceState) {
    View customView= inflater.inflate(R.layout.custom_view, container, false);
    ImageView back= (ImageView) customView.findViewById(R.id.back);


    back.someFunc();
    return customView;
 }

答案 7 :(得分:0)

为避免崩溃,请进行空检查

   @Override
 public View onCreateView(LayoutInflater inflater, ViewGroup container,
                       Bundle savedInstanceState) {
View customView= inflater.inflate(R.layout.custom_view, container, false);
ImageView back= (ImageView) customView.findViewById(R.id.back);

if(back!=null)
back.someFunc();
 }