2017-07-01 3 views
0

Androidスタジオで停止情報を取得するには CUMTD APIのJSONフォームを停止して何らかの理由でこのエラーが発生します。java.lang.NullPointerException:私のGET要求とクエリーパラメータが正常であるにもかかわらず、ヌルオブジェクト参照でインタフェースメソッド 'java.lang.Object java.util.List.get(int)'を呼び出そうとしました。アンドロイドスタジオのRetrofit 2を使用したGETリクエストは、クエリパラメータが正しくても機能していないようです。

マイMTDのAPIインタフェース:

import java.util.List; 
import retrofit2.Call; 
import retrofit2.Retrofit; 
import retrofit2.converter.gson.GsonConverterFactory; 
import retrofit2.http.GET; 
import retrofit2.http.Path; 
import retrofit2.http.Query; 

/** 
* Class that details the request(s) that we will call 
*/ 

public interface MTDApi{ 
    @GET("GetStops") 
    Call<List<UserModel>> loadStops(
      @Query("api_key") String key, 
      @Query("stop name") String stop 
    ); 

    Retrofit retrofit = new Retrofit.Builder() 
      .baseUrl("https://developer.cumtd.com/api/v2.2/json/") 
      .addConverterFactory(GsonConverterFactory.create()) 
      .build(); 

} 

マイUserModelクラス:

public class UserModel { 
    String stop_id; 
    public String getStop_id(){ 
     return stop_id; 
    } 
    public void setStop_id(String stop_id){ 
     this.stop_id = stop_id; 
    } 
} 

私の主な活動:

import android.support.v7.app.AppCompatActivity; 
import android.os.Bundle; 
import android.util.Log; 
import android.view.View; 
import android.widget.Button; 
import android.widget.EditText; 
import android.widget.TextView; 

import java.util.List; 
import java.util.Random; 

import retrofit2.Call; 
import retrofit2.Callback; 
import retrofit2.Response; 

import static android.R.attr.x; 
import static android.media.CamcorderProfile.get; 
import static com.example.neelpatel.weatherapp.MTDApi.retrofit; 

public class MainActivity extends AppCompatActivity { 

    String key= "<APIKEY>"; 
    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main);//Starts Retrofit 
     final MTDApi mtdApi = MTDApi.retrofit.create(MTDApi.class); 

     //Sets up Button and EditText for use in this class 
     final EditText edit = (EditText) findViewById(R.id.edit); 
     Button requestButton = (Button) findViewById(R.id.button); 

     //Behavior once button is clicked 
     requestButton.setOnClickListener(new View.OnClickListener() { 
      @Override 
      public void onClick(View v) { 

       String s = edit.getText().toString(); 
       //Sets up up the API call 
       Call<List<UserModel>> call = mtdApi.loadStops(key,s); 

       //Runs the call on a different thread 
       call.enqueue(new Callback<List<UserModel>>() { 
        @Override 
        //Once the call has finished 

       public void onResponse(Call<List<UserModel>> call, Response<List<UserModel>> response) { 
        //Gets the list of stops 
        List<UserModel> stops = response.body(); 
        String text = stops.get(0).getStop_id(); 
        edit.setText(text); 
       } 

        @Override 
        //If the call failed 
        public void onFailure(Call<List<UserModel>> call, Throwable t) { 
         edit.setText("Request Failed"); 
         Log.e("RequestCall", "Request failed"); 
        } 
       }); 
      } 
     }); 
    } 
} 

マイactivity_main.xml:

<?xml version="1.0" encoding="utf-8"?> 
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    xmlns:app="http://schemas.android.com/apk/res-auto" 
    xmlns:tools="http://schemas.android.com/tools" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    tools:context="com.example.neelpatel.weatherapp.MainActivity"> 

    <EditText 
     android:id="@+id/edit" 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content" 
     android:layout_above="@+id/button" 
     android:layout_alignParentLeft="true" 
     android:layout_alignParentStart="true" 
     android:layout_marginBottom="133dp" /> 

    <Button 
     android:id="@+id/button" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:text="Request" 
     tools:layout_editor_absoluteX="16dp" 
     tools:layout_editor_absoluteY="16dp" 
     android:layout_alignParentBottom="true" 
     android:layout_centerHorizontal="true" 
     android:layout_marginBottom="95dp" /> 

</RelativeLayout> 
+0

エラーメッセージだけでなく、質問にスタックトレースを追加します。 –

答えて

0

onResponseでは、response.isSuccessful()をチェックし、停止することを確認する必要があります!= null。サーバーがエラーを返すようです。

0

まず、で、応答が成功したかどうか(つまり、HTTPステータスコードの[200,300]の範囲内にある)を確認する必要があります。あなたはonResponse(...)方法でこれを行うことができます。

public void onResponse(Call<List<UserModel>> call, Response<List<UserModel>> response) { 
     if (response.isSuccessful()) { 
      //Gets the list of stops 
      List<UserModel> stops = response.body(); 
      String text = stops.get(0).getStop_id(); 
      edit.setText(text); 
     } else { 
      // show error message 
     } 
} 

また、クエリが間違っています。 GetStopsのドキュメントによれば、ではなくkeyのクエリパラメータが必要です(また、空白を持つstop nameも渡しています)。したがって、あなたのURLは(最終的に)https://developer.cumtd.com/api/v2.2/json/GetStops?key=<your_api_key>のようになります。

@GET("GetStops") 
Call<List<UserModel>> loadStops(@Query("key") String key); 

それはあなたの予想される応答は、あなたがsampleで見ることができます実際の応答の構造に一致していないことも言及する価値があります:これは、インタフェースのエンドポイント記述は次のようになりますことを意味します。その構造体を手動で作成したくない場合は、実際にサンプルを適切なPOJOモデル構造に変換するために使用できるthis oneなどのJSONからPOJOへの変換を使用できます。あなたがあなたの改造インターフェイスタイプList<UserModel>を書いた時に期待しているように見えるよう

+0

しかし、それはパラメータのためのAPIのキーだから、私はそれのための文字列としてAPIキーを渡すことはできません? –

+0

私はこの部分を私の答えで明確にしました。また、期待されるモデルの構造が実際の応答の構造と一致していないことにも注意してください。 –

+0

だから、loadstopsを呼び出すと、メインアクティビティのメソッドにキーを追加する必要がありますか? –

0

documentationによると、サーバは、JSONオブジェクトなくJSON配列を返します。あなたが欲しいの配列はオブジェクトでstopsフィールドであるので、あなたはどちらかにしたいことがあります。

  • カスタムGsonデシリアライザを作成

    • がそこから配列を返されたJSONオブジェクトに一致するPOJOを作成してもらいますanswerで説明されているとおりです。
  • 関連する問題