NPE when creating a fragment

2019-01-20 20:17发布

问题:

i am creating an example about Fragment with sensorEventlitener. the mainactivity hosts the fragment as shown below in the code, but at run time i receive the below posted logcat Errors.

MainActivity:

public class MainActivity extends Activity {

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main_activity);

    initViews();
}

private void initViews() {
    // TODO Auto-generated method stub

    View frag1 = findViewById(R.id.frag_1);

    FragmentManager fMgr = getFragmentManager();
    FragmentTransaction fragmentTransaction = fMgr.beginTransaction();
    fragmentTransaction.replace(R.id.frag_1, new Frag1());
    fragmentTransaction.commit();
}

}

Frag1:

public class Frag1 extends Fragment implements SensorEventListener {

private SensorManager sensorManager;
TextView tvAccX;
TextView tvAccY;
TextView tvAccZ;
Button btnSend;

@Override
public void onAttach(Activity activity) {
    // TODO Auto-generated method stub
    super.onAttach(activity);

    sensorManager = (SensorManager) getActivity().getSystemService(Context.SENSOR_SERVICE);
}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) {
    // TODO Auto-generated method stub
    View view = inflater.inflate(R.layout.frag_1, container, false);

    tvAccX = (TextView) view.findViewById(R.id.tv_accX_value);
    tvAccY = (TextView) view.findViewById(R.id.tv_accY_value);
    tvAccZ = (TextView) view.findViewById(R.id.tv_accZ_value);
    btnSend = (Button) view.findViewById(R.id.btn_send);

    return view;
}

@Override
public void onResume() {
    // TODO Auto-generated method stub
    super.onResume();
    Sensor accSensor = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
    sensorManager.registerListener(this, accSensor, sensorManager.SENSOR_DELAY_FASTEST);
}

@Override
public void onPause() {
    // TODO Auto-generated method stub
    super.onPause();
    sensorManager.unregisterListener(this);
}

@Override
public void onSensorChanged(SensorEvent event) {
    // TODO Auto-generated method stub
    switch (event.sensor.getType()) {
    case Sensor.TYPE_ACCELEROMETER:
        showAccReadings(event);
        break;

    default:
        break;
    }
}

private void showAccReadings(SensorEvent event) {
    // TODO Auto-generated method stub
    float[] values = event.values;

    float x = values[0];
    float y = values[1];
    float z = values[2];

    tvAccX.setText(String.valueOf(x));
    tvAccY.setText(String.valueOf(y));
    tvAccZ.setText(String.valueOf(z));
}

@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
    // TODO Auto-generated method stub

}

}

mainActivity.xml:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="${relativePackage}.${activityClass}">

<fragment
    android:id="@+id/frag_1"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_centerHorizontal="true"/>

<fragment
    android:id="@+id/frag_2"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_marginTop="50dp"
    android:layout_centerHorizontal="true"
    android:layout_below="@+id/frag_1"/>

</RelativeLayout>

Frag1.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">
<TextView 
    android:id="@+id/tv_accX_label"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignParentStart="true"
    android:text="Acc[X]: "/>
<TextView 
    android:id="@+id/tv_accX_value"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_centerHorizontal="true"
    android:layout_toRightOf="@+id/tv_accX_label"/>

<TextView 
    android:id="@+id/tv_accY_label"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignParentStart="true"
    android:layout_below="@+id/tv_accX_label"
    android:text="Acc[Y]: "/>
<TextView 
    android:id="@+id/tv_accY_value"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_centerHorizontal="true"
    android:layout_toRightOf="@+id/tv_accY_label"/>

<TextView 
    android:id="@+id/tv_accZ_label"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignParentStart="true"
    android:layout_below="@+id/tv_accY_label"
    android:text="Acc[Z]: "/>
<TextView 
    android:id="@+id/tv_accZ_value"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_centerHorizontal="true"
    android:layout_toRightOf="@+id/tv_accZ_label"/>

<Button 
    android:id="@+id/btn_send"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_below="@+id/tv_accZ_label"
    android:gravity="center_vertical|center_horizontal"
    android:text="send to frag_2"/>
</RelativeLayout>

LogCat:

