重新打开和关闭应用程序时,Android服务停止

本尼·莱特

我试图了解android服务的工作原理。

因此,我创建了一个带有活动和服务的简单应用程序,代码如下:

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

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Start Service"
        android:id="@+id/buttonStart"
        android:layout_marginTop="60dp"
        android:layout_alignParentTop="true"
        android:layout_alignParentLeft="true"
        android:layout_alignParentStart="true"
        android:layout_alignParentRight="true"
        android:layout_alignParentEnd="true"
        android:onClick="startButtonClickHandler"/>

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Stop Service"
        android:id="@+id/buttonStop"
        android:layout_below="@+id/buttonStart"
        android:layout_alignParentRight="true"
        android:layout_alignParentEnd="true"
        android:layout_alignParentLeft="true"
        android:layout_alignParentStart="true"
        android:enabled="false"
        android:onClick="stopButtonClickHandler" />

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textAppearance="?android:attr/textAppearanceLarge"
        android:id="@+id/textView"
        android:layout_centerVertical="true"
        android:layout_centerHorizontal="true"
        android:text="Counter is: 0" />

</RelativeLayout>

MainActivity.java:

package com.example.wellsaid.provaservice;

import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.IntentFilter;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.content.Intent;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

import org.w3c.dom.Text;


public class MainActivity extends Activity {

    Button btn_stop = null;
    Button btn_start = null;

    /*---------------------------- CODICE NUOVO -----------------------------*/
    private class MyReceiver extends BroadcastReceiver{

        @Override
        public void onReceive(Context arg0, Intent arg1) {
            int datapassed = arg1.getIntExtra("count", 0);
            TextView text = (TextView) findViewById(R.id.textView);
            text.setText("Counter is: " + datapassed);
        }

    }

    MyReceiver myreceiver = null;
    /*---------------------------------------------------------------------*/

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        btn_stop = (Button) findViewById(R.id.buttonStop);
        btn_start = (Button) findViewById(R.id.buttonStart);
        if(ExampleService.isRunning()){
            btn_stop.setEnabled(true);
            btn_start.setText("Send request");
            Intent intent = new Intent(this, ExampleService.class);
            intent.putExtra("count",0);
            startService(intent);
        }

        /*--------------------- CODICE NUOVO -------------------------------*/
        myreceiver = new MyReceiver();
        IntentFilter intentFilter = new IntentFilter();
        intentFilter.addAction(ExampleService.RETURN_COUNTER);
        registerReceiver(myreceiver, intentFilter);
        /*------------------------------------------------------------------*/
    }

    public void startButtonClickHandler(View v){
        if(!btn_stop.isEnabled()) {
            btn_stop.setEnabled(true);
            btn_start.setText("Send request");
        }
        Intent intent = new Intent(this, ExampleService.class);
        intent.putExtra("count",0);
        startService(intent);
    }

    public void stopButtonClickHandler(View v){
        Intent intent = new Intent(this, ExampleService.class);
        stopService(intent);
        btn_start.setText("Start Service");
        btn_stop.setEnabled(false);
    }
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        int id = item.getItemId();
        return super.onOptionsItemSelected(item);
    }

    @Override
    protected void onStop() {
        // TODO Auto-generated method stub
        unregisterReceiver(myreceiver);
        super.onStop();
    }

}

ExampleService.java

package com.example.wellsaid.provaservice;

import android.app.Activity;
import android.app.AlarmManager;
import android.app.Notification;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.os.IBinder;
import android.os.SystemClock;
import android.util.Log;


public class ExampleService extends Service {

    /*--------------------- CODICE NUOVO-------------------------------*/
    final static String RETURN_COUNTER = "RETURN_COUNTER";
    /*----------------------------------------------------------------*/

    @Override
    public void onTaskRemoved(Intent rootIntent) {
        super.onTaskRemoved(rootIntent);
        Intent intent = new Intent(this, ExampleService.class);
        intent.putExtra("count",thread.getCounter());
        startService(intent);
    }

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

    ExampleThread thread = null;
    private static boolean running = false;

