【问题标题】:Android prevent service from being killed by application managerAndroid防止服务被应用程序管理器杀死
【发布时间】:2017-01-03 21:31:48
【问题描述】:

目前我正试图防止我的服务被应用程序管理器杀死。每次我刷应用程序时,服务也会被杀死。

我尝试过的是 1. 使用 START_STICKY

public int onStartCommand(Intent intent, int flags, int startId) {

Log.d(TAG, "onStartCommand started");



        if(!isRunning){
            mythread.start();
            isRunning = true;
        }
   return START_STICKY;
} 

在此示例中,我的线程每五秒显示一次 toast。

我还创建了一个广播接收器,并给了一个服务单独的进程

<service android:name="com.example.asd.mainhub.GPSTracker"
                 android:process=":my_process"
                 android:enabled="true" />

        <receiver android:name="com.example.asd.mainhub.BootCompletedIntentReceiver">
            <intent-filter>
                <action android:name="android.intent.action.BOOT_COMPLETED" />
                <action android:name="android.intent.action.USER_PRESENT" />
                <action android:name="android.intent.action.PACKAGE_RESTARTED" />
                <action android:name="com.example.asd.mainhub.BootCompletedIntentReceiver" />
            </intent-filter>
        </receiver>

服务的 onDestroy() 方法,它将使用广播接收器来恢复我的服务,没有工作。

public void onDestroy() {

Intent intent = new Intent("com.example.asd.mainhub.BootCompletedIntentReceiver");
intent.putExtra("yourvalue", "torestore");
sendBroadcast(intent);

}

MainActivity,调用我的服务 onCreate()

    gps = new GPSTracker();
    mServiceIntent = new Intent(this, gps.getClass());

    if (!isMyServiceRunning(gps.getClass())) {

        startService(mServiceIntent);
    }

我也尝试过使用通知和前台 onCreate() 服务:

Intent notificationIntent = new Intent(this, MainActivity.class);

PendingIntent pendingIntent = PendingIntent.getActivity(this, 0,
        notificationIntent, 0);

Notification notification = new NotificationCompat.Builder(this)
        .setSmallIcon(R.mipmap.ic_launcher)
        .setContentTitle("My Awesome App")
        .setContentText("Doing some work...")
        .setContentIntent(pendingIntent).build();

startForeground(1337, notification);

还是一样,每次我交换我的应用程序时,服务也会停止,不再显示 Toast。在我的控制台中,最后的消息是: I/MAINACT:onDestroy! 应用程序终止。 似乎甚至没有调用服务 onDestroy() 方法。请提出一些建议,我该如何解决。

顺便说一句,我将应用程序安装为系统应用程序,它会解决问题吗?

编辑1:

