We downloaded data from this server in Weather. See that app for printouts of the JSON that came from the server.
The download in this app had to be performed in the second thread, not in the UI thread, because it might take several seconds. But there is no reason that the current version of this app has to parse the JSON in the second thread. But I’m doing it in the sceond thread to make it easier to do the icon exercise. The JSON has to be parsed in order to get the names of the icon files, and the icon files can’t be downloaded by the UI thread, Parsing the JSON in the second thread makes it possible for the cons to be downloaded in the second thread.
In the project
Offer,
the
GridView
was fed by a
SimpleCursorAdapter
;
see that project’s
gridview_item.xml
file.
In the project
GridView,
the
GridView
was fed by an adapter we wrote ourselves.
We couldn’t use a
SimpleCursorAdapter
because we had no cursor.
And we couldn’t use an
ArrayAdapter
,
because an
ArrayAdapter
always creates
TextView
s.
In the project
Weather,
we downloaded JSON from
openweathermap.org
.
MainActivity.java
.
Class
MainActivity
contains the inner class
DownloadTask
.
ReportAdapter.java
.
activity_main.xml
is a
RelativeLayout
containing a
GridView
.
gridview_item.xml
is a vertical
LinearLayout
containing three
TextView
s
and eventually an
ImageView
.
strings.xml
dimens.xml
AndroidManifest.xml
has
uses-permission
INTERNET
.
build.gradle
(Module: app).
In the Android Studio
project
view,
select the layout folder.
File → New → XML → Layout XML File
Layout File Name: gridview_item
Root Tag: LinearLayout
Finish
LinearLayout
in
gridview_item.xml
.
<ImageView android:id="@+id/icon" android:layout_width="wrap_content" android:layout_height="wrap_content"/>
DownloadTask
.
A
Bitmap
holds the rows and columns of pixels that can be displayed by an
ImageView
.
Bitmap[] bitmap = new Bitmap[7];
doInBackground
method of class
DownloadTask
,
immediately after the
humidity[i] = day.getInt("humidity");insert the following.
JSONArray weather = day.getJSONArray("weather"); JSONObject w = (JSONObject)weather.get(0); String icon = w.getString("icon"); HttpURLConnection connection = null; InputStream inputStream = null; byte[] byteArray = null; try { URL url = new URL("http://openweathermap.org/img/w/" + icon + ".png"); connection = (HttpURLConnection)url.openConnection(); connection.setRequestMethod("GET"); connection.setDoInput(true); connection.connect(); // Read the response. inputStream = connection.getInputStream(); byte[] buffer = new byte[1024]; ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); while (inputStream.read(buffer) != -1) { outputStream.write(buffer); } byteArray = outputStream.toByteArray(); } catch (Exception exception) { Log.e("myTag", "doInBackground", exception); } finally { try { inputStream.close(); } catch(Exception exception) { Log.e("myTag", "doInBackground", exception); return null; } try { connection.disconnect(); } catch(Exception exception) { Log.e("myTag", "doInBackground", exception); return null; } } if (byteArray != null && byteArray.length > 0) { bitmap[i] = BitmapFactory.decodeByteArray(byteArray, 0, byteArray.length); }
onPostExecute
method of class
DownloadTask
,
add one more argument to the follwing constructor.
ReportAdapter reportAdapter = new ReportAdapter(MainActivity.this, date, humidity, temperature, bitmap);
ReportAdapter
.
Bitmap[] bitmap;Initialize the new field in the
ReportAdapter
constructor.
public ReportAdapter(/* four existing arguments */, Bitmap[] bitmap) { this.context = context; //etc. this.bitmap = bitmap; }
getView
method of class
ReportAdapter
immediately before the
return
.
ImageView imageView = (ImageView)linearLayout.findViewById(R.id.icon); imageView.setImageBitmap(bitmap[position]);
http://openweathermap.org/img/w/01d.png
layout_width
and
layout_height
of the
ImageView
in
gridview_item.xml
to
50dp
.
drawable
folder of the
res
folder.
Give the files names that start with a letter,
e.g.,
icon01d.png
.
The array of seven
BitMap
s
will become an array of seven
String
s
containing strings such as
"01d"
or
"01n"
(for
“day”
or
“night”).
The last argument of the constructor of
ReportAdapter
,
and the field you added to this class,
will also become
String
s; rename the field to
icon
.
The
getView
method of the
ReportAdapter
will say something like the following.
if (icon.equals("01d") { imageView.setImageResource(R.drawable.icon01d); } else if (icon.equals("01n") { //etc.There are 18 icons. What are the tradeoffs between download-before vs. download during execution?