    public static boolean isRunning() { return running; }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        running = true;
        if(thread == null) {
            int counter = intent.getExtras().getInt("count");
            thread = new ExampleThread(counter);
            thread.start();
        }
        else{
            /*-----------------------CODICE NUOVO ----------------------*/
            Intent send = new Intent();
            send.setAction(RETURN_COUNTER);
            send.putExtra("count",thread.getCounter());
            sendBroadcast(send);
            /*----------------------------------------------------------*/
        }
        return startId;
    }

    @Override
    public void onDestroy() {
        running = false;
        thread.kill();
        super.onDestroy();
    }

    private class ExampleThread extends Thread {

        boolean stopped;
        int counter = 0;

        public ExampleThread(int counter){
            this.counter = counter;
        }

        public void start(){
            stopped = false;
            super.start();
        }

        public int getCounter(){ return counter; }

        public void kill(){
            stopped = true;
        }

        public void run(){
            while(!stopped) {
                try { Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); }
                counter++;
                Log.i("Service", "Counter is: " + counter);
            }
        }
    }
}

这就是我的清单:

<?xml version="1.0" encoding="utf-8"?> 
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.wellsaid.provaservice" >

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name=".MainActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

        <service android:name=".ExampleService" />

    </application>

</manifest>

我尝试过:1)打开应用程序,使用“开始”按钮启动服务,然后使用其他按钮将其停止。一切正常2)打开应用程序,启动服务,然后关闭应用程序。一切正常(服务仍在运行)3)打开应用程序,启动服务,重新打开应用程序并获取计数器值。一切正常4)打开应用程序,启动服务,关闭应用程序,重新打开应用程序并停止服务。而且一切正常(关闭后也可以重新启动服务)当我打开,启动服务,关闭应用程序,重新打开以检查计数器编号然后再次关闭应用程序时出现问题,服务停止了一段时间后在logcat中没有消息:(在应用程序管理中的我的android设备上,我可以看到我的应用程序处于重新启动状态,经过很长的键入后,它会重新启动,然后又一次又一次地停止。

安德烈·卡蒂南(Andrei Catinean)

您是否已阅读https://developer.android.com/reference/android/app/Service.html

请注意以下几点:

对于已启动的服务,它们可以决定运行在其上的两种其他主要操作模式,具体取决于它们从onStartCommand()返回的值:START_STICKY用于根据需要显式启动和停止的服务,而START_NOT_STICKY或START_REDELIVER_INTENT用于对于仅在处理发送给它们的命令时仍保持运行状态的服务。

START_STICKY文档中:

从onStartCommand(Intent,int,int)返回的常量:如果此服务的进程在启动时被杀死(从onStartCommand(Intent,int,int)返回之后),则将其保留为启动状态,但不保留此状态传达了意图。稍后,系统将尝试重新创建服务。因为它处于启动状态,所以将保证在创建新服务实例后调用onStartCommand(Intent,int,int);如果没有任何待处理的启动命令要传递给服务,则将使用空意图对象调用该命令,因此您必须注意进行检查。

对于在任意时间段内将明确启动和停止运行的事物(例如执行背景音乐播放的服务),此模式很有意义。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

使用任务管理器关闭应用程序时停止Android服务

打开应用程序时,Android TimerTask关闭

退出应用程序时Android停止服务

当用户在 Android 中关闭应用程序时如何重新启动应用程序

在销毁应用程序时停止服务

按后退按钮关闭后重新打开应用程序时的空白活动或片段

关闭并重新打开应用程序时如何在 iOS 上保持 Firebase 连接?

应用程序关闭时,Android服务停止

Android服务-应用程序关闭后无法停止

停止服务并关闭应用程序

注册打开和关闭 android 应用程序

停止应用程序时停止服务的顺序是什么

打开应用程序时发生强制关闭

关闭应用程序时单击通知按钮打开活动

Android Studio (Kotlin) - 每次关闭应用程序时,用户都必须重新登录应用程序

关闭应用程序时如何停止音乐

我的Android服务并非一直都在运行。当我重新打开应用程序时,它熄灭。实施我的服务的正确方法是什么?

重新打开应用程序时获取AsyncTask状态

重新打开应用程序时,Swift Admob隐藏

Android:过一会儿重新打开应用程序时,无法解释的崩溃

重新打开android应用程序时,从最后一个计数器继续

如何让 React Native Expo 应用程序自行关闭,并在用户下次打开应用程序时重新打开?

通过在android中滑动删除应用程序时关闭服务

Android应用程序关闭但未打开

关闭后停止处理程序,然后在Android中打开应用程序

在安装应用程序时停止SQL Server服务

从最近删除应用程序时停止后台服务

再次运行应用程序时如何停止关闭的应用程序留下的线程?C#

关闭应用程序,然后重新打开继续阅读文本