Java 我需要从MainActivity取消在服务类中启动的计时器,但获取null引用异常

Java 我需要从MainActivity取消在服务类中启动的计时器,但获取null引用异常,java,android,timer,nullpointerexception,timertask,Java,Android,Timer,Nullpointerexception,Timertask,我有一个服务类型类,它在onCreate方法中启动timertask,当用户按下按钮时,我需要从MainActivity停止计时器。我知道我必须在我的服务中保留对计时器的引用,但我不知道如何做,需要一些帮助,请 请看一下我的代码 package com.example.timertest; import android.content.Intent; import android.support.v7.app.AppCompatActivity; import android.os.Bundl

我有一个服务类型类,它在onCreate方法中启动timertask,当用户按下按钮时,我需要从MainActivity停止计时器。我知道我必须在我的服务中保留对计时器的引用,但我不知道如何做,需要一些帮助,请

请看一下我的代码

package com.example.timertest;

import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;

public class MainActivity extends AppCompatActivity implements View.OnClickListener {
    Button button;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        button = findViewById(R.id.button);
        button.setOnClickListener(this);
        startService(new Intent(this, TimeService.class));

    }

    @Override
    public void onClick(View v) {
        if(v.getId() == R.id.button){
            // i need here to call mTimer.cancel() in TimeService.class
            //
        }
    }
}
//这里是TimeService.java

package com.example.timertest;

import android.app.Service;
import android.content.Intent;
import android.os.Handler;
import android.os.IBinder;
import android.support.annotation.Nullable;
import android.widget.Toast;


import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;

public class TimeService extends Service {
    public Timer mTimer;
    private Handler mHandler = new Handler();
    long NOTIFY_INTERVAL = 60 * 1000 * 1; // 1 min

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

    @Override
    public void onCreate() {
        if (mTimer != null) {
            mTimer.cancel();
        } else {
            mTimer = new Timer();
        }
        mTimer.scheduleAtFixedRate(new RefreshDataTimerTask(), 0, NOTIFY_INTERVAL);
    }

    class RefreshDataTimerTask extends TimerTask {

        @Override
        public void run() {
            mHandler.post(new Runnable() {

                @Override
                public void run() {
                    Toast.makeText(getApplicationContext(), getDateTime(), Toast.LENGTH_LONG).show();
                }
            });
        }

        private String getDateTime() {
            SimpleDateFormat sdf = new SimpleDateFormat("[yyyy/MM/dd - HH:mm:ss]");
            return sdf.format(new Date());
        }
    }
}

//在舱单中登记的服务

<service android:name=".TimeService"/>
我试图调用mTimer.cancel,但得到了一个空引用,因为我似乎已经创建了服务类的一个新实例

这个例子展示了一个每分钟都有日期和时间的祝酒词,我想当15秒过去,我按下按钮时,计时器将被取消,并从一开始再次开始计数60秒。在这个服务中,我有很多其他的东西,比如通知、频道、共享首选项等等,所以如果我只能使用timer对象操作,那就太好了。

看看这个和。有一个示例说明了如何在您可以直接访问服务方法之后将服务绑定到活动

成功绑定后,您可以在服务中添加方法以停止计时器:

public void stopMyTimer() {
    mTimer.cancel();
}

并从活动调用此方法这可能不是最佳做法,但您可以通过直接引用类来访问公共值:

TimeService.mTimer.cancel()

因为服务的功能类似于单例,startService的每次调用都应该调用同一个实例。

从哪里调用cancel timer?我需要从from button click事件调用,但我不知道如何引用mTimer对象。你的链接没有用,这不是我的情况,无论如何,谢谢你。感谢Oleg GolomozThank您,我已经找到了解决方案,但如果可能的话,我不想停止服务。我只想把计时器停在原来的位置,重新启动计时器,只需要一个新的计数周期。我在服务内部也有其他东西,它们与计时器的问题没有任何共同之处。谢谢,您的回答和链接解决了我的问题。这不起作用,尽管mTimer已宣布为公共,但它在MainActivity中不可见。解决这个问题要复杂得多,看看Oleg Golomoz之前的回答。对我来说,这是正确的解决方案。