当应用程序被重新打开和关闭的Android服务站(Android service stop when

2019-10-20 10:24发布

我试图了解服务是如何工作的机器人。

所以,我创建了一个活动和服务的简单应用,还有就是代码:

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)打开应用程序,在开始按钮来启动服务,并与其他阻止它。 和一切OK 2)打开应用程序,启动服务并关闭应用程序。 和一切OK(服务仍在运行中)3)打开应用程序,推出的服务,重新打开应用程序并获取计数器值。 和所有OK 4)打开应用程序,推出的服务,关闭应用程序,重新打开应用程序,并停止该服务。 和一切OK了(也重新启动该服务结束后)的问题出现时,我打开,启动服务,关闭应用程序,重新检查柜台号码,然后再次关闭该应用程序,一段时间后,在logcat中没有消息服务停止:(在我的应用程序管理Android设备,我可以看到我的应用程序在重新启动状态和很长的类型后,它的重新启动,然后再次停止,并在....我在三星Galaxy Express库存测试(安卓4.1.2 )和三星Galaxy标签2 10.1用的CyanogenMod 10.1.3(机器人4.2.2)

Answer 1:

你必须通过阅读https://developer.android.com/reference/android/app/Service.html ?

请注意以下几点:

对于启动的服务,也有操作的,他们可以决定在运行,这取决于他们从onStartCommand()返回值的两个附加的主要模式:START_STICKY用于显式启动和停止需要的服务,而START_NOT_STICKY或START_REDELIVER_INTENT使用一种新的服务应该只停留在处理发送给他们的任何命令运行。

START_STICKY文档:

恒从onStartCommand(意向,INT,INT)返回:,然后把它留在启动状态,但不保留这个(从onStartCommand返回(意向,INT,INT)之后),如果同时启动该服务的过程中被杀害交付意图。 后来,系统将尝试重新创建服务。 因为它是在启动的状态,这将保证在创建新的服务实例之后调用onStartCommand(意向,INT,INT); 如果没有任何悬而未决的启动命令都被传递到服务,它将与一个空的意图对象被调用,所以你必须小心检查此。

这种模式是有道理的,将被明确地启动和停止为任意时间周期,如服务执行后台音乐播放功能运行的东西。



文章来源: Android service stop when application is reopened and closed