前提・実現したいこと
Androidのアプリを開発しており、DB内の一部情報を取得しリスト表示する機能の実装を考えています。
※アプリの開発はAndroid Studioで開発しています。
DBの作成は、「DB Browser for SQLite」で作成しています。
DBは以下の通りです。
id | name | tag |
---|---|---|
1 | 施設A | 娯楽 |
2 | 施設B | 飲食店 |
3 | 施設C | 娯楽 |
実現したいことは、
①DBから「tag」を取得してListViewで表示すること
②任意のListを選択すると、選択された「tag」の名前の情報をもって遷移すること
の2点です。
発生している問題・エラーメッセージ
プロブラム事態にエラーは発生していないのですが、画面のListViewになにも表示されないという事態が生じています。
public void run()内のリスト表示の処理が原因かなと考えています。
該当のソースコード
以下は、Android Stdioのコードです。
Java
1package com.websarva.wings.android.town_infoapp; 2 3//importは長いので割愛します。 4 5public class MainActivity extends AppCompatActivity { 6 7 private InputMethodManager inputMethodManager; 8 private static final String DEBUG_TAG = "AsyncSample"; 9 private static final String URL = "ローカルURL"; 10 11 @Override 12 protected void onCreate(Bundle savedInstanceState) { 13 super.onCreate(savedInstanceState); 14 setContentView(R.layout.activity_main); 15 16 String urlFull = URL; 17 receiveTag(urlFull); 18 19 // タグを格納するListMapを生成。 20 ListView lvtag = findViewById(R.id.lvtag); 21 // クリックリスナーを登録。 22 lvtag.setOnItemClickListener(new ListItemClickListener()); 23 24 } 25 26 private void receiveTag(final String urlFull){ 27 //確実にUIスレッドに処理を戻す 28 Looper mainLooper = Looper.getMainLooper(); 29 //スレッド間通信を行うHandlerオブジェクトを登録 30 Handler handler = HandlerCompat.createAsync(mainLooper); 31 //非同期処理を行うためのインスタンス生成と実行 32 MainActivity.TagInfoReceiver tagInfo = new MainActivity.TagInfoReceiver(handler, urlFull); 33 ExecutorService executorService = Executors.newSingleThreadExecutor(); 34 executorService.submit(tagInfo); 35 } 36 37 //非同期でAPIにアクセスするためのクラス 38 private class TagInfoReceiver implements Runnable{ 39 //ハンドラオブジェクト 40 private final Handler _handler; 41 //情報取得のURL 42 private final String _urlFull; 43 44 //コンストラクタ(ハンドラオブジェクトの受け取り) 45 public TagInfoReceiver(Handler handler , String urlFull){ 46 _handler = handler; 47 _urlFull = urlFull; 48 } 49 50 @WorkerThread 51 @Override 52 public void run() { 53 //ここにWEBAPIにアクセスするコード 54 //HTTP接続を行うオブジェクト宣言 55 HttpURLConnection con = null; 56 //レスポンスデータを取得するInputStringオブジェクトを宣言 57 InputStream is = null; 58 //JSON文字列を格納 59 String result = ""; 60 61 try { 62 //URLオブジェクトを生成 63 java.net.URL url = new URL(_urlFull); 64 //URLオブジェクトからHttpURLConnectionオブジェクトを取得 65 con = (HttpURLConnection) url.openConnection(); 66 //各種タイム設定 67 con.setConnectTimeout(1000); 68 con.setReadTimeout(1000); 69 //GET通信に指定 70 con.setRequestMethod("GET"); 71 //接続開始 72 con.connect(); 73 //レスポンスデータを取得 74 is = con.getInputStream(); 75 //レスポンスデータのInputStringオブジェクトを文字列に変換 76 result = is2String(is); 77 } 78 catch (MalformedURLException ex) { 79 Log.e(DEBUG_TAG, "URL変換失敗", ex); 80 } 81 catch (SocketTimeoutException ex) { 82 Log.w(DEBUG_TAG, "通信タイムアウト", ex); 83 } 84 catch (IOException ex){ 85 Log.e(DEBUG_TAG, "通信失敗", ex); 86 } 87 finally { 88 if(con != null) { 89 con.disconnect(); 90 } 91 if(is != null) { 92 try { 93 is.close(); 94 } 95 catch (IOException ex) { 96 Log.e(DEBUG_TAG, "InputStream解放失敗", ex); 97 } 98 } 99 } 100 MainActivity.TagInfoPostExecutor postExecutor = new MainActivity.TagInfoPostExecutor(result); 101 _handler.post(postExecutor); 102 } 103 104 //InputStreamをStringに変換する定型文 105 private String is2String(InputStream is) throws IOException { 106 BufferedReader reader = new BufferedReader(new InputStreamReader(is, "UTF-8")); 107 StringBuffer sb = new StringBuffer(); 108 char[] b = new char[1024]; 109 int line; 110 while (0 <= (line = reader.read(b))) { 111 sb.append(b, 0, line); 112 } 113 return sb.toString(); 114 } 115 } 116 117 private class TagInfoPostExecutor extends MainActivity implements Runnable { 118 119 //取得したJSON文字列 120 private final String _result; 121 //コンストラクタ 122 public TagInfoPostExecutor(String result) { 123 _result = result; 124 } 125 126//ここのコードに問題? 127 @UiThread 128 @Override 129 public void run(){ 130 //ここにUIスレッドで行う処理コード 131 String tag = ""; 132 ArrayList<String> taglist = new ArrayList<String>(); 133 try { 134 JSONArray rootJSON = new JSONArray(_result); 135 for(int i=0; i<rootJSON.length(); i++) { 136 tag = rootJSON.getJSONObject(i).getString("tag"); 137 taglist.add(tag); 138 } 139 ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, taglist); 140 ListView lvtag = findViewById(R.id.lvtag); 141 lvtag.setAdapter(adapter); 142 } 143 catch (JSONException ex) { 144 Log.e(DEBUG_TAG, "JSON解析失敗", ex); 145 } 146 } 147 } 148 149 class ListItemClickListener implements AdapterView.OnItemClickListener{ 150 @Override 151 public void onItemClick(AdapterView<?> parent, View view, int position, long id) { 152 // リストデータの取得 153 154 //tagnameに選択したリストのtagを格納する処理 155 156 // インテント生成 157 Intent intent = new Intent(MainActivity.this, SelectActivity.class); 158 // 次画面に送るデータを格納 159 intent.putExtra("tagname", tagname); 160 // 次画面を起動 161 startActivity(intent); 162 } 163 } 164}
先のURLで処理しているコードです
python
1from flask import Flask, app, jsonify, g 2import sqlite3 3 4app = Flask(__name__) 5#JSONでの日本語の文字化け阻止 6app.config['JSON_AS_ASCII'] = False 7 8#DBに接続 9def get_db(): 10 if 'db' not in g: 11 g.db = sqlite3.connect("sample.sqlite3") 12 return g.db 13#DBとの接続を終了 14def close_db(e=None): 15 db = g.pop('db', None) 16 if db is not None: 17 db.close() 18 19 20@app.route('/', methods=["GET"]) 21def index(): 22 db = get_db() 23 cur = db.execute("select * from mydata") 24 cur.row_factory = sqlite3.Row 25 mydata = [dict(row) for row in cur.fetchall()] 26 return jsonify(mydata) 27 28if __name__ == "__main__": 29 app.run(host='ローカルURL', port=5000, debug=True)
分からないこと
現状、起きている不具合は「処理は動くがListviewに要素が表示されていない」という事象です。
表示されていないということは、taglistに要素が追加されていないと思うのですが、どのように改良すればよいのかわからない状態です。
これに加え、Listviewを選択した際に選択したtagの名前の情報を次の画面へ渡したいのですが、tagnameに選択したリストのtagを格納するコードがわかりません。。
上記の2点、ご教授いただければ幸いです。
回答1件
あなたの回答
tips
プレビュー