【问题标题】:java.lang.NullPointerException error on Retrofit onResponse改造 onResponse 上的 java.lang.NullPointerException 错误
【发布时间】:2017-10-24 20:01:13
【问题描述】:

您好,我是第一次使用 Retrofit,但似乎无法正常工作。正在开发一个以当地货币获取加密货币汇率的应用程序,这里是 api link,JSON 格式

{
  "BTC": {
    "USD": 6019.1,
    "EUR": 5139.44,
    "NGN": 2136243.25
  },
  "ETH": {
    "USD": 290.98,
    "EUR": 250.03,
    "NGN": 103031.01
  }
}

这是我的模型(来自http://www.jsonschema2pojo.org/):已更新

public class CryptoCurrency {

@SerializedName("BTC")
@Expose
private BTC BTC;
@SerializedName("ETH")
@Expose
private ETH ETH;

public BTC getBTC() {
    return BTC;
}

public void setBTC(BTC BTC) {
    this.BTC = BTC;
}

public ETH getETH() {
    return ETH;
}

public void setETH(ETH ETH) {
    this.ETH = ETH;
}

public class BTC {

    @SerializedName("USD")
    @Expose
    private Double USD;

    @SerializedName("EUR")
    @Expose
    private Double EUR;

    @SerializedName("NGN")
    @Expose
    private Double NGN;

    public Double getUSD() {
        return USD;
    }

    public void setUSD(Double USD) {
        this.USD = USD;
    }

    public Double getEUR() {
        return EUR;
    }

    public void setEUR(Double EUR) {
        this.EUR = EUR;
    }

    public Double getNGN() {
        return NGN;
    }

    public void setNGN(Double NGN) {
        this.NGN = NGN;
    }


}


public class ETH {

    @SerializedName("USD")
    @Expose
    private Double USD;
    @SerializedName("EUR")
    @Expose
    private Double EUR;
    @SerializedName("NGN")
    @Expose
    private Double NGN;

    public Double getUSD() {
        return USD;
    }

    public void setUSD(Double USD) {
        this.USD = USD;
    }

    public Double getEUR() {
        return EUR;
    }

    public void setEUR(Double EUR) {
        this.EUR = EUR;
    }

    public Double getNGN() {
        return NGN;
    }

    public void setNGN(Double NGN) {
        this.NGN = NGN;
    }

}

}

我的界面:

public interface CurrencyInterface {
    @GET("/data/pricemulti/")
    Call<CryptoCurrency.BTC> currency(@Query("crypto") String crypto, @Query("local") String local);
}

我的onResponse 方法:

call.enqueue(new Callback<CryptoCurrency.BTC>() {
        @Override
        public void onResponse(Call<CryptoCurrency.BTC> call, Response<CryptoCurrency.BTC> response) {
            String currency = response.body().toString();
            Toast.makeText(getApplicationContext(), "result " + currency, Toast.LENGTH_LONG).show();
            Log.i("MainActivity", currency);

        }

        @Override
        public void onFailure(Call<CryptoCurrency.BTC> call, Throwable t) {

        }
    });

当我运行代码并检查我的日志时,我得到了这个错误:

java.lang.NullPointerException
at com.example.raynold.cryptorates.MainActivity$1.onResponse(MainActivity.java:53)
at retrofit2.ExecutorCallAdapterFactory$ExecutorCallbackCall$1$1.run(ExecutorCallAdapterFactory.java:70)

已更新------

我的 MainActivity 类

public class MainActivity extends AppCompatActivity {

private RecyclerView mCurrencyRecycler;
private Button mclickMe;
private CurrencyAdapter mCurrencyAdapter;
private List<CryptoCurrency> mCurrencyList;
private CurrencyInterface mCurrencyInterface;
private LinearLayoutManager mLinearLayoutManager;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    mCurrencyRecycler = (RecyclerView) findViewById(R.id.rv_rates);
    mLinearLayoutManager = new LinearLayoutManager(this);
    mCurrencyRecycler.setLayoutManager(mLinearLayoutManager);
    mCurrencyRecycler.setHasFixedSize(true);
    mclickMe = (Button) findViewById(R.id.click_me);

    mCurrencyInterface = ApiClient.getApiClient().create(CurrencyInterface.class);

    Call<CryptoCurrency.BTC> call = mCurrencyInterface.currency("BTC", "NGN");

    call.enqueue(new Callback<CryptoCurrency.BTC>() {
        @Override
        public void onResponse(Call<CryptoCurrency.BTC> call, Response<CryptoCurrency.BTC> response) {
            String currency = response.body().toString();
            Toast.makeText(getApplicationContext(), "result " + currency, Toast.LENGTH_LONG).show();
            Log.i("MainActivity", currency);

        }

        @Override
        public void onFailure(Call<CryptoCurrency.BTC> call, Throwable t) {

        }
    });

    mclickMe.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {

        }
    });

}

}

