Bitte entschuldigen Sie, wenn dies einfach zu lösen ist. Ich bin wirklich neu im Debuggen und Lösen von Situationen wie dieser. Ich bin mir wirklich nicht sicher, wo ich anfangen soll, dieses Problem aufzuspüren, und ich bin sicher, dass es sich um die Architektur handelt. Es passiert sporadisch und scheint mehr wie eine Race-Bedingung zu sein, basierend darauf, wie schnell ich versuche, die Animation nach dem Ende der vorherigen Animation neu zu starten. Sehr schätzen Sie alle Hinweise und lernen ein wenig.Wie Debuggen und Auflösen einer NPE in AnimatorListener.onAnimationEnd
08-08 09:26:01.410 30626-30626/com.myapp.myappname E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.myapp.myappname, PID: 30626
java.lang.NullPointerException: Attempt to invoke interface method 'void android.animation.Animator$AnimatorListener.onAnimationEnd(android.animation.Animator)' on a null object reference
at android.animation.ValueAnimator.endAnimation(ValueAnimator.java:1239)
at android.animation.ValueAnimator.cancel(ValueAnimator.java:1140)
at android.animation.ObjectAnimator.animateValue(ObjectAnimator.java:974)
at android.animation.ValueAnimator.animationFrame(ValueAnimator.java:1384)
at android.animation.ValueAnimator.doAnimationFrame(ValueAnimator.java:1427)
at android.animation.ValueAnimator$AnimationHandler.doAnimationFrame(ValueAnimator.java:759)
at android.animation.ValueAnimator$AnimationHandler$1.run(ValueAnimator.java:801)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:920)
at android.view.Choreographer.doCallbacks(Choreographer.java:695)
at android.view.Choreographer.doFrame(Choreographer.java:628)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:906)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:158)
at android.app.ActivityThread.main(ActivityThread.java:7229)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1230)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1120)
Hier ist ein Referenzcode über die Mechanik der NPE. Im Wesentlichen habe ich eine Start- und eine Stopp-Taste, um einen Lichtsensor zu registrieren und die Registrierung aufzuheben. Wenn registriert und ein Lichtereignis passiert, erlaube ich jeweils einen Anruf über eine Sperre und starte einen Handler/Runnable. Wenn die Animation beendet/abgeschlossen ist, wird die Sperre für eine weitere Ausführung in dem Ereignis-Handler freigegeben.
Wo sehe ich die NPE sporadisch passiert, wenn ich START drücken, nachdem ein vorheriger STOP ausgegeben wurde. Es passiert selten, direkt an der Grenze eines STOP Happening und START passiert wieder.
// on startup of app, prepare runnable
runnableAlpha = new Runnable()
{
@Override
public void run()
{
try
{
final float newAlpha = (.10f * (mLastLightValue/(mLightSensor.getMaximumRange()/100)));
final ObjectAnimator oa = ObjectAnimator.ofFloat(mMyAppRatingBar, "alpha", mMyAppRatingBarLastAlpha, newAlpha);
oa.addListener(new AnimatorListener()
{
@Override
public void onAnimationStart(Animator animation)
{
}
@Override
public void onAnimationEnd(Animator animation)
{
try
{
oa.addListener(null);
oa.addUpdateListener(null);
mMyAppRatingBarLastAlpha = newAlpha;
}
catch (Exception e1)
{
// do nothing
}
finally
{
try
{
mTweenLock.release();
}
catch (Exception e1)
{
// do nothing
}
}
}
@Override
public void onAnimationCancel(Animator animation)
{
try
{
oa.addListener(null);
oa.addUpdateListener(null);
mMyAppRatingBarLastAlpha = newAlpha;
}
catch (Exception e1)
{
// do nothing
}
finally
{
try
{
mTweenLock.release();
}
catch (Exception e1)
{
// do nothing
}
}
}
@Override
public void onAnimationRepeat(Animator animation)
{
}
});
oa.setInterpolator(new DecelerateInterpolator());
oa.setDuration(1000);
oa.start();
try
{
if (mAlphaHandler != null)
{
mAlphaHandler.removeCallbacks(runnableAlpha);
}
}
catch (Exception e1)
{
// do nothing
}
finally
{
mAlphaHandler = null;
}
}
catch(Exception e)
{
try
{
mTweenLock.release();
}
catch (Exception e1)
{
// do nothing
}
}
}
}
// wire up handler and runnable only if light sensor registered, light event triggered, no current lock(prior light event being handled)
public void onSensorChanged(SensorEvent event)
{
if(!mTweenLock.tryAcquire())
{
return;
}
try
{
mAlphaHandler = new Handler();
mLastLightValue = event.values[0];
mAlphaHandler.postDelayed(runnableAlpha, 0);
}
catch(Exception e)
{
mAlphaHandler = null;
mTweenLock.release();
}
}
// when we press START button in app, fire up the light sensor to begin work
mSensorManager = (SensorManager) mContext.getSystemService(mContext.SENSOR_SERVICE);
mLightSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_LIGHT);
if(mLightSensor == null)
{
mSensorManager = null;
return;
}
mSensorManager.unregisterListener(this, mLightSensor); // clear out prior if existent
mSensorManager.registerListener(this, mLightSensor, SensorManager.SENSOR_DELAY_UI);
// when we press STOP button in app, we force teardown of everything
try
{
if(mAlphaHandler != null)
{
mAlphaHandler.removeCallbacksAndMessages(null);
mAlphaHandler = null;
runnableAlpha = null;
}
}
catch(Exception e1)
{
// do nothing
}
Wo ist ein Code? –
Lassen Sie mich wissen, welchen Code Sie gerne sehen würden. Angenommen, nur das Setup und der Abbau der Animation? – user1701153
Ja, und Animation zu –