01-23 15:25:11.200: E/AndroidRuntime(7195): Process: com.example.fragmentcommunication_00, PID: 7195
01-23 15:25:11.200: E/AndroidRuntime(7195): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.fragmentcommunication_00/com.example.fragmentcommunication_00.MainActivity}: android.view.InflateException: Binary XML file line #7: Error inflating class fragment
01-23 15:25:11.200: E/AndroidRuntime(7195):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2282)
01-23 15:25:11.200: E/AndroidRuntime(7195):     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2340)
01-23 15:25:11.200: E/AndroidRuntime(7195):     at android.app.ActivityThread.access$800(ActivityThread.java:157)
01-23 15:25:11.200: E/AndroidRuntime(7195):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1247)
01-23 15:25:11.200: E/AndroidRuntime(7195):     at android.os.Handler.dispatchMessage(Handler.java:102)
01-23 15:25:11.200: E/AndroidRuntime(7195):     at android.os.Looper.loop(Looper.java:157)
01-23 15:25:11.200: E/AndroidRuntime(7195):     at android.app.ActivityThread.main(ActivityThread.java:5293)
01-23 15:25:11.200: E/AndroidRuntime(7195):     at java.lang.reflect.Method.invokeNative(Native Method)
01-23 15:25:11.200: E/AndroidRuntime(7195):     at java.lang.reflect.Method.invoke(Method.java:515)
01-23 15:25:11.200: E/AndroidRuntime(7195):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1265)
01-23 15:25:11.200: E/AndroidRuntime(7195):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1081)
01-23 15:25:11.200: E/AndroidRuntime(7195):     at dalvik.system.NativeStart.main(Native Method)
01-23 15:25:11.200: E/AndroidRuntime(7195): Caused by: android.view.InflateException: Binary XML file line #7: Error inflating class fragment
01-23 15:25:11.200: E/AndroidRuntime(7195):     at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:719)
01-23 15:25:11.200: E/AndroidRuntime(7195):     at android.view.LayoutInflater.rInflate(LayoutInflater.java:761)
01-23 15:25:11.200: E/AndroidRuntime(7195):     at android.view.LayoutInflater.inflate(LayoutInflater.java:498)
01-2    3 15:25:11.200: E/AndroidRuntime(7195):     at android.view.LayoutInflater.inflate(LayoutInflater.java:398)
01-23 15:25:11.200: E/AndroidRuntime(7195):     at android.view.LayoutInflater.inflate(LayoutInflater.java:354)
01-23 15:25:11.200: E/AndroidRuntime(7195):     at com.android.internal.policy.impl.PhoneWindow.setContentView(PhoneWindow.java:340)
01-23 15:25:11.200: E/AndroidRuntime(7195):     at android.app.Activity.setContentView(Activity.java:1973)
01-23 15:25:11.200: E/AndroidRuntime(7195):     at com.example.fragmentcommunication_00.MainActivity.onCreate(MainActivity.java:17)
01-23 15:25:11.200: E/AndroidRuntime(7195):     at android.app.Activity.performCreate(Activity.java:5389)
01-23 15:25:11.200: E/AndroidRuntime(7195):     at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1105)
01-23 15:25:11.200: E/AndroidRuntime(7195):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2246)
01-23 15:25:11.200: E/AndroidRuntime(7195):     ... 11 more
01-23 15:25:11.200: E/AndroidRuntime(7195): Caused by: java.lang.NullPointerException: name == null
01-23 15:25:11.200: E/AndroidRuntime(7195):     at java.lang.VMClassLoader.findLoadedClass(Native Method)
01-23 15:25:11.200: E/AndroidRuntime(7195):     at java.lang.ClassLoader.findLoadedClass(ClassLoader.java:350)
01-23 15:25:11.200: E/AndroidRuntime(7195):     at java.lang.ClassLoader.loadClass(ClassLoader.java:487)
01-23 15:25:11.200: E/AndroidRuntime(7195):     at java.lang.ClassLoader.loadClass(ClassLoader.java:457)
01-23 15:25:11.200: E/AndroidRuntime(7195):     at android.app.Fragment.instantiate(Fragment.java:583)
01-23 15:25:11.200: E/AndroidRuntime(7195):     at android.app.Fragment.instantiate(Fragment.java:561)
01-23 15:25:11.200: E/AndroidRuntime(7195):     at android.app.Activity.onCreateView(Activity.java:4927)
01-23 15:25:11.200: E/AndroidRuntime(7195):     at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:695)

Update:

Frag1.xml:

 <fragment
    android:name="com.example.fragmentcommunication_00.Frag1"
    android:id="@+id/frag_1"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_centerHorizontal="true"/>

Logact:

01-23 15:37:42.980: E/AndroidRuntime(8267): FATAL EXCEPTION: main
01-23 15:37:42.980: E/AndroidRuntime(8267): Process: com.example.fragmentcommunication_00, PID: 8267
01-23 15:37:42.980: E/AndroidRuntime(8267): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.fragmentcommunication_00/com.example.fragmentcommunication_00.MainActivity}: android.view.InflateException: Binary XML file line #14: Error inflating class fragment
01-23 15:37:42.980: E/AndroidRuntime(8267):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2282)
01-23 15:37:42.980: E/AndroidRuntime(8267):     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2340)
01-23 15:37:42.980: E/AndroidRuntime(8267):     at android.app.ActivityThread.access$800(ActivityThread.java:157)
01-23 15:37:42.980: E/AndroidRuntime(8267):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1247)
01-23 15:37:42.980: E/AndroidRuntime(8267):     at android.os.Handler.dispatchMessage(Handler.java:102)
    01-23 15:37:42.980: E/AndroidRuntime(8267):     at android.os.Looper.loop(Looper.java:157)
