当应用程序从任务管理器中杀死时服务崩溃

时间:2016-12-29 17:00:14

标签: android

我想开发android应用程序,我写下面的代码,但是当运行应用程序时,当来自 taskBar (清除应用程序)的关闭应用程序显示我错误时:

E/AndroidRuntime: FATAL EXCEPTION: main
Process: in.nouri.cameraalways, PID: 5300
java.lang.RuntimeException: Unable to start service in.nouri.cameraalways.Service.OverlayService@ba23650 with null: java.lang.NullPointerException: Attempt to invoke virtual method 'float android.content.Intent.getFloatExtra(java.lang.String, float)' on a null object reference
 at android.app.ActivityThread.handleServiceArgs(ActivityThread.java:3394)
 at android.app.ActivityThread.-wrap21(ActivityThread.java)
 at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1609)
 at android.os.Handler.dispatchMessage(Handler.java:102)
 at android.os.Looper.loop(Looper.java:154)
 at android.app.ActivityThread.main(ActivityThread.java:6247)
 at java.lang.reflect.Method.invoke(Native Method)
 at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:872)
 at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:762)
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'float android.content.Intent.getFloatExtra(java.lang.String, float)' on a null object reference
 at in.nouri.cameraalways.Service.OverlayService.onStartCommand(OverlayService.java:113)
 at android.app.ActivityThread.handleServiceArgs(ActivityThread.java:3377)
 at android.app.ActivityThread.-wrap21(ActivityThread.java) 
 at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1609) 
 at android.os.Handler.dispatchMessage(Handler.java:102) 
 at android.os.Looper.loop(Looper.java:154) 
 at android.app.ActivityThread.main(ActivityThread.java:6247) 
 at java.lang.reflect.Method.invoke(Native Method) 
 at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:872) 
 at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:762) 

我的服务类:

public class OverlayService extends Service {
    public static final String ACTION_CHANGE_ALPHA = "in.nouri.cameraalways.action.CHANGE_ALPHA";

    public static final String EXTRA_ALPHA = "in.nouri.cameraalways.extra.ALPHA";
    public static final String EXTRA_SX = "in.nouri.cameraalways.extra.ScaleX";
    public static final String EXTRA_SY = "in.nouri.cameraalways.extra.ScaleY";

    private View mOverlayView;

    private BroadcastReceiver mReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            Log.d("OverlayService", "(broadcast received) action:" + intent.getAction());
            switch (intent.getAction()) {
                case ACTION_CHANGE_ALPHA:
                    setOverlayAlpha(intent.getFloatExtra(EXTRA_ALPHA, CamOverlay.DEFAULT_ALPHA));
                    break;
            }
        }
    };

    private static boolean running = false;

    public static void start(Context context) {
        SharedPreferences sharedPreferences =
                PreferenceManager.getDefaultSharedPreferences(context);
        float alpha = Float.parseFloat(sharedPreferences.getString(
                context.getString(R.string.key_pref_alpha), String.valueOf(CamOverlay.DEFAULT_ALPHA)));
        float sx = sharedPreferences.getBoolean(
                context.getString(R.string.key_pref_invert_x), false) ? -1 : 1;
        float sy = sharedPreferences.getBoolean(
                context.getString(R.string.key_pref_invert_y), false) ? -1 : 1;
        Bundle bundle = new Bundle();
        bundle.putFloat(EXTRA_ALPHA, alpha);
        bundle.putFloat(EXTRA_SX, sx);
        bundle.putFloat(EXTRA_SY, sy);
        start(context, bundle);
    }

    public static void start(Context context, @NonNull Bundle bundle) {
        Intent intent = new Intent(context, OverlayService.class);
        intent.putExtras(bundle);
        context.startService(intent);
    }

    public static void stop(Context context) {
        Intent intent = new Intent(context, OverlayService.class);
        context.stopService(intent);
    }

    public static void toggle(Context context) {
        if (running)
            stop(context);
        else
            start(context);
    }

    public static boolean isRunning() {
        String str;
        if (running) {
            str = "RUNNING";
        } else {
            str = "NOT running";
        }
        Log.d("OverlayService", "service is " + str);
        return running;
    }

    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    public void onCreate() {
        Log.d("OverlayService", "onCreate");
        super.onCreate();
        running = true;

        mOverlayView = CamOverlay.show(this);

        IntentFilter filter = new IntentFilter();
        filter.addAction(ACTION_CHANGE_ALPHA);
        registerReceiver(mReceiver, filter);
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.d("OverlayService", "onStartCommand");
            setOverlayAlpha(intent.getFloatExtra(EXTRA_ALPHA, CamOverlay.DEFAULT_ALPHA));
            float sx = intent.getFloatExtra(EXTRA_SX, 1);
            float sy = intent.getFloatExtra(EXTRA_SY, 1);
            setOverlayScale(sx, sy);

        return super.onStartCommand(intent, flags, startId);
    }

    @Override
    public void onDestroy() {
        Log.d("OverlayService", "onDestroy");
        super.onDestroy();
        running = false;
        unregisterReceiver(mReceiver);

        CamOverlay.hide();
    }

    protected void setOverlayAlpha(float alpha) {
        if (mOverlayView != null) {
            mOverlayView.setAlpha(alpha);
        }
    }

    void setOverlayScale(float sx, float sy) {
        if (mOverlayView != null) {
            mOverlayView.setScaleX(sx);
            mOverlayView.setScaleY(sy);
        }
    }
}

亲爱的朋友们,我知道nullPointerException的这个错误,但我不知道如何解决这个问题?

请不要给我负面的分数。谢谢所有< 3

1 个答案:

答案 0 :(得分:3)

问题是,当你杀死你的应用程序时,Android操作系统会尝试重新创建你的服务,那时你将intent作为null并且你再次尝试从{{1}获取数据在intent内,此时onStartCommandnull,以便在重新使用时再次获取intent START_REDELIVER_INTENT

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.d("OverlayService", "onStartCommand");
            setOverlayAlpha(intent.getFloatExtra(EXTRA_ALPHA, CamOverlay.DEFAULT_ALPHA));
            float sx = intent.getFloatExtra(EXTRA_SX, 1);
            float sy = intent.getFloatExtra(EXTRA_SY, 1);
            setOverlayScale(sx, sy);

        return START_REDELIVER_INTENT;
    }

或者如果您不希望操作系统重新创建您的服务,请使用START_NOT_STICKY