【问题标题】:how to call method after 2 minutes in background如何在后台 2 分钟后调用方法
【发布时间】:2018-06-27 04:52:10
【问题描述】:

我需要在 2 分钟后调用一个方法。我已经尝试过处理程序和计时器,但是当应用程序关闭时它不起作用。然后我在服务中有呼叫计时器并在按钮单击时启动服务并在 2 分钟后停止服务。它可以工作,但问题是有时服务会调用自己。下面是我的代码。

我的服务类

public class MyService extends Service {

private static Retrofit retrofit = null;

@Override
public IBinder onBind(Intent intent) {
    throw new UnsupportedOperationException("Not yet implemented");
}

@Override
public void onCreate() {
    new CountDownTimer(120000, 1000) {
        public void onTick(long millisUntilFinished) {
            Log.d("message", "start");
        }
        public void onFinish() {
            Log.d("message", "finish");

            callMyMethod();
            stopService(new Intent(MyService.this, MainActivity.class));
        }
    }.start();
}

我开始服务的 MainActivity 类。

stopService(new Intent(getContext(), MyService.class));
startService(new Intent(getContext(), MyService.class));

清单

<service android:name="MyService" android:enabled="true" android:exported="true"/>

注意:我只想在按钮单击时调用服务并在 2 分钟后停止服务。 请需要帮助来解决这个问题,或者如果除了服务之外还有其他好的解决方案。

更新:如果网络响应不成功,我该如何处理重试。

我的服务类

public class MyService extends Service {

private static Retrofit retrofit = null;

@Override
public IBinder onBind(Intent intent) {
    throw new UnsupportedOperationException("Not yet implemented");
}

@Override
public void onCreate() {
    new CountDownTimer(120000, 1000) {
        public void onTick(long millisUntilFinished) {
            Log.d("mess", "start");
        }
        public void onFinish() {
            Log.d("mess", "finish");

            selectDriverForJOb();
            stopSelf();//(new Intent(MyService.this, MainActivity.class));
        }
    }.start();
}

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
     return START_NOT_STICKY;
}

private void selectDriverForJOb() {
    SharedPreferences sharedPreferences = getSharedPreferences("Login_credentials", MODE_PRIVATE);
    String user_id = sharedPreferences.getString("userID", null);
    if (retrofit == null) {
        retrofit = new Retrofit.Builder()
                .baseUrl(BASE_URL)
                .addConverterFactory(GsonConverterFactory.create())
                .build();
    }
    APIServices_interface selectDriver_interface = retrofit.create(APIServices_interface.class);
    Call<SelectDriverforJobResult> call = null;
    try {
        call = selectDriver_interface.selectDriverforJob(user_id);
    } catch (Exception e) {
        e.printStackTrace();
    }
    if (call != null) {
        try {
            call.enqueue(new Callback<SelectDriverforJobResult>() {
                @Override
                public void onResponse(Call<SelectDriverforJobResult> call, Response<SelectDriverforJobResult> response) {
                    SelectDriverforJobResult selectDriver = response.body();
                    String message = selectDriver.getMessage();
                    if(!(message.equalsIgnoreCase("success"))){

                    }
                }

                @Override
                public void onFailure(Call<SelectDriverforJobResult> call, Throwable t) {
                    Log.d("mess : ", "Error Updating ");
                    //want to retry
                }
            });
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
}

【问题讨论】:

  • 使用异步任务在异步任务中使用处理程序或倒计时
  • @Nilesh Rathod 它不重复。我已经检查过这个问题。这并没有解决我的问题。
  • @VinodMaurya 在按钮单击时从主要活动调用服务。
  • 如果用户第一次点击按钮并且服务启动并关闭应用程序怎么办? 2分钟后你还需要执行任务吗?
  • 好的!所以服务不是这种情况的解决方案,正如我在下面的答案中已经提到的那样。这显然是AlarmManagerJobShedular 的用例。由于您需要 Internet 连接,因此最好使用JobShedular。你可以试试WorkManager,它是JobShedular 的一个包装器,适用于所有操作系统版本。

标签: java android service


【解决方案1】:

在服务中覆盖onStartCommand并返回START_NOT_STICKY它不会重新启动

public void onStartCommand()
{
     return START_NOT_STICKY
}

并使用stopSelf() insted of stopService(new Intent(getContext(), MyService.class));

【讨论】:

  • 我已经更新了我的代码。请立即检查。服务器响应失败时如何处理。
  • 如果它解决了您的问题,请接受答案@AsifUllah
【解决方案2】:

应用关闭后您的服务将不会运行,请阅读background restriction。 这并不是真正的 Service 用例。

解决您的问题的方法是 AlarmManager 。设置 2 分钟后准确的警报,您的接收器将在触发时被调用。在使用AlarmManger 之前,请阅读setExactAndAllowWhileIdle()setExact()

或者,您也可以使用 WorkManager 设置 Exact Job 。但是,如果您不需要Job Constraints,这将是一种矫枉过正。因此,如果您的工作不依赖于网络连接或其他任何约束,您可以使用AlarmManger

PS:- 如果您的任务依赖于网络连接,那么您应该使用WorkManager。阅读Schedule tasks with WorkManager

【讨论】:

  • 是的,我在我的方法中发出网络请求。我正在检索一条消息作为响应。如果响应为“成功”,我想停止服务,或者如果响应不成功,我想再次发送请求。请您编辑我的代码如何使用 WorkManager?
  • how to use WorkManager? 可以是一个非常广泛的答案。您应该通过上面的链接并遵循一些教程Sample。使用和理解它并不难,只需通过示例即可。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-09-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多