1

这些天我正在学习服务,只是围绕它进行试验,我无意制作音乐播放器,只是想了解服务是如何工作的。所以让我解释一下我在做什么。

我的应用程序有一个Activity和一个Service扩展Service类,我在其中

@Override
public void onCreate()
{
    mediaPlayer=MediaPlayer.create(this,R.raw.serenity);
}
@Override
public int onStartCommand(Intent intent, int flags, int startId)
{
    mediaPlayer.start();
    return 0;
}

在我的MainActivity课堂上,我开始Service在主线程上

startService(intent);

而且我还添加了属性

<service
        android:name=".MusicService"
        android:process=":music"/>

在另一个进程中运行服务。现在我想说的是,当我使用活动类上的按钮启动服务时,服务会开始播放音乐,尽管当我按下后退按钮时,活动会破坏并且音乐仍然会播放,是的,这是我想要的,但是当我从最近删除此应用程序时然后音乐停止并从头开始。请告诉我为什么会这样。我不想让音乐停止我希望它只播放独立于应用程序的活动或进程。

4

2 回答 2

2

如果服务当前正在其 onCreate()、onStartCommand() 或 onDestroy() 方法中执行代码,则托管进程将是前台进程,以确保此代码可以在不被杀死的情况下执行。

看:

https://developer.android.com/reference/android/app/Service.html#ServiceLifecycle

我知道这件事,但我的问题是,尽管正如您所说的执行 onStartCommand() 是一个前台进程,但当我从最近的服务中清除应用程序时,它会停止,它会停止一次并从头开始重新启动。– Dushyant Suthar 14 小时前

    • 返回 START_STICKY因为您想在关闭/崩溃时重新创建服务
    • 并使用startForeground(int,Notification);

如图所示:

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
         // log start
        logger.info(getServiceName(), " Service: start id " + startId + ": " + intent);
        /** set foreground */
        setForeground();
        /** run until explicitly stopped. */
        return START_STICKY;
    }


    private setForeground() {
        Intent intent = new Intent(this, NotStickyActivity.class);
        intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
        PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, 0);
        Notification noti = new, Notification.Builder(getApplicationContext())
              .setContentTitle("Pratikk")
              .setContentText("Subject")
              .setSmallIcon(R.drawable.ic_launcher)
              .setContentIntent(pendingIntent)
              .build();

       startForeground(1234, noti);     
    }
    • 不要在清单中启用服务
    • 通过代码启动服务并使用基本上下文(不是活动 - 因为您将获得泄漏服务的异常)
    • 您还可以提供活页夹并绑定到活动中的服务

示例启用/启动:

     /**
     * This method enables the Component (Receiver/Service) registered i
     * n the AndroidManifest file.
     */
     public static void enableComponent(Context context, Class<?> componentClass) {
        getLogger().debug("Enabling component {} request from {}", componentClass.getName(), StackTraceInfo.getInvokingClassName());

        ComponentName receiver;
        receiver = new ComponentName(context, componentClass);
        PackageManager pm = context.getPackageManager();

        pm.setComponentEnabledSetting(receiver,
                PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
                PackageManager.DONT_KILL_APP);
    }

     /**
    * start a service
    *
    * @param context      - context to start service
    * @param serviceClass - service class to start
    * @return If the service is being started or is already running, the
    * {@link ComponentName} of the actual service that was started is
    * returned; else if the service does not exist null is returned.
    */
    public static ComponentName startService(Context context, Class<?> serviceClass) {
        getLogger().info("Starting service {} by {}", serviceClass.getName(), StackTraceInfo.getInvokingClassName());
        Intent serviceIntent = new Intent(context, serviceClass);
        return context.startService(serviceIntent);
    }

是的,兄弟,我设法使我的服务处于前台以便问题得到解决,但是正如你所说的那样,文档也说,当系统执行 onStartCommand() 时,它被视为前台,但正如你所知,当我从最近清除它时然后它被杀死了。我不明白系统将其视为前台和我们将其设置为前台之间的区别,这两者之间的行为为何不同。– 杜希扬特·苏塔尔

前台服务是一种被认为是用户主动意识到的服务,因此不会在内存不足时被系统杀死。

前台服务必须为状态栏提供通知,该通知位于“正在进行”标题下,这意味着除非服务停止或从前台删除,否则无法解除通知。

于 2016-06-18T17:09:08.407 回答
0

为了让你的服​​务更稳定,你应该创建一个前台服务。每次您的主进程停止时,这不会终止服务。我遇到了类似的问题,当我停止主进程时,我的进程曾经被杀死并重新启动。为了避免这种情况,我使用了前台服务。下面的链接将让您轻松实现和理解前台进程。希望这可以帮助。 Android-前台服务示例

于 2016-06-18T17:46:40.243 回答