문제

I want to pass the readings of a sensor to the class MyCompassView that extends a view, and based on the readings from the sensor to be passed, a pointer is changing its orientation. Actually, all this works fine, i tested it. But the same concept when I tried to implement it on a surface view that opens the camera preview on the surface, it does not work and crashes the app. Simply, I have SurfaceViewHolder class the holds the camera preview, the MyCompassView class as described above and the MainActivity that should has both views of MyCompassView and SurfaceHolder on its surface. The way I used to overlay the MainActivity with these views is as posted below: please help me to find why the method myCompassView.update(azimuth);that is located inside the onSensorChanged cause the logcate to say"Null Pointer Exception"

UPDATE:

When I omit myCompassView.update(azimuth); the app works but with drawings in the MyCompassView class is static not indicting orientation, ofcourse because of the myCompassView.update(azimuth); is not activated.However, when i activate that method
the app crashs and the logcat generates the posted output. Line 100 is myCompassView.update(azimuth);

MainActivity.java

     public class Mainactivity extends ActionBarActivity  implements SensorEventListener {

    private SurfaceHolderActivity myCameraSurfaceHolder;
    private View compassOverLayView;
    private MyCompassView myCompassView;
    private LayoutInflater loiViewInflater = null;
            ..
            ..
            //myCompassView = new MyCompassView(getApplicationContext());               
            myCompassView = (MyCompassView) findViewById(R.id.mycompass);
        myCameraSurfaceHolder = new SurfaceHolderActivity(this);
        setContentView(myCameraSurfaceHolder);          
                    
        loiViewInflater = (LayoutInflater) getSystemService (Context.LAYOUT_INFLATER_SERVICE);
        loiViewInflater = LayoutInflater.from(getApplicationContext());
        compassOverLayView = loiViewInflater.inflate(R.layout.activity_viewactivity, null);
        addContentView(compassOverLayView, new LayoutParams(LayoutParams.FILL_PARENT, 
                LayoutParams.FILL_PARENT));
    ...
    ...
            @Override
    public void onSensorChanged(SensorEvent event) {
        // TODO Auto-generated method stub
        switch (event.sensor.getType()) {
        case Sensor.TYPE_ACCELEROMETER:
            valuesAccelerometer = event.values.clone();
            /*for (int i=0; i<3; i++) {
                valuesAccelerometer[i] = event.values[i];
            }*/
            break;
        case Sensor.TYPE_MAGNETIC_FIELD:
            valuesMagneticField = event.values.clone();
            /*for (int i=0; i<3; i++) {
                valuesMagneticField[i] = event.values[i];
            }*/
            break;
        }
        
        boolean success = SensorManager.getRotationMatrix(MatrixR, MatrixI, 
                valuesMagneticField, valuesAccelerometer);
        if (success) {
            SensorManager.getOrientation(MatrixR, MatrixValues);
            azimuth = Math.toDegrees(MatrixValues[0]);
            pitch = Math.toDegrees(MatrixValues[1]);
            roll = Math.toDegrees(MatrixValues[2]);             
            myCompassView.update(azimuth);
        } 
    }

Activity_ViewActivity.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"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="com.example.augrealtest00.Mainactivity" >

<view 
        android:id="@+id/mycompass" 
        android:layout_height="match_parent" 
        android:layout_width="match_parent" 
        class="com.example.augrealtest01.MyCompassView"/>

</RelativeLayout>

Logcat:

04-26 23:38:15.136: E/AndroidRuntime(18873): java.lang.NullPointerException
04-26 23:38:15.136: E/AndroidRuntime(18873):    at 
com.example.augrealtest01.Mainactivity.onSensorChanged(Mainactivity.java:100)
04-26 23:38:15.136: E/AndroidRuntime(18873):    at         android.hardware.SystemSensorManager$SensorEventQueue.dispatchSensorEvent(SystemSensorManag    er.java:467)
04-26 23:38:15.136: E/AndroidRuntime(18873):    at  
android.os.MessageQueue.nativePollOnce(Native Method)
04-26 23:38:15.136: E/AndroidRuntime(18873):    at    
android.os.MessageQueue.next(MessageQueue.java:132)
04-26 23:38:15.136: E/AndroidRuntime(18873):    at    
android.os.Looper.loop(Looper.java:124)
04-26 23:38:15.136: E/AndroidRuntime(18873):    at android.app.ActivityThread.main(ActivityThread.java:5493)
도움이 되었습니까?

해결책

Move that line :

myCompassView = (MyCompassView) findViewById(R.id.mycompass);

to be called after :

setContentView(myCameraSurfaceHolder);
....
addContentView(compassOverLayView, new LayoutParams(LayoutParams.FILL_PARENT, 
            LayoutParams.FILL_PARENT));

So the view with id = mycompass is attached to activity's view hierarchy.

Otherwise, findViewById will return null, thus your NPE.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top