Android无法停止服务

时间:2014-08-06 19:19:48

标签: android android-intent

在我的应用程序中,我使用的服务会定期检查登录用户是否有新的个人消息。 如果用户启用通知功能,则启动该服务。现在,如果用户禁用通知功能,我想停止服务。

我尝试使用以下代码行停止服务。

Intent service = new Intent(getApplicationContext(), MessageService.class);
                stopService(service);

问题是服务没有停止。它继续工作。

您可以在此处查看我的留言服务。

public class MessageService extends Service {

private int intervall;


public MessageService(){
}

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


@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    super.onStartCommand(intent,flags,startId);

    Bundle intentData = intent.getExtras();
    if(intentData != null) {
        this.intervall = intentData.getInt("intervall");
    }

    final Handler handler = new Handler(){
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            // async task for calling api otherwise we get an exeception here
            new ServiceMessagesTask().execute(MessageService.this);
        }
    };

    new Thread(new Runnable(){
        public void run() {
            while(true)
            {
                try {
                    Thread.sleep(intervall); // repeat after given intervall
                    handler.sendEmptyMessage(0);
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }
    }).start();

    return START_STICKY;
}

@Override
public void onDestroy() {
    super.onDestroy();
}

}

我有一个活动,用户可以编辑他的偏好。在那里也可以激活通知功能。

通知服务在savePreferences()方法中启动或停止:

public void savePreferences(View button) {
    EditText login      = (EditText)findViewById(R.id.txtbLogin);
    EditText password   = (EditText)findViewById(R.id.txtbPassword);
    CheckBox enableNotification = (CheckBox) findViewById(R.id.cbNotifications);
    Spinner spinner     = (Spinner) findViewById(R.id.notificationInterval);

    if(!login.getText().equals("") && !password.getText().equals("")){
        Map<String, Object> preferences = new HashMap<String, Object>();
        preferences.put("document_type", CouchbaseHelper.CB_VIEW_USER_PREFERENCES);
        preferences.put("login", login.getText().toString());
        preferences.put("password", password.getText().toString());

        if(enableNotification.isChecked()){
            preferences.put("enableNotification", true);
        } else {
            preferences.put("enableNotification", false);
        }

        preferences.put("notificationInterval", this.notificationInterval);

        CouchbaseHelper couchbaseHelper = new CouchbaseHelper(getApplicationContext());
        String documentId = couchbaseHelper.createDocUserPreferences(preferences);
        couchbaseHelper.closeDb();

        // start notification service if enabled
        if(enableNotification.isChecked()){
            Intent service = new Intent(getApplicationContext(), MessageService.class);
            service.putExtra("intervall", Integer.valueOf(this.notificationInterval)*60*1000);
            startService(service);
        } else {
            // TODO: this is not working!!! service doesnt stop
            // try to stop running service
            if(isMyServiceRunning()){
                Intent service = new Intent(getApplicationContext(), MessageService.class);
                stopService(service);
            }
        }
    }

    finish();
    Intent main = new Intent(Preferences.this, Main.class);
    startActivity(main);
}

1 个答案:

答案 0 :(得分:1)

我担心你真的不知道服务是什么,服务只是一个不需要UI而且没有链接到活动生命周期的组件,因此它在后台运行,但背景不一定意味着在一个单独的线程中,实际上服务在主线程中运行,现在这是一回事,杀死一个服务并不意味着你要杀死你在其中创建的所有工作线程,并且在你的代码中你正在创建一个循环的线程永远,虽然在服务中创建的线程没有以任何方式链接到服务生命周期。

所以,如果你想要停止线程,在startCommand方法中获取对你正在创建的线程的引用,并在onDestroy方法中停止它,而不是进行while(true)验证,去寻找一个标志,只需在onDestroy中将其更改为false,这样就会停止启动服务时创建的线程。

问候!