質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
JOIN

これはSQL文のJOINに関するタグです。リレーショナルデータベースシステムの二つ以上のテーブルを結合する際に、この構文が利用されます。

Android

Androidは、Google社が開発したスマートフォンやタブレットなど携帯端末向けのプラットフォームです。 カーネル・ミドルウェア・ユーザーインターフェイス・ウェブブラウザ・電話帳などのアプリケーションやソフトウェアをひとつにまとめて構成。 カーネル・ライブラリ・ランタイムはほとんどがC言語/C++、アプリケーションなどはJavaSEのサブセットとAndroid環境で書かれています。

Android Studio

Android Studioは、 Google社によって開発された、 Androidのネイティブアプリケーション開発に特化した統合開発ツールです。

Kotlin

Kotlinは、ジェットブレインズ社のアンドリー・ブレスラフ、ドミトリー・ジェメロフが開発した、 静的型付けのオブジェクト指向プログラミング言語です。

Q&A

解決済

1回答

7893閲覧

【Android Studio】moshiでJsonの配列をパースしたい

sawaIT

総合スコア21

JOIN

これはSQL文のJOINに関するタグです。リレーショナルデータベースシステムの二つ以上のテーブルを結合する際に、この構文が利用されます。

Android

Androidは、Google社が開発したスマートフォンやタブレットなど携帯端末向けのプラットフォームです。 カーネル・ミドルウェア・ユーザーインターフェイス・ウェブブラウザ・電話帳などのアプリケーションやソフトウェアをひとつにまとめて構成。 カーネル・ライブラリ・ランタイムはほとんどがC言語/C++、アプリケーションなどはJavaSEのサブセットとAndroid環境で書かれています。

Android Studio

Android Studioは、 Google社によって開発された、 Androidのネイティブアプリケーション開発に特化した統合開発ツールです。

Kotlin

Kotlinは、ジェットブレインズ社のアンドリー・ブレスラフ、ドミトリー・ジェメロフが開発した、 静的型付けのオブジェクト指向プログラミング言語です。

0グッド

0クリップ

投稿2018/09/18 18:24

編集2018/09/18 18:32

前提・実現したいこと

moshiでJsonが配列になっている値をそれぞれパースしたい。

以前、moshiを使ってた1つのJsonの中で、2階層以上のJsonのパースについて回答いただきましたが
今度は複数の単純なJsonが配列になっているパターンで詰まってしまいました。

今回はそもそも配列のJsonというより配列にJsonが入っていると捉えているので
forなりforEacheで1番目の要素を取得してパースするのがよいのではないかと考えてAdapterを配列用に設定しております。
結果contentsListのn番目では情報を取得することができるのですが、contentsList[0][name]といった取得ができないことが分かりました。
(シンプルに構文エラーかと思いますが)

そうなるとMapとして扱うことになるのかと思い以前回答いただいた下記の内容も試してみましたがうまくいきませんでした。
https://teratail.com/questions/145737

https://api.myjson.com/bins/10laeg [ { name: "スポーツデポ 大曲店", link: "https://www.alpen-group.jp/store/sportsdepo_alpen/shop_search/detail.php?shopid=7524", business_hours: "10:00~20:30 地震の影響により休業しておりましたが、営業再開いたしました。", shop_tel: "011-377-1477", address: "北海道 北広島市大曲幸町 2丁目8番地2", address_memo: "国道36号線沿い、北広島インター交差点より札幌方面へ300m" }, { name: "スポーツデポ 宮の沢店", link: "https://www.alpen-group.jp/store/sportsdepo_alpen/shop_search/detail.php?shopid=7586", business_hours: "10:00~21:00 地震の影響により休業いたしておりましたが、営業再開いたしました。", shop_tel: "011-665-6140", address: "北海道 札幌市手稲区 西宮の沢4条2丁目1番8", address_memo: "札幌西インターより国道5号線を小樽方面に約1km" }, ・ ・ 省略 ・ ・ }]

