このチュートリアルをベースとして、Redmine APIによって生成された JSONを GSON で解析しようとしています。残念ながら、JSON は内部でしか機能しないため、URL を提供できませんが、次のようになります。
{
"limit": 25,
"total_count": 653,
"offset": 0,
"time_entries": [
{
"spent_on": "2013-02-14",
"activity": {
"name": "Blah1",
"id": 10
},
"project": {
"name": "TEST",
"id": 10
},
"id": 661,
"hours": 1,
"updated_on": "2013-02-14T14:32:19Z",
"user": {
"name": "USER1",
"id": 7
},
"issue": {
"id": 467
},
"comments": "COMMENT 1",
"created_on": "2013-02-14T14:32:19Z"
},
{
"spent_on": "2013-02-14",
"activity": {
"name": "Bla2",
"id": 10
},
"project": {
"name": "TEST TEST",
"id": 10
},
"id": 660,
"hours": 1,
"updated_on": "2013-02-14T11:52:13Z",
"user": {
"name": "USER2",
"id": 4
},
"issue": {
"id": 466
},
"comments": "COMMENT 2.",
"created_on": "2013-02-14T11:52:13Z"
}
]
}
が得られますが、NullPointerException
それが JSON の取得に失敗したためなのか、モデル化が間違っているためなのかはわかりません。内部クラスに関係する何かが欠けているのではないかと心配しています。JSON が正しく取得されないという単純なものであれば、私は本当に腹が立ちます。
私のデバイスはすべて、内部ネットワークに接続された WIFI で実行されており、ブラウザーを使用すると JSON が表示されるので、ネットワークの問題ではないと思います。
これが私のLogCatです:
02-20 21:11:11.175: E/AndroidRuntime(14450): FATAL EXCEPTION: main
02-20 21:11:11.175: E/AndroidRuntime(14450): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.javacodegeeks.android.json/com.javacodegeeks.android.json.JsonParsingActivity}: java.lang.NullPointerException
02-20 21:11:11.175: E/AndroidRuntime(14450): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2180)
02-20 21:11:11.175: E/AndroidRuntime(14450): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2230)
02-20 21:11:11.175: E/AndroidRuntime(14450): at android.app.ActivityThread.access$600(ActivityThread.java:141)
02-20 21:11:11.175: E/AndroidRuntime(14450): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1234)
02-20 21:11:11.175: E/AndroidRuntime(14450): at android.os.Handler.dispatchMessage(Handler.java:99)
02-20 21:11:11.175: E/AndroidRuntime(14450): at android.os.Looper.loop(Looper.java:137)
02-20 21:11:11.175: E/AndroidRuntime(14450): at android.app.ActivityThread.main(ActivityThread.java:5041)
02-20 21:11:11.175: E/AndroidRuntime(14450): at java.lang.reflect.Method.invokeNative(Native Method)
02-20 21:11:11.175: E/AndroidRuntime(14450): at java.lang.reflect.Method.invoke(Method.java:511)
02-20 21:11:11.175: E/AndroidRuntime(14450): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
02-20 21:11:11.175: E/AndroidRuntime(14450): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560)
02-20 21:11:11.175: E/AndroidRuntime(14450): at dalvik.system.NativeStart.main(Native Method)
02-20 21:11:11.175: E/AndroidRuntime(14450): Caused by: java.lang.NullPointerException
02-20 21:11:11.175: E/AndroidRuntime(14450): at com.javacodegeeks.android.json.JsonParsingActivity.onCreate(JsonParsingActivity.java:46)
02-20 21:11:11.175: E/AndroidRuntime(14450): at android.app.Activity.performCreate(Activity.java:5104)
02-20 21:11:11.175: E/AndroidRuntime(14450): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1080)
02-20 21:11:11.175: E/AndroidRuntime(14450): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2144)
私のJsonParsingActivity
:
public class JsonParsingActivity extends Activity {
String url = "URL";
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
InputStream source = retrieveStream(url);
Gson gson = new Gson();
Reader reader = new InputStreamReader(source);
RedmineResponse response = gson.fromJson(reader, RedmineResponse.class);
Toast.makeText(this, response.query, Toast.LENGTH_SHORT).show();
List<Result> results = response.results;
for (Result result : results) {
if (result.comments != null) {
Toast.makeText(this, result.comments, Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(this, "EMPTY", Toast.LENGTH_SHORT).show();
}
}
}
private InputStream retrieveStream(String url) {
DefaultHttpClient client = new DefaultHttpClient();
HttpGet getRequest = new HttpGet(url);
try {
HttpResponse getResponse = client.execute(getRequest);
final int statusCode = getResponse.getStatusLine().getStatusCode();
if (statusCode != HttpStatus.SC_OK) {
Log.w(getClass().getSimpleName(), "Error " + statusCode + " for URL " + url);
return null;
}
HttpEntity getResponseEntity = getResponse.getEntity();
return getResponseEntity.getContent();
} catch (IOException e) {
getRequest.abort();
Log.w(getClass().getSimpleName(), "Error for URL " + url, e);
}
return null;
}
}
私Result
のクラス:
public class Result {
@SerializedName("id")
public String time_entry_ID;
@SerializedName("spent_on")
public String spent_on;
@SerializedName("created_on")
public String created_on;
public Project project;
@SerializedName("hours")
public String hours;
@SerializedName("comments")
public String comments;
@SerializedName("iso_language_code")
public String isoLanguageCode;
@SerializedName("to_user_id_str")
public String toUserIdStr;
public String source;
}
私RedmineResponse
のクラス:
public class RedmineResponse {
public List<Result> results;
@SerializedName("limit")
public int limit;
@SerializedName("offset")
public int offset;
public String query;
}
私Activity
のクラス:
public class Activity {
@SerializedName("id")
public String activity_ID;
@SerializedName("name")
public String activity_name;
}
私Issue
のクラス:
public class Issue {
@SerializedName("id")
public String issue_ID;
}
私Project
のクラス:
public class Issue {
@SerializedName("id")
public String issue_ID;
}
私User
のクラス:
public class User {
@SerializedName("id")
public String user_ID;
@SerializedName("name")
public String user_name;
}