private final class ServiceHandler extends Handler {
        public ServiceHandler(Looper looper) {
            super(looper);
        }
        @Override
        public void handleMessage(Message msg) {
            // Normally we would do some work here, like download a file.
            // For our sample, we just sleep for 5 seconds.
//            try {
//                Thread.sleep(5000);
//            } catch (InterruptedException e) {
//                // Restore interrupt status.
//                Thread.currentThread().interrupt();
//            }

            while(isRunning){
                Log.d(TAG,"Running");

                try {
                    postToastMessage("Toast from Service");
                    Thread.sleep(DELAY);

                } catch (InterruptedException e) {
                    isRunning = false;
                    e.printStackTrace();
                }
            }
            // Stop the service using the startId, so that we don't stop
            // the service in the middle of handling another job
            //stopSelf(msg.arg1);
        }
    }

    public void postToastMessage(final String message) {
        Handler handler = new Handler(Looper.getMainLooper());

        handler.post(new Runnable() {

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

    static final long DELAY = 5000;

编辑 2:

HelloService service = new HelloService();

protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

Intent intent = new Intent(this, service.getClass());

        if (!isMyServiceRunning(service.getClass())) {

            //startService(mServiceIntent);
            startService(intent);
        }

【问题讨论】:

  • "I'm trying to prevent my service from being killed [...] ",你不能那样做,不可能完成任务
  • 你能解释一下为什么吗?尽管我的应用程序打开或关闭,创建系统服务之类的东西是不可能的吗?
  • 为什么有很多关于这个主题的文章和教程,人们都说它有效
  • 为什么?你想运行一些你无法杀死的恶意服务吗?我不会
  • 如果"alot of articles and tutorials" 说有可能,那就关注他们

标签: android android-studio android-service


【解决方案1】:

使用意图服务而不是服务,它在工作线程而不是主线程上运行。所以当应用程序从任务管理器中删除时会继续运行。

【讨论】:

  • IntentServices 用于单一的即发即弃的事情,而不是用于长时间运行的任务
  • 你可以传递任务队列,或者重新启动服务而不检查它是否运行。
【解决方案2】:

您正在寻找的是Services。最推荐您阅读 Android Studio here 的文档。

服务将允许您的应用程序的特定部分始终存在。即使用户重新启动他们的设备并且不再运行您的应用程序。关于服务有很多需要了解的地方,但目前我相信 sn-p 对您最有帮助,这里有一些代码,

清单中的第一个

    <!--notification-->
    <service android:name="services.HelloService"
        android:exported="false"
        android:description="My notification Center"/>
    <!--notification-->

第二

创建一个名为 HelloService 的类

并将以下代码粘贴到正确的导入中*

public class HelloService extends Service {
private Looper mServiceLooper;
private ServiceHandler mServiceHandler;

// Handler that receives messages from the thread
 private final class ServiceHandler extends Handler {
  public ServiceHandler(Looper looper) {
      super(looper);
  }
  @Override
  public void handleMessage(Message msg) {
      // Normally we would do some work here, like download a file.
      // For our sample, we just sleep for 5 seconds.
      try {
          Thread.sleep(5000);
      } catch (InterruptedException e) {
          // Restore interrupt status.
          Thread.currentThread().interrupt();
      }
      // Stop the service using the startId, so that we don't stop
      // the service in the middle of handling another job
      stopSelf(msg.arg1);
  }
}

@Override
public void onCreate() {
// Start up the thread running the service.  Note that we create a
// separate thread because the service normally runs in the process's
// main thread, which we don't want to block.  We also make it
// background priority so CPU-intensive work will not disrupt our UI.
HandlerThread thread = new HandlerThread("ServiceStartArguments",
        Process.THREAD_PRIORITY_BACKGROUND);
thread.start();

// Get the HandlerThread's Looper and use it for our Handler
mServiceLooper = thread.getLooper();
mServiceHandler = new ServiceHandler(mServiceLooper);
  }

  @Override
   public int onStartCommand(Intent intent, int flags, int startId) {
   Toast.makeText(this, "servicestarting",Toast.LENGTH_SHORT).show();


  Message msg = mServiceHandler.obtainMessage();
  msg.arg1 = startId;
  mServiceHandler.sendMessage(msg);

  // If we get killed, after returning from here, restart
  return START_STICKY;
      }

@Override
public IBinder onBind(Intent intent) {
   // We don't provide binding, so return null
   return null;
          }


 @Override
 public void onDestroy() {
   Toast.makeText(this, "service done", Toast.LENGTH_SHORT).show();
 }
}

现在,在“handleMessage 方法”中添加您的代码,例如;

  @Override
public void handleMessage(Message msg) {

 //... your bit of code goes here 

试试{ 线程.sleep(5000);

         // make a toast appears here 

  } catch (InterruptedException e) {
      // Restore interrupt status.
      Thread.currentThread().interrupt();
  }
    //stopSelf(msg.arg1);  //... kill the service in your condition
}

最后,激活服务类,在你的触发服务的函数中,首先导入HelloService.class,然后创建一个Intent并启动!

 Intent intent = new Intent(this, HelloService.class);
 startActivity(intent)

【讨论】:

  • 一会儿我会试试你的代码,但是使用你的方法是否可以在服务中做一个恒定的任务,比如发送 http get 请求?
  • 准确地说,例如,您可以先检查网络是否可用,然后继续执行您的 http 请求。
  • 我试过使用你的代码,但还是一样。生病写了 EDIT1 来显示我申请的内容,每次我杀死我的应用程序服务都会停止并且不再敬酒
  • 我忘了提到如何激活服​​务,在你想要的函数中触发所有这个第一个导入 services.HelloService;然后启动以下活动 Intent intent = new Intent(this, HelloService.class);
  • Intent intent = new Intent(this, HelloService.class); if (!isMyServiceRunning(gps.getClass())) { //startService(mServiceIntent);启动服务(意图); } 像这样?
猜你喜欢
  • 2011-02-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-18
  • 1970-01-01
  • 2018-03-18
相关资源
最近更新 更多