3

I am building an SDK.

The Scenario

  • From the app, the developer passes the JsonObject and URL in a method and inside the SDK.
  • I add those values in SQLite database and start a JobScheduler.
  • The Jobscheduler takes the request at 0 indexes out of the database executes it.
  • When I get the response, I delete that request from the database and now the request at 1 index comes to the 0 index and again I execute the same code where 0th index request is fired.

The Problem

  • When I get the response from a server inside the SDK, I need to send it to the developer using a callback.
  • I can take the callback as an argument when I take the JSON and URL from user, but I don't know how to proceed further because I cannot store it into the database
  • Suppose I have 5 requests in the database and scheduler executes it one by one, I don't know how to send the response back to the developer. I can not pass context in the jobscheduler. The only way to do that is I get the corresponding context for each row (request) in the database.

What I tried

  • I tried using a LocalBroadcastManager, but I can not create a generic class and get it's onreceive() method implemented, also the context passing was a problem
  • Tried using Realm as a database so that I can add Context type and use my model, but it is not working as Context is not supported.
  • Storing Activity name in the database with other details and then driving out the class from it and activity from class. And then typecasting the activity into my callback. but it throws ClassCastException as the class it tries to derive from the Name is on the developer's app and not in my SDK

..

The App's MainActivity Code

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

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

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

sdkClass.executeQueue();

The SDK class which adds and executes code

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);
}

MyJobServiceCode

@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();
    }
}

Any help will be blessed right now.

The Bat
  • 1,085
  • 1
  • 13
  • 31
  • Why are you storing things that you don't want to store, in the database? Why not storing them in the memory? (I mean the pending requests) – Eselfar Jul 18 '17 at 08:51
  • @Eselfar Because if at the time of any submit click, internet is not there, I am letting user to proceed, I store his request in database and start the jobscheduler. So whenever the internet comes, it is executed. The jobscheduler takes care of the persistence, even if app is killed or even the phone is rebooted. So it is kind of queue mechanism that I am maintaining. – The Bat Jul 18 '17 at 08:54
  • So in that case I think you can use a PendingIntent. – Eselfar Jul 18 '17 at 10:11
  • @Eselfar can you please explain a little, so that i can take it forward? thanks – The Bat Jul 18 '17 at 10:25
  • My bad you can't use this. But what you can do is to use a Broascast Intent. Then the other app will have to register a Broascast receiver. https://stackoverflow.com/a/33611355/1827254 – Eselfar Jul 18 '17 at 14:22
  • @Eselfar yes, register and write a BroadcastReceiver extending class too which should implement `onReceive()` method... I don' want user to go through this amount of work. The SDK should do that.. This is a really good idea though, but if you can think of any other solution, it will better :) – The Bat Jul 18 '17 at 14:31
  • If you want to be able to "wake up" an app as you want your system to work even if the device has been rebooted, there is not so many solutions. But what do you want to return exactly to your user? – Eselfar Jul 18 '17 at 14:33
  • @Eselfar the `String Response` that you can see in JobService code's `onSuccess()` – The Bat Jul 18 '17 at 14:36

1 Answers1

0

You store requests in database, so it can has unique id (autoincrement). Then you can store callbacks in memory with relation request id -> callback. On response you can call it.

If you want, return id to developers. Then they can bind and unbind and get results when they need, even the response had got yesterday.

Take a look on TransferUtility from Amazon AWS SDK for example.

MaxF
  • 2,123
  • 1
  • 14
  • 17