我也想知道如何让它与 recyclerview 一起工作,因为 JSON 是对象类型而不是数组。

【问题讨论】:

标签: java android retrofit2


【解决方案1】:
public class CryptoCurrency {

        @SerializedName("BTC")
        @Expose
        private BTC BTC;
        @SerializedName("ETH")
        @Expose
        private ETH ETH;

        public BTC getBTC() {
            return BTC;
        }

        public void setBTC(BTC BTC) {
            this.BTC = BTC;
        }

        public ETH getETH() {
            return ETH;
        }

        public void setETH(ETH ETH) {
            this.ETH = ETH;
        }

    class ETH {
      ...
    }

    class BTC {
       ...
    }

}

在你的界面CurrencyInterface使用like

@GET("/data/pricemulti")
Call<CryptoCurrency> currency(@Query("fsyms") String crypto, @Query("tsyms") String local);

处理方式

Call<CryptoCurrency> call = mCurrencyInterface.currency("BTC", "NGN");

call.enqueue(new Callback<CryptoCurrency>() {
        @Override
        public void onResponse(Call<CryptoCurrency> call, Response<CryptoCurrency> response) {
            BTC btc = response.body().getBTC();
            Toast.makeText(getApplicationContext(), "result " + btc.getNGN(), Toast.LENGTH_LONG).show();

        }

        @Override
        public void onFailure(Call<CryptoCurrency.BTC> call, Throwable t) {

        }
    });

【讨论】:

  • 请我需要更多信息
  • @Raynold 现在明白了吗?
  • "com.example.raynold.cryptorates.model.CryptoCurrency@412052f8"。我得到这个作为回应
  • 调试并确认你的调用url和你喜欢的api一样min-api.cryptocompare.com/data/…
  • 我把它改成了@GET("data/pricemulti") Call currency(@Query("crypto") String crypto, @Query("local") String local);跨度>
【解决方案2】:

您不应在 URL 的开头和结尾使用反斜杠。

试试

@GET("data/pricemulti")

而不是

@GET("/data/pricemulti/")

【讨论】:

    【解决方案3】:

    像这样更改您的 onResponse 方法:

    ...........
    call.enqueue(new Callback<CryptoCurrency.BTC>() {
            @Override
            public void onResponse(Call<CryptoCurrency.BTC> call, Response<CryptoCurrency.BTC> response) {
                String currency = response.getUSD().toString();
                Toast.makeText(getApplicationContext(), "result " + currency, Toast.LENGTH_LONG).show();
                Log.i("MainActivity", currency);
    
            }
    
            @Override
            public void onFailure(Call<CryptoCurrency.BTC> call, Throwable t) {
    
            }
        });
    

    试试这个解决你的问题。

    【讨论】:

    • 没有工作,无法在响应@HassanUsman 时调用 getJsonArray
    • 试试response.body().getJsonArray("BTC"); 我也更新了我的ans。
    • 仍然无法在 response.body.getJsonArray 上调用 getJsonArray
    • 现在试试我改了代码String currency = response.getUSD().toString();
    • @HassanUsman 不应该是String currency = response.body().getUSD().toString(); 吗?
    【解决方案4】:

    检查 response.body() 在此行之前是否为空

    String currency = response.body().toString();
    

    如果响应代码不等于 200,您的响应将为空

    【讨论】:

    • "com.example.raynold.cryptorates.model.CryptoCurrency$BTC@41204318" 我得到这个响应@NermeenSaleh
    • @Raynold 响应包含 BTC 对象,请覆盖 BTC 类的字符串方法以返回货币。
    • 请您提供更多信息.. 进行了更改并得到了 java.lang.NullPointerException
    猜你喜欢
    • 2017-12-01
    • 2018-03-01
    • 2021-03-27
    • 2020-07-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-08-15
    相关资源
    最近更新 更多