01-23 15:37:42.980: E/AndroidRuntime(8267):     at android.app.ActivityThread.main(ActivityThread.java:5293)
01-23 15:37:42.980: E/AndroidRuntime(8267):     at java.lang.reflect.Method.invokeNative(Native Method)
01-23 15:37:42.980: E/AndroidRuntime(8267):     at java.lang.reflect.Method.invoke(Method.java:515)
01-23 15:37:42.980: E/AndroidRuntime(8267):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1265)
01-23 15:37:42.980: E/AndroidRuntime(8267):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1081)
01-23 15:37:42.980: E/AndroidRuntime(8267):     at dalvik.system.NativeStart.main(Native Method)
01-23 15:37:42.980: E/AndroidRuntime(8267): Caused by: android.view.InflateException: Binary XML file line #14: Error inflating class fragment
01-23 15:37:42.980: E/AndroidRuntime(8267):     at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:719)
01-23 15:37:42.980: E/AndroidRuntime(8267):     at android.view.LayoutInflater.rInflate(LayoutInflater.java:761)
01-23 15:37:42.980: E/AndroidRuntime(8267):     at android.view.LayoutInflater.inflate(LayoutInflater.java:498)
01-23 15:37:42.980: E/AndroidRuntime(8267):     at android.view.LayoutInflater.inflate(LayoutInflater.java:398)
01-23 15:37:42.980: E/AndroidRuntime(8267):     at android.view.LayoutInflater.inflate(LayoutInflater.java:354)
01-23 15:37:42.980: E/AndroidRuntime(8267):     at com.android.internal.policy.impl.PhoneWindow.setContentView(PhoneWindow.java:340)
01-23 15:37:42.980: E/AndroidRuntime(8267):     at android.app.Activity.setContentView(Activity.java:1973)
01-23 15:37:42.980: E/AndroidRuntime(8267):     at com.example.fragmentcommunication_00.MainActivity.onCreate(MainActivity.java:17)
01-23 15:37:42.980: E/AndroidRuntime(8267):     at android.app.Activity.performCreate(Activity.java:5389)
01-23 15:37:42.980: E/AndroidRuntime(8267):     at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1105)
01-23 15:37:42.980: E/AndroidRuntime(8267):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2246)
01-23 15:37:42.980: E/AndroidRuntime(8267):     ... 11 more
01-23 15:37:42.980: E/AndroidRuntime(8267): Caused by: java.lang.NullPointerException: name == null
01-23 15:37:42.980: E/AndroidRuntime(8267):     at java.lang.VMClassLoader.findLoadedClass(Native Method)
01-23 15:37:42.980: E/AndroidRuntime(8267):     at java.lang.ClassLoader.findLoadedClass(ClassLoader.java:350)
01-23 15:37:42.980: E/AndroidRuntime(8267):     at java.lang.ClassLoader.loadClass(ClassLoader.java:487)
01-23 15:37:42.980: E/AndroidRuntime(8267):     at java.lang.ClassLoader.loadClass(ClassLoader.java:457)
01-23 15:37:42.980: E/AndroidRuntime(8267):     at android.app.Fragment.instantiate(Fragment.java:583)
01-23 15:37:42.980: E/AndroidRuntime(8267):     at android.app.Fragment.instantiate(Fragment.java:561)
01-23 15:37:42.980: E/AndroidRuntime(8267):     at android.app.Activity.onCreateView(Activity.java:4927)
01-23 15:37:42.980: E/AndroidRuntime(8267):     at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:695)

回答1:

It looks like you are missing the name attribute in your fragment tags in your activity layout file. There are basically two ways to get a Fragment inflated into your view hierarchy:

  1. Specify everything in the layout XML
  2. Load up the Fragment in your java code

It appears that you have mixed these two paradigms together, which is what is causing you the trouble.

In order to do everything in the layout XML, you must specify the name attribute. So, something like this:

<fragment
    android:name="com.my.package.for.Frag1"
    android:id="@+id/frag_1"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_centerHorizontal="true"/>

You could then remove the code from your initViews() method as it is no longer necessary.

If, instead, you would prefer to do everything in code, then you must change your layout to specify an empty container where the Fragment will go. For example, use a FrameLayout instead of a fragment tag, like this:

<FrameLayout
    android:id="@+id/frag_1"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_centerHorizontal="true"/>


回答2:

you are declaring the <fragment tag in your xml

   <fragment
    android:id="@+id/frag_2"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_marginTop="50dp"
    android:layout_centerHorizontal="true"
    android:layout_below="@+id/frag_1"/>

but you didn't specify the android:name= property, which tells the system which fragment it has to instantiate. It must contain the full qualified path to the fragment subclass you want to instantiate. E.g

android:name="path.to.Frag1"