【问题标题】:Android: Service restarts after app gets startedAndroid:应用程序启动后服务重新启动
【发布时间】:2017-08-30 15:55:24
【问题描述】:

我正在努力实现,我的服务会在后台下载信息并使用该信息填充数据库。

解决方案(使用前台服务,代码现在是编辑版本)

这就是服务:

public class UnitPullService extends Service {
    private final static String name = UnitPullService.class.getSimpleName();
    public static Boolean isRunning = false;
    private Looper mServiceLooper;
    private ServiceHandler mServiceHandler;

    private final class ServiceHandler extends Handler {
        public ServiceHandler(Looper looper) {
            super(looper);
        }

        @Override
        public void handleMessage(Message msg) {
            try {
                UnitDataSource unitdataSource = new UnitDataSource(getApplicationContext());
                unitdataSource.fillTables();
                SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
                SharedPreferences.Editor spEitor = sharedPreferences.edit();
                // disables the button which starts this service
                spEitor.putBoolean("isFilled", true);
                spEitor.commit();
            } catch (JSONException e) {
                e.printStackTrace();
            }
            stopSelf(msg.arg1);
        }
    }

    @Override
    public void onCreate() {
        HandlerThread thread = new HandlerThread("ServiceStartArguments",
            Process.THREAD_PRIORITY_BACKGROUND);
        thread.start();

        mServiceLooper = thread.getLooper();
        mServiceHandler = new ServiceHandler(mServiceLooper);
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        // PART OF THE SOLUTION
        startForeground(1000, new Notification());

        Toast.makeText(this, "service starting", 
           Toast.LENGTH_SHORT).show();
        // to check if the service is currently running
        isRunning = true;
        Message msg = mServiceHandler.obtainMessage();
        msg.arg1 = startId;
        mServiceHandler.sendMessage(msg);

        return START_REDELIVER_INTENT;
    }

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

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

这就是活动中的意图(实际上来自片段):

 Intent i= new Intent(getContext(), UnitPullService.class);
 getContext().startService(i);

在清单中,服务声明如下:

<service
  android:name=".UnitPullService"
  android:exported="false"/>

关键是,我想做整个“下载和数据库填充”——完全独立于启动服务的应用程序的状态(以便用户可以在服务执行时使用其他应用程序)工作)。

编辑(做出错误假设)

以下行为很奇怪:

  1. 开始申请
  2. 启动服务
  3. 关闭应用程序(从 running-apps-overview 滑开)
  4. 服务完成之前启动应用程序
  5. “服务启动”-toast 出现,handleMessage() 被调用并且 DatabaseErros 发生(因为独特的约束,但这不是重点)。

另一种情况:

  1. 开始申请
  2. 启动服务
  3. 关闭应用程序(从 running-apps-overview 滑开)
  4. fillTables() 已完成。
  5. 似乎直接 fillTables() 完成并重新启动服务(Toast 出现)之后。

Q1:那么我的错在哪里,当我启动应用程序而正在运行的服务尚未完成时,正在运行的服务将重新启动?

Q1.1:我如何调用/创建一个完全独立的服务,它在工作时不会以如此讨厌的方式重新启动?

【问题讨论】:

    标签: android service background restart foreground


    【解决方案1】:

    刷掉应用程序会将其置于强制关闭状态。这会杀死任何附加到它的服务。在用户启动之前,它不会允许应用程序中的服务或任何其他活动再次运行。

    现在,如果用户没有滑开,无论前台是什么应用程序,您的服务都将继续运行。如果该服务被操作系统杀死以获取资源,您可以让它在可用时自动重新启动。但是被刷掉后没有什么可以让它运行服务。

    【讨论】:

    • >刷掉应用程序使其进入强制关闭状态。这会杀死与之相关的任何服务。onStartCommand() 中的return START_REDELIVER_INTENT; 的意义,而不是在应用程序关闭时终止服务。 >但没有什么能让它在被刷掉后运行服务。
    • 不,start_redeliver_intent 的目的是在操作系统停止它时重新启动它,而不是如果用户停止它。用户关闭应用后,您无法重新启动或继续运行。
    • 再一次。当用户关闭应用程序时,服务不会停止。当服务当前正在运行并且用户再次启动之前关闭的应用时,服务会再次启动。
    • @Nico 你错了。当用户强制关闭应用程序时,所有服务都会关闭。
    • 好吧,看来我做了一些错误的假设,因为 fillTables() 需要时间并且缺少日志输出。我已经编辑了原始帖子。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-03-08
    • 1970-01-01
    • 1970-01-01
    • 2012-06-12
    • 1970-01-01
    • 1970-01-01
    • 2011-04-21
    相关资源
    最近更新 更多