无法在Android中实现回调函数

3

我正在构建一个SDK。

场景

  • 开发人员从应用程序中通过方法将JsonObject和URL传递到SDK内。
  • 我将这些值添加到SQLite数据库中并启动JobScheduler。
  • Jobscheduler从数据库中获取请求的0索引并执行它。
  • 当我收到响应时,我会从数据库中删除该请求,现在1索引处的请求变为0索引,然后我再次执行相同的代码,其中会触发0号索引请求。

问题

  • 当我在SDK内从服务器收到响应时,我需要使用回调将其发送给开发人员。
  • 当我从用户那里获取JSON和URL时,可以将回调作为参数传递,但是我不知道如何进一步处理,因为我无法将其存储到数据库中。
  • 假设数据库中有5个请求并且scheduler依次执行它们,我不知道如何将响应发送回开发人员。我无法在jobscheduler中传递上下文。唯一的方法是获取数据库中每行(请求)的相应上下文。

我的尝试

  • 我尝试使用LocalBroadcastManager,但我无法创建通用类并实现其onreceive()方法,而且上下文传递是个问题。
  • 尝试使用Realm作为数据库,以便我可以添加Context类型并使用我的模型,但是它不起作用,因为不支持上下文。
  • 将Activity名称存储在数据库中以及其他详细信息,然后从中导出类和活动。然后将活动强制转换为我的回调函数。但是它会抛出ClassCastException,因为它尝试从Name中派生的类位于开发人员的应用程序中而不是我的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);
}

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

现在任何帮助都将受到祝福。


为什么要将不需要存储的东西存储在数据库中?为什么不将它们存储在内存中呢?(我指的是待处理请求) - Eselfar
@Eselfar 因为如果在任何提交点击时,没有网络,我会让用户继续,将他的请求存储在数据库中并启动作业调度程序。因此,每当有网络连接时,它就会被执行。作业调度程序负责持久性,即使应用程序被杀死或甚至手机重新启动也是如此。因此,我正在维护一种队列机制。 - The Bat
@Eselfar,您能否请稍微解释一下,以便我可以继续进行?谢谢。 - The Bat
如果您希望能够“唤醒”应用程序,以便即使设备已重新启动,系统也能正常工作,这并不是那么容易实现的。但是,您到底希望向用户返回什么? - Eselfar
@Eselfar 在 JobService 代码的 onSuccess() 中可以看到 String Response - The Bat
显示剩余3条评论
1个回答

0

你可以将请求存储在数据库中,以便它可以拥有唯一的ID(自动递增)。 然后你可以将回调与请求ID相关联并存储在内存中。 在响应时,可以调用它。

如果你愿意,可以将ID返回给开发人员。 然后他们就可以在需要时绑定和解绑,并获取结果,即使响应是昨天收到的。

例如,可以查看Amazon AWS SDK中的TransferUtility


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接