発生している問題・エラーメッセージ

//listで処理したとき
09-18 17:59:17.383 25195-25195/com.example.tatsuro.sportable E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.newsour.sportable, PID: 25195
java.lang.ClassCastException: com.example.newsour.sportable.Contents cannot be cast to com.example.newsour.sportable.ContentsListData

//Mapで処理したとき
09-18 18:27:27.327 26517-26517/com.example.tatsuro.sportable E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.tatsuro.sportable, PID: 26517
com.squareup.moshi.JsonDataException: Expected BEGIN_OBJECT but was BEGIN_ARRAY at path $
at com.squareup.moshi.JsonUtf8Reader.beginObject(JsonUtf8Reader.java:141)
at com.squareup.moshi.MapJsonAdapter.fromJson(MapJsonAdapter.java:65)
at com.squareup.moshi.MapJsonAdapter.fromJson(MapJsonAdapter.java:30)
at com.squareup.moshi.JsonAdapter$2.fromJson(JsonAdapter.java:128)
at com.squareup.moshi.JsonAdapter.fromJson(JsonAdapter.java:35)
at com.squareup.moshi.JsonAdapter.fromJson(JsonAdapter.java:39)
at com.example.newsour.sportable.ShopsFragment.createDataList(ShopsFragment.kt:94)
at com.example.newsour.sportable.ShopsFragment.access$createDataList(ShopsFragment.kt:21)
at com.example.newsour.sportable.ShopsFragment$MyAsyncTask.onPostExecute(ShopsFragment.kt:39)
at com.example.newsour.sportable.ShopsFragment$MyAsyncTask.onPostExecute(ShopsFragment.kt:32)
at android.os.AsyncTask.finish(AsyncTask.java:695)
at android.os.AsyncTask.access$600(AsyncTask.java:180)
at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:712)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:193)
at android.app.ActivityThread.main(ActivityThread.java:6669)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)

該当のソースコード

kotlin

1 2import android.app.PendingIntent.getActivity 3import android.net.Uri 4import android.os.AsyncTask 5import android.os.Bundle 6import android.support.customtabs.CustomTabsIntent 7import android.support.v4.app.Fragment 8import android.support.v7.widget.LinearLayoutManager 9import android.view.ViewGroup 10import android.view.LayoutInflater 11import android.view.View 12import android.support.v7.widget.RecyclerView 13import com.squareup.moshi.JsonAdapter 14import com.squareup.moshi.Moshi 15import com.squareup.moshi.Types 16import okhttp3.OkHttpClient 17import okhttp3.Request 18 19 20class ShopsFragment : Fragment() { 21 22 override fun onCreate(savedInstanceState: Bundle?) { 23 super.onCreate(savedInstanceState) 24 MyAsyncTask().execute() 25 } 26 override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { 27 val view = inflater.inflate(R.layout.shops_fragment, container, false) 28 return view 29 } 30 31 inner class MyAsyncTask: AsyncTask<Void, Void, String>() { 32 override fun doInBackground(vararg p0: Void?): String { 33 return this.getHtml() 34 } 35 override fun onPostExecute(result: String) { 36 super.onPostExecute(result) 37 val recyclerView = view?.findViewById(R.id.contentsListView) as RecyclerView 38 val adapter = ContentsListViewAdapter(createDataList(result), object : ContentsListViewAdapter.ListListener { 39 override fun onClickRow(tappedView: View, ContentsListData: ContentsListData) { 40 this@ShopsFragment.onClickRow(ContentsListData) 41 } 42 }) 43 44 recyclerView.setHasFixedSize(true) 45 recyclerView.layoutManager = LinearLayoutManager(activity) 46 recyclerView.adapter = adapter 47 48 } 49 50 fun getHtml(): String { 51 val client = OkHttpClient() 52 val req = Request.Builder().url("https://api.myjson.com/bins/10laeg").get().build() 53 val resp = client.newCall(req).execute() 54 55 return resp.body()!!.string() 56 } 57 } 58 59 private fun createDataList(result:String): List<ContentsListData>? { 60 61 val jsonText = result 62 val contentsListDataType = Types.newParameterizedType( 63 List::class.java, 64 Contents::class.java 65 ) 66 val contentsListDataAdapter: JsonAdapter<List<ContentsListData>> = Moshi.Builder() 67 .build() 68 .adapter(contentsListDataType) 69 70 val contentsList: List<ContentsListData>? = contentsListDataAdapter.fromJson(jsonText) 71 72 val dataList = mutableListOf<ContentsListData>() 73 74    //ここでrecycleビューに突っ込みたい(addするところは途中で消えてしまいました) 75 contentsList?.forEach { 76 ContentsListData().also { 77 it.name = contentsList[0].toString() 78 it.link = contentsList[1].toString() 79 it.business_hours = contentsList[2].toString() 80 it.address = contentsList[4].toString() 81 it.address_memo = contentsList[5].toString() 82 } 83 } 84 val rssMapType = Types.newParameterizedType( 85 86//Map Rssと”a”は無視してください 87 88// Map::class.java, 89// String::class.java, 90// Contents::class.java 91// ) 92// val rssMapAdapter: JsonAdapter<Map<String, Contents>> = Moshi.Builder() 93// .build() 94// .adapter(rssMapType) 95// 96// val rssMap: Map<String, Contents>? = rssMapAdapter.fromJson(jsonText) 97// 98// val dataList = rssMap?.map { (key, rss) -> 99// ContentsListData().also { 100// it.name = "a" 101// it.link = "a" 102// it.business_hours = "a" 103// it.address = "a" 104// it.address_memo = "a" 105// } 106// } 107 108 return dataList 109 110 111 } 112 113 fun onClickRow(rowModel: ContentsListData) { 114 val intent = CustomTabsIntent.Builder().build() 115 intent.launchUrl(getActivity(), Uri.parse(rowModel.link)) 116 } 117 118 companion object { 119 120 fun newInstance(): ShopsFragment { 121 val fragment = ShopsFragment() 122 return fragment 123 } 124 } 125} 126 127

Content.tk

kotlin

1import com.squareup.moshi.Json 2 3data class Contents( 4 var name: String, 5 var business_hours : String, 6 var address: String, 7 var address_memo: String, 8 var link: String, 9 @field:Json(name = "shop_tel") var tel: String 10) 11

ContensListData.kt

kotlin

1 2class ContentsListData { 3 var name: String = "" 4 var link: String = "" 5 var business_hours: String = "" 6// var shop_tel: String = "" 7 var address: String = "" 8 var address_memo: String = "" 9} 10

補足情報(FW/ツールのバージョンなど)

Android Studio 3.1.4
Build #AI-173.4907809, built on July 24, 2018
JRE: 1.8.0_152-release-1024-b02 amd64
JVM: OpenJDK 64-Bit Server VM by JetBrains s.r.o
Windows 10 10.0

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

単純に型の指定ミスをしているように思います。

kotlin

1val contentsListDataType = Types.newParameterizedType( 2 List::class.java, 3 Contents::class.java // ここではContentsを指定している 4) 5 6// ここではContentsListDataを指定している 7val contentsListDataAdapter: JsonAdapter<List<ContentsListData>> = Moshi.Builder() 8 .build() 9 .adapter(contentsListDataType)

2つが一致していないためにパースに失敗しています。どちらかに合わせてください。

投稿2018/09/19 05:30

kakajika

総合スコア3131

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

sawaIT

2018/09/19 11:38

ご解答ありがとうございます! 全くご指摘の通りで修正できました! 入門用にコピペしたものがほとんどだったのでパース用のデータクラスと配列用のデータクラスで二種類持っていないといけないと思っておりました… また何かありましたらお願いいたします。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問