【问题标题】:Android Intent Service work requests running parallelyAndroid Intent Service 工作请求并行运行
【发布时间】:2017-02-14 10:03:13
【问题描述】:

我创建了一个 IntentService 如下:

    public class OrdersSyncService extends IntentService {

    private static final String TAG = OrdersSyncService.class.getSimpleName();

    private Order orderObject;

    public OrdersSyncService() {
        super("OrdersSyncService");
    }

    @Override
    protected void onHandleIntent(Intent intent) {

        //Util.showToast(getApplicationContext(), "Syncing Orders........");
        Log.d(TAG, "I'm running....");
        syncOrders();
    }

    private void syncOrders() {

        Database database = CouchBaseHelper.openCouchBaseDB(this);
        JSONArray ordersJsonArray = new JSONArray(CouchBaseHelper.retrieveNotSyncedOrders(database));
        if (ordersJsonArray.length() != 0) {
            uploadOrders(ordersJsonArray.toString());
            Log.d(TAG, "Orders syncing started.");
        } else {
            Log.d(TAG, "Nothing to sync.");
        }
    }

    private void uploadOrders(String ordersJsonArray) {

        RetrofitApi.ApiInterface apiInterface = RetrofitApi.getApiInterfaceInstance();
        final Call<Order> uploadOrders = apiInterface.uploadOrders(
                ordersJsonArray,
                Util.getDeviceId(this),
                AppPreference.getString(this, AppPreference.USER_ID)
        );

        uploadOrders.enqueue(new Callback<Order>() {
            @Override
            public void onResponse(Call<Order> call, Response<Order> response) {

                if (response.isSuccessful()) {

                    if (response.body().getStatus().equals("success")) {

                        orderObject = response.body();

                        Log.d(TAG, "Server Response : " + orderObject.getMobileOrderIds());

                        boolean flag = updateOrders(orderObject);

                        if (flag) {
                            Log.d(TAG, "Orders Synced And Updated.");
                            EventBus.getDefault().post(new SyncFinished(true));

                        } else {
                            Log.d(TAG, "Orders Synced But Update Failed.");
                        }

                    } else {

                        Log.d(TAG, response.body().getMessage());

                    }

                } else {

                    Log.d(TAG, "Some Error. Sync Failed.");

                }

            }

            @Override
            public void onFailure(Call<Order> call, Throwable t) {
                Log.d(TAG, "Network problem. Sync Failed.");
                //Log.d("VICKY",call.request().url().toString());

            }
        });
    }

    private boolean updateOrders(Order order) {
        Database database = CouchBaseHelper.openCouchBaseDB(this);
        boolean flag = CouchBaseHelper.updateOrders(database, order);
        return flag;
    }
}

它的作用是,它发出一个网络请求,并在网络请求之后用响应更新数据库(我正在使用 couchbaselite for android)。现在的问题是当我向它发出多个请求时它会并行执行。 android文档明确指出: Creating a Background Service

工作请求按顺序运行。如果一个操作正在 IntentService 中运行,并且您向它发送另一个请求,则该请求将一直等待,直到第一个操作完成。

我从 Activity 的 onResume 方法调用此服务。因此,每当活动恢复时,都会调用此服务:

@Override
protected void onResume() {

    super.onResume();

    Intent ordersSyncServiceIntent = new Intent(SellerHomeActivity.this, OrdersSyncService.class);
    startService(ordersSyncServiceIntent);

}

我不知道问题是什么。我认为这与我用来发出异步网络请求的Retrofit 库有关。请帮忙。

【问题讨论】:

    标签: android retrofit retrofit2 android-intentservice


    【解决方案1】:

    您在这一行中异步执行此操作:

    uploadOrders.enqueue(new Callback<Order>() {...});
    

    使用execute() 方法同步进行。

    【讨论】:

    • 好的,我知道我是异步执行的,但究竟是什么导致我的 IntentService 并行运行?你能详细说明一下吗?
    • @Vicky,您正在 IntentService 的另一个线程中生成您的工作。 IntentService 运行,假设是线程 4,并且您正在线程上运行网络调用,假设是 6。因此,您不使用 IntentService 类。在这种情况下,您可以使用服务。
    • @azizbekian,我明白你的意思,我正在 IntentService 中创建另一个线程,但是来自 RetrofitCallback 应该在 IntentService 线程上执行,对吧?
    • enqueue 在执行此操作的线程上运行您的回调,但实际的 http 请求发生在 Retrofit 为您创建的另一个线程上。您必须执行 uploadOrders.execute() 才能在此线程上运行此请求。
    • 我从改造文档中得到这个:` public interface Callback 通信来自服务器或离线请求的响应。响应给定请求,将调用一种且只有一种方法。回调方法使用 Retrofit 回调执行器执行。如果没有指定,则使用以下默认值: Android:在应用程序的主 (UI) 线程上执行回调。 JVM:回调在执行请求的后台线程上执行。 ` 这是什么意思?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-17
    • 2020-11-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多