Невозможно реализовать обратный вызов в Android

Я создаю SDK.

Сценарий

  • Из приложения разработчик передает JsonObject и URL-адрес в метод и внутри SDK.
  • Я добавляю эти значения в базу данных SQLite и запускаю JobScheduler.
  • Jobscheduler берет запрос с индексами 0 из базы данных и выполняет его.
  • Когда я получаю ответ, я удаляю этот запрос из базы данных, и теперь запрос с индексом 1 приходит к индексу 0, и снова я выполняю тот же код, где запускается запрос с индексом 0.

Проблема

  • Когда я получаю ответ от сервера внутри SDK, мне нужно отправить его разработчику с помощью обратного вызова.
  • Я могу принять обратный вызов в качестве аргумента, когда я беру JSON и URL-адрес от пользователя, но я не знаю, как действовать дальше, потому что я не могу сохранить его в базе данных.
  • Предположим, у меня есть 5 запросов в базе данных, и планировщик выполняет их один за другим, я не знаю, как отправить ответ обратно разработчику. Я не могу передать контекст в планировщик заданий. Единственный способ сделать это — получить соответствующий контекст для каждой строки (запроса) в базе данных.

Что я пробовал

  • Я пытался использовать LocalBroadcastManager, но не могу создать универсальный класс и реализовать его метод onreceive(), а также проблема с передачей контекста.
  • Пытался использовать Realm в качестве базы данных, чтобы добавить тип контекста и использовать свою модель, но это не работает, поскольку контекст не поддерживается.
  • Сохранение имени действия в базе данных с другими деталями, а затем вытеснение из него класса и действия из класса. А затем приведение активности в мой обратный вызов. но выдает ClassCastException, поскольку класс, который он пытается получить из имени, находится в приложении разработчика, а не в моем SDK

..

Код MainActivity приложения

sdkClass.queueRequest(jo.toString(),"url1",12,"MainActivity");

sdkClass.queueRequest(jo2.toString(),"url2",13,"MainActivity");

sdkClass.queueRequest(jo.toString(),"url3",14,"MainActivity");

sdkClass.executeQueue();

Класс SDK, который добавляет и выполняет код

public void queueRequest(String payload, String URL, int requestId, String identifier){
    RequestsDatabase database = new RequestsDatabase(context);
    database.insertItem(TxnType,payload,url, String.valueOf(requestId), identifier);
}


public JobScheduler getQueueInstance(Context context){

    if(jobScheduler==null){
        jobScheduler = (JobScheduler)context.getSystemService(JOB_SCHEDULER_SERVICE);
    }
    return jobScheduler;
}
public void executeQueue(){
    getQueueInstance(context);
    ComponentName jobService = new ComponentName(context.getPackageName(), MyJobService.class.getName());
    JobInfo jobInfo = new JobInfo.Builder(1,jobService).setPersisted(true).setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY). build();
    jobScheduler.schedule(jobInfo);
}

МойJobServiceCode

@Override
public boolean onStartJob(JobParameters params) {

    // UtilityMethods.showToast(this,params.getExtras().getString("json"));
    Toast.makeText(this,"test", Toast.LENGTH_SHORT).show();
    database = RequestsDatabase.getInstance(this);
    ALlRequests = database.getAllItemId();
    executeCall();

    return false;
}
public void executeCall(){
    ALlRequests = database.getAllItemId();
    if(ALlRequests.size()>0) {
        requestModel = ALlRequests.get(0);

        try {
            String payload = getPayload(this, requestModel.getTxnType(), requestModel.getPayload());
            SilverLineRequest req = new SilverLineRequest(this, requestModel.getUrl(), payload, Integer.parseInt(requestModel.getRequestId()), this);
            req.executeToServer();
            Toast.makeText(getApplicationContext(), "requested", Toast.LENGTH_LONG).show();
        } catch (JSONException e) {
            e.printStackTrace();
        }
    }
    else{
        Toast.makeText(this, "Queue empty", Toast.LENGTH_LONG).show();
    }

}
@Override
public void onSuccess(String response, int requestId) {
    if(requestId ==Integer.parseInt(requestModel.getRequestId())){
        Toast.makeText(this,"responded", Toast.LENGTH_SHORT).show();
        database.deleteItem(requestModel.getTxnType());

        // HERE I WANT TO SEND THE USER RESPONSE LIKE
        // listener.onTransactionSuccess(response)
        // BUT I DON'T HAVE 'listener' SO IT SHOWS NULLPOINTER


        SDKClass sl = new SDKClass(this);
        sl.executeQueue();
    }
}

Любая помощь будет благословлена ​​прямо сейчас.


person The Bat    schedule 18.07.2017    source источник
comment
Почему вы храните в базе данных то, что не хотите хранить? Почему бы не сохранить их в памяти? (я имею в виду ожидающие запросы)   -  person Eselfar    schedule 18.07.2017
comment
@Eselfar Потому что, если во время любого щелчка отправки интернета нет, я позволяю пользователю продолжить, я сохраняю его запрос в базе данных и запускаю планировщик заданий. Поэтому всякий раз, когда приходит интернет, он выполняется. Планировщик заданий позаботится о сохранении, даже если приложение будет убито или телефон будет перезагружен. Так что это своего рода механизм очереди, который я поддерживаю.   -  person The Bat    schedule 18.07.2017
comment
Так что в этом случае я думаю, вы можете использовать PendingIntent.   -  person Eselfar    schedule 18.07.2017
comment
@Eselfar, не могли бы вы немного объяснить, чтобы я мог продолжить? спасибо   -  person The Bat    schedule 18.07.2017
comment
Плохо, что ты не можешь использовать это. Но что вы можете сделать, так это использовать широковещательное намерение. Затем другое приложение должно будет зарегистрировать приемник широковещательной рассылки. stackoverflow.com/a/33611355/1827254   -  person Eselfar    schedule 18.07.2017
comment
@Eselfar да, зарегистрируйтесь и напишите класс расширения BroadcastReceiver, который должен реализовать метод onReceive() ... Я не хочу, чтобы пользователь выполнял такой объем работы. SDK должен делать это. Это действительно хорошая идея, но если вы можете придумать какое-либо другое решение, оно будет лучше :)   -  person The Bat    schedule 18.07.2017
comment
Если вы хотите иметь возможность разбудить приложение так, как вы хотите, чтобы ваша система работала, даже если устройство было перезагружено, решений не так много. Но что именно вы хотите вернуть своему пользователю?   -  person Eselfar    schedule 18.07.2017
comment
@Eselfar String Response, который вы можете видеть в коде JobService onSuccess()   -  person The Bat    schedule 18.07.2017


Ответы (1)


Вы храните запросы в базе данных, поэтому они могут иметь уникальный идентификатор (автоинкремент). Затем вы можете хранить обратные вызовы в памяти с идентификатором запроса отношения -> обратный вызов. В ответ вы можете позвонить ему.

Если хотите, верните id разработчикам. Затем они могут связать и развязать и получить результаты, когда им нужно, даже если ответ был получен вчера.

Взгляните на TransferUtility из SDK Amazon AWS.

person MaxF    schedule 18.10.2017