繁体   English   中英

Android:在使用Retrofit继续执行之前等待API响应

[英]Android: Wait for a response by API before continue the execution using Retrofit

我的android编程遇到问题,我有一个需要运行一些例程的应用程序,比如扫描一些条码。 一旦我扫描了条形码,我就会将这个条形码的数据发送到我的API,“等待”以获取一些信息,然后再做其他事情。

问题是当我调用我的API来获取信息时,在我尝试使用应该来自API的信息之后,我将陷入NULL异常,请参阅下面的代码:

我每次扫描条形码时都会调用我的扫描程序:

    // 1 - First Stage: Scan barcode of tank
    if(stageScannerTank == 1)
    {
        // Verify if the user scanned the correct Tank
        if (!resultScan.equals(expectedTank)) {
            Toast.makeText(getContext(), "Wrong Tank, scan the correct ", Toast.LENGTH_LONG).show();
            stageScannerTank = 0;
            return;
        }


        // Get the tank information

        //new TanqueTask().execute(resultScan);

        **HERE IS MY PROBLEM, When I call the function below, I fill my tankMixPlant with data**

        getTankMixPlant(resultScan);

        ** I always fall into this IF **
        // If null information
        if(tankMixPlant == null) {
            Toast.makeText(getContext(), "Error to read tank information", Toast.LENGTH_LONG).show();
            return;
        }

    }

getTankMixPlant,使用Retrofit来调用我的服务,如果我测试了我的例程,它就可以了:

private void getTankMixPlant(String tankName){
    mService.getTankMixPlant(tankName).enqueue(new Callback<TankMixPlant>() {
        @Override
        public void onResponse(Call<TankMixPlant> call, Response<TankMixPlant> response) {
            tankMixPlant = response.body();

        }

        @Override
        public void onFailure(Call<TankMixPlant> call, Throwable t) {
            // On failure show the error message to the User
            AlertDialog alert;
            AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
            builder.setTitle("Error");
            builder.setMessage("Error: " + t.getMessage());
            alert = builder.create();
            alert.show();
        }
    });
}

我如何等待tankMixPlant充满数据以继续我的日常工作?

更新:

我继续解决这个问题,但是我改变了一些你可以在下面看到的东西:现在我得到了NullPointerException。

现在我在onResponse方法中验证我的对象是否为null:

     private void getTankMixPlant(String tankName){
    mService.getTankMixPlant(tankName).enqueue(new Callback<TankMixPlant>() {
        @Override
        public void onResponse(Call<TankMixPlant> call, Response<TankMixPlant> response) {
            tankMixPlant = response.body();
            if(tankMixPlant == null) {
              Toast.makeText(getContext(), "Error to read tank information", 
              Toast.LENGTH_LONG).show();
              return;
           }
        }

        @Override
        public void onFailure(Call<TankMixPlant> call, Throwable t) {
            // On failure show the error message to the User
            AlertDialog alert;
            AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
            builder.setTitle("Error");
            builder.setMessage("Error: " + t.getMessage());
            alert = builder.create();
            alert.show();
        }
    });
}

但是当我尝试验证有关tankMixPlant的一些信息时:

        // Verify tank stage
        if(!tankMixPlant.getBlenderCode().equals("0") && tankMixPlant.getIngr() == 1)
        {
            getPackages(tankMixPlant.getRecipeNumber(), tankMixPlant.getBlenderCode(), tankMixPlant.getTankName());
            // 2 - Mix Packages: Scan package barcode
            stageScannerTank = 2;
        }

        if(!tankMixPlant.getIngrSAPNumber().equals("0") && tankMixPlant.getIngr() == 1)
        {
            getIngr(tankMixPlant.getRecipeNumber(), tankMixPlant.getTankName());
            // 3 - P.I Packages: Scan package barcode
            stageScannerTank = 3;
        }

我的应用程序因此错误而崩溃:

E/AndroidRuntime: FATAL EXCEPTION: main
              Process: com.example.labtse.kibonapp, PID: 21519
              java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=114910, result=-1, data=Intent { act=com.google.zxing.client.android.SCAN flg=0x80000 VirtualScreenParam=Params{mDisplayId=-1, null, mFlags=0x00000000)} (has extras) }} to activity {com.example.labtse.kibonapp/com.example.labtse.kibonapp.TabPagesActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String com.example.labtse.kibonapp.model.TankMixPlant.getBlenderCode()' on a null object reference
                  at android.app.ActivityThread.deliverResults(ActivityThread.java:5007)
                  at android.app.ActivityThread.handleSendResult(ActivityThread.java:5050)
                  at android.app.ActivityThread.access$1600(ActivityThread.java:230)
                  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1876)
                  at android.os.Handler.dispatchMessage(Handler.java:102)
                  at android.os.Looper.loop(Looper.java:148)
                  at android.app.ActivityThread.main(ActivityThread.java:7409)
                  at java.lang.reflect.Method.invoke(Native Method)
                  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1230)
                  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1120)
               Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String com.example.labtse.kibonapp.model.TankMixPlant.getBlenderCode()' on a null object reference
                  at com.example.labtse.kibonapp.MixPlantFragment.scanRoutine(MixPlantFragment.java:367)
                  at com.example.labtse.kibonapp.MixPlantFragment.onActivityResult(MixPlantFragment.java:399)
                  at android.support.v4.app.FragmentActivity.onActivityResult(FragmentActivity.java:151)
                  at android.app.Activity.dispatchActivityResult(Activity.java:7165)
                  at android.app.ActivityThread.deliverResults(ActivityThread.java:5003)
                  at android.app.ActivityThread.handleSendResult(ActivityThread.java:5050) 
                  at android.app.ActivityThread.access$1600(ActivityThread.java:230) 
                  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1876) 
                  at android.os.Handler.dispatchMessage(Handler.java:102) 
                  at android.os.Looper.loop(Looper.java:148) 
                  at android.app.ActivityThread.main(ActivityThread.java:7409) 
                  at java.lang.reflect.Method.invoke(Native Method) 
                  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1230) 
                  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1120) 

我的tankMixPlant类:

package com.example.labtse.kibonapp.model;

public class TankMixPlant {
    private String tankName;
    private String recipeNumber;
    private int idBatch;
    private String ingrSAPNumber;
    private String blenderCode;
    private short ingr;
    private boolean QRUN;
    private boolean QEND;
    private Boolean QDOSANDO;
    private Boolean CONF_ING;

    public TankMixPlant() {
    }

    public String getTankName() {
        return tankName;
    }

    public void setTankName(String tankName) {
        this.tankName = tankName;
    }

    public String getRecipeNumber() {
        return recipeNumber;
    }

    public void setRecipeNumber(String recipeNumber) {
        this.recipeNumber = recipeNumber;
    }

    public int getIdBatch() {
        return idBatch;
    }

    public void setIdBatch(int idBatch) {
        this.idBatch = idBatch;
    }

    public String getIngrSAPNumber() {
        return ingrSAPNumber;
    }

    public void setIngrSAPNumber(String ingrSAPNumber) {
        this.ingrSAPNumber = ingrSAPNumber;
    }

    public String getBlenderCode() {
        return blenderCode;
    }

    public void setBlenderCode(String blenderCode) {
        this.blenderCode = blenderCode;
    }

    public short getIngr() {
        return ingr;
    }

    public void setIngr(short ingr) {
        this.ingr = ingr;
    }

    public boolean isQRUN() {
        return QRUN;
    }

    public void setQRUN(boolean QRUN) {
        this.QRUN = QRUN;
    }

    public boolean isQEND() {
        return QEND;
    }

    public void setQEND(boolean QEND) {
        this.QEND = QEND;
    }

    public Boolean getQDOSANDO() {
        return QDOSANDO;
    }

    public void setQDOSANDO(Boolean QDOSANDO) {
       this.QDOSANDO = QDOSANDO;
    }

    public Boolean getCONF_ING() {
        return CONF_ING;
    }

    public void setCONF_ING(Boolean CONF_ING) {
        this.CONF_ING = CONF_ING;
    }

}

解:

你必须这样写:

    if(tankMixPlant == null) {
        Toast.makeText(getContext(), "Error to read tank information", Toast.LENGTH_LONG).show();
        return;
    }

在你的onResponse里面,在行tankplant = ...

现在,如果从服务器获取任何数据,则将消除null异常。

希望能帮助到你。

UPDATE1:

写这个:

    if(!tankMixPlant.getBlenderCode().equals("0") && tankMixPlant.getIngr() == 1)
    {
        getPackages(tankMixPlant.getRecipeNumber(), tankMixPlant.getBlenderCode(), tankMixPlant.getTankName());
        // 2 - Mix Packages: Scan package barcode
        stageScannerTank = 2;
    }

    if(!tankMixPlant.getIngrSAPNumber().equals("0") && tankMixPlant.getIngr() == 1)
    {
        getIngr(tankMixPlant.getRecipeNumber(), tankMixPlant.getTankName());
        // 3 - P.I Packages: Scan package barcode
        stageScannerTank = 3;
    }

在你的onResponse方法中,如下所示:

 private void getTankMixPlant(String tankName){
mService.getTankMixPlant(tankName).enqueue(new Callback<TankMixPlant>() {
    @Override
    public void onResponse(Call<TankMixPlant> call, Response<TankMixPlant> response) {
       tankMixPlant = response.body();
       if(tankMixPlant == null) {
          Toast.makeText(getContext(), "Error to read tank information", 
          Toast.LENGTH_LONG).show();
          return;
       }

       ...... (Write Here)

    }

    @Override
    public void onFailure(Call<TankMixPlant> call, Throwable t) {
        // On failure show the error message to the User
        AlertDialog alert;
        AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
        builder.setTitle("Error");
        builder.setMessage("Error: " + t.getMessage());
        alert = builder.create();
        alert.show();
    }
});

试试吧。

问题是改装调用是异步完成的,而其余的代码则不是。 这就是为什么你的数据是null ,因为它还没有准备好。

首先,您必须删除您正在检查“待处理数据”的代码部分,并将其移至您的改造onResponse或其他某个地方,然后在网络响应后使用回调进行调用。

关于如何做到这一点,有很多方法。 我建议你阅读文档和一些像这样的教程, 另一篇

此外,在您进行改装调用时,最好向用户显示加载消息,让他意识到您正在进行网络呼叫并等待结果。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM