This tutorial will describe how to develop a forecast weather app in Android. In this tutorial, we will explore what we need to develop a forecast weather app and what are the bricks we can use to create our app.
We already know how to develop an android weather app with current weather information. We will develop a forecast weather app with weather current condition and weather forecast. You can give a look here to know how to retrieve current user position and the corresponding city name.
To develop an android application we need at least:
- An activity
- a Layout
These are the basic component we can use. Of course we want to create some more complex because we have to retrieve information from a remote server (in our case the openweathermap), and we have to parse the result data. To develop an Android app we need to add to the basic components:
- HTTP connection
- AsyncTask (to not have ANR problems)
- JSON parsing
- Data model (that holds the JSON data)
At the end we will obtain:
Develop a forecast weather app: App Layout
The first step is creating the layout. As you can see from the image below our layout is divided in two sections: one that holds the current weather condition and the other that holds the forecast weather. In the forecast weather we have to move among different days so we can use a ViewPager. We can use in this case a LinearLayout:
Now we have our layout we can start working on each section. In the first section (current
android:layout_width=”match_parent”
android:layout_height=”match_parent”
android:paddingBottom=”@dimen/activity_vertical_margin”
android:paddingLeft=”@dimen/activity_horizontal_margin”
android:paddingRight=”@dimen/activity_horizontal_margin”
android:paddingTop=”@dimen/activity_vertical_margin”
tools:context=”.MainActivity”
android:layout_weight=”1″>
<TextView
android:id=”@+id/cityText”
style=”?android:attr/textAppearanceMedium”
android:layout_width=”wrap_content”
android:layout_height=”wrap_content”
android:layout_alignParentLeft=”true”>
</TextView>
<TextView
android:id=”@+id/temp”
style=”@style/tempStyle”
android:layout_width=”wrap_content”
android:layout_height=”wrap_content”
android:layout_below=”@id/cityText”
android:layout_centerHorizontal=”true”>
</TextView>
<TextView
android:id=”@+id/unittemp”
android:layout_width=”wrap_content”
style=”?android:attr/textAppearanceMedium”
android:layout_height=”wrap_content”
android:layout_below=”@id/cityText”
android:layout_toRightOf=”@id/temp”
android:layout_alignBaseline=”@id/temp”>
</TextView>
<TextView
android:id=”@+id/skydesc”
android:layout_width=”wrap_content”
style=”?android:attr/textAppearanceMedium”
android:layout_height=”wrap_content”
android:layout_below=”@id/temp”
android:layout_alignStart=”@id/temp”
android:layout_toRightOf=”@id/temp”>
</TextView>
<!– Image weather condition –>
<ImageView android:id=”@+id/condIcon”
android:layout_height=”wrap_content”
android:layout_width=”wrap_content”
android:layout_alignTop=”@id/temp”
android:layout_toRightOf=”@id/temp”/>
</RelativeLayout>[/xml]
In the second section, as we said we have to show several day forecast. In this case we can use a ViewPager that helps us to swipe between pages, so we have:
[xml]<android.support.v4.view.ViewPagerandroid:id=”@+id/pager”
android:layout_width=”match_parent”
android:layout_height=”match_parent”
android:layout_weight=”6″>
<android.support.v4.view.PagerTitleStrip
android:id=”@+id/pager_title_strip”
android:layout_width=”match_parent”
android:layout_height=”wrap_content”
android:layout_gravity=”top”
android:background=”#E6E6E6″
android:paddingBottom=”4dp”
android:paddingTop=”4dp”
android:textColor=”#fff” />
</android.support.v4.view.ViewPager>[/xml]
This is our layout. We have now to fill it we the forecast weather data.
HTTP, AsyncTask and json data parsing
The next step is retrieving data using HTTP connection with an asynctask to avoid a ANR problem. Once we have our data we will parse it using JSON parser.
Let’s ask we our browser the weather forecast using this link:
http://api.openweathermap.org/data/2.5/forecast/daily?q=Rome,IT&mode=json&units=metric&cnt=3
where cnt is the number of the days we want to have the weather condition. The result is shown below:
“cod”: “200”,
“message”: 0.0192,
“city”: {
“id”: “3169070”,
“name”: “Rome”,
“coord”: {
“lon”: 12.4958,
“lat”: 41.903
},
“country”: “Italy”,
“population”: 0
},
“cnt”: 7,
“list”: [
{
“dt”: 1377774000,
“temp”: {
“day”: 26.83,
“min”: 16.41,
“max”: 29.12,
“night”: 16.41,
“eve”: 24.81,
“morn”: 26.83
},
“pressure”: 1007.2,
“humidity”: 72,
“weather”: [
{
“id”: 800,
“main”: “Clear”,
“description”: “sky is clear”,
“icon”: “01d”
}
],
“speed”: 0.71,
“deg”: 146,
“clouds”: 0
},
{
“dt”: 1377860400,
“temp”: {
“day”: 29.84,
“min”: 16.8,
“max”: 29.84,
“night”: 16.8,
“eve”: 24.81,
“morn”: 17.93
},
“pressure”: 1006.68,
“humidity”: 50,
“weather”: [
{
“id”: 800,
“main”: “Clear”,
“description”: “sky is clear”,
“icon”: “02d”
}
],
“speed”: 2.2,
“deg”: 235,
“clouds”: 8
},
{
“dt”: 1377946800,
“temp”: {
“day”: 29.14,
“min”: 14.11,
“max”: 29.14,
“night”: 14.11,
“eve”: 24.08,
“morn”: 18.32
},
“pressure”: 1005.17,
“humidity”: 45,
“weather”: [
{
“id”: 801,
“main”: “Clouds”,
“description”: “few clouds”,
“icon”: “02d”
}
],
“speed”: 1.56,
“deg”: 320,
“clouds”: 20
},
{
“dt”: 1378033200,
“temp”: {
“day”: 28.43,
“min”: 12.11,
“max”: 28.95,
“night”: 14.28,
“eve”: 23.89,
“morn”: 12.11
},
“pressure”: 1005.23,
“humidity”: 39,
“weather”: [
{
“id”: 800,
“main”: “Clear”,
“description”: “sky is clear”,
“icon”: “01d”
}
],
“speed”: 1.55,
“deg”: 289,
“clouds”: 0
},
{
“dt”: 1378119600,
“temp”: {
“day”: 29.83,
“min”: 16.02,
“max”: 29.83,
“night”: 18.86,
“eve”: 25.35,
“morn”: 16.02
},
“pressure”: 1006.57,
“humidity”: 32,
“weather”: [
{
“id”: 800,
“main”: “Clear”,
“description”: “sky is clear”,
“icon”: “01d”
}
],
“speed”: 3.3,
“deg”: 292,
“clouds”: 0
},
{
“dt”: 1378206000,
“temp”: {
“day”: 27.76,
“min”: 19.68,
“max”: 27.76,
“night”: 19.68,
“eve”: 25,
“morn”: 20.25
},
“pressure”: 1014.89,
“humidity”: 0,
“weather”: [
{
“id”: 800,
“main”: “Clear”,
“description”: “sky is clear”,
“icon”: “01d”
}
],
“speed”: 4.05,
“deg”: 298,
“clouds”: 0
},
{
“dt”: 1378292400,
“temp”: {
“day”: 27.85,
“min”: 19.91,
“max”: 27.85,
“night”: 19.91,
“eve”: 24.78,
“morn”: 20.13
},
“pressure”: 1017.2,
“humidity”: 0,
“weather”: [
{
“id”: 800,
“main”: “Clear”,
“description”: “sky is clear”,
“icon”: “01d”
}
],
“speed”: 1.91,
“deg”: 252,
“clouds”: 0
}
] }[/plain]
Analyzing the result we find out that the information we are looking for are inside the list tag and this an array. To hold this information we can create two classes on that hold the daily forecast and the other that hold the daily forecast classes:
[java]public class DayForecast {private static SimpleDateFormat sdf = new SimpleDateFormat(“dd/MM/yyyy”);
public Weather weather = new Weather();
public ForecastTemp forecastTemp = new ForecastTemp();
public long timestamp;
public class ForecastTemp {
public float day;
public float min;
public float max;
public float night;
public float eve;
public float morning;
}
public String getStringDate() {
return sdf.format(new Date(timestamp));
}
}[/java]
and the other one:
[java]public class WeatherForecast {private List<DayForecast> daysForecast = new ArrayList<DayForecast>();
public void addForecast(DayForecast forecast) {
daysForecast.add(forecast);
System.out.println(“Add forecast [“+forecast+”]”);
}
public DayForecast getForecast(int dayNum) {
return daysForecast.get(dayNum);
}
}[/java]
Now we have our data model and we have simply parse the JSON data using a simple class like the one used in the previous post (JSONWeatherParser).
Now it is time to go on with forecast weather app development, it is necessary to retrieve the data and parse it.
[java]public static WeatherForecast getForecastWeather(String data) throws JSONException {WeatherForecast forecast = new WeatherForecast();
// We create out JSONObject from the data
JSONObject jObj = new JSONObject(data);
JSONArray jArr = jObj.getJSONArray(“list”); // Here we have the forecast for every day
// We traverse all the array and parse the data
for (int i=0; i < jArr.length(); i++) {
JSONObject jDayForecast = jArr.getJSONObject(i);
// Now we have the json object so we can extract the data
DayForecast df = new DayForecast();
// We retrieve the timestamp (dt)
df.timestamp = jDayForecast.getLong(“dt”);
// Temp is an object
JSONObject jTempObj = jDayForecast.getJSONObject(“temp”);
df.forecastTemp.day = (float) jTempObj.getDouble(“day”);
df.forecastTemp.min = (float) jTempObj.getDouble(“min”);
df.forecastTemp.max = (float) jTempObj.getDouble(“max”);
df.forecastTemp.night = (float) jTempObj.getDouble(“night”);
df.forecastTemp.eve = (float) jTempObj.getDouble(“eve”);
df.forecastTemp.morning = (float) jTempObj.getDouble(“morn”);
// Pressure and Humidity
df.weather.currentCondition.setPressure((float) jDayForecast.getDouble(“pressure”));
df.weather.currentCondition.setHumidity((float) jDayForecast.getDouble(“humidity”));
// …and now the weather
JSONArray jWeatherArr = jDayForecast.getJSONArray(“weather”);
JSONObject jWeatherObj = jWeatherArr.getJSONObject(0);
df.weather.currentCondition.setWeatherId(getInt(“id”, jWeatherObj));
df.weather.currentCondition.setDescr(getString(“description”, jWeatherObj));
df.weather.currentCondition.setCondition(getString(“main”, jWeatherObj));
df.weather.currentCondition.setIcon(getString(“icon”, jWeatherObj));
forecast.addForecast(df);
}
return forecast;
}[/java]
Well done! What do we need more?…Well we have to handle the ViewPager and create the adapter to hold everyday forecast.
ViewPager, Fragments and the adapter
The first thing we have to create our adapter that handles each fragment that shows the forecast weather:
[java]public class DailyForecastPageAdapter extends FragmentPagerAdapter {private int numDays;
private FragmentManager fm;
private WeatherForecast forecast;
private final static SimpleDateFormat sdf = new SimpleDateFormat(“E, dd-MM”);
public DailyForecastPageAdapter(int numDays, FragmentManager fm,
WeatherForecast forecast) {
super(fm);
this.numDays = numDays;
this.fm = fm;
this.forecast = forecast;
}
// Page title
@Override
public CharSequence getPageTitle(int position) {
// We calculate the next days adding position to the current date
Date d = new Date();
Calendar gc = new GregorianCalendar();
gc.setTime(d);
gc.add(GregorianCalendar.DAY_OF_MONTH, position);
return sdf.format(gc.getTime());
}
@Override
public Fragment getItem(int num) {
DayForecast dayForecast = (DayForecast) forecast.getForecast(num);
DayForecastFragment f = new DayForecastFragment();
f.setForecast(dayForecast);
return f;
}
/*
* Number of the days we have the forecast
*/
@Override
public int getCount() {
return numDays;
}
}[/java]
Two methods are important: one that “create” the fragment and another one that “create” the page title. The first one instantiate a fragment that shows the daily forecat passing the dayForecast data and the other one create the page tile using GregorianCalendar.
The last step is coding the fragment:
…
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.dayforecast_fragment,
container, false);
TextView tempView = (TextView) v.findViewById(R.id.tempForecast);
TextView descView = (TextView) v.findViewById(R.id.skydescForecast);
tempView.setText( (int) (dayForecast.forecastTemp.min – 275.15) + “-”
+ (int) (dayForecast.forecastTemp.max – 275.15) );
descView.setText(dayForecast.weather.currentCondition.getDescr());
iconWeather = (ImageView) v.findViewById(R.id.forCondIcon);
// Now we retrieve the weather icon
JSONIconWeatherTask task = new JSONIconWeatherTask();
task.execute(new String[]{dayForecast.weather.currentCondition.getIcon()});
return v;
}
…
}[/java]
In the onCreateView we inflate our layout and retrieve with (AsyncTask) the weather icon.
At the end, you know how to develop a forecast weather app in Android and how to code it.
Thank you so much, this is amazing!
How can this be used with a navigation drawer implementation, for example i want the app to implement a navigation drawer for switching cities?
There's an example about navigation drawer in my blog look here https://www.survivingwithandroid.com/2013/06/navigation-drawer-with-account-picker.html
Thx man
Is there any way to get the weather forecast without a pager? e.g populate the forecast temps in a grid view?
You can modify the source code as you prefer. Of course you can create a gridview and fill it with the forecast.
i run this program but ERROR this log cat
09-20 22:48:19.928: W/dalvikvm(19427): Unable to resolve superclass of Lcom/survivingwithandroid/weatherapp/MainActivity; (9)
09-20 22:48:19.928: W/dalvikvm(19427): Link of class 'Lcom/survivingwithandroid/weatherapp/MainActivity;' failed
09-20 22:48:19.928: W/dalvikvm(19427): threadid=1: thread exiting with uncaught exception (group=0x40b019f0)
09-20 22:48:19.948: E/AndroidRuntime(19427): FATAL EXCEPTION: main
09-20 22:48:19.948: E/AndroidRuntime(19427): java.lang.RuntimeException: Unable to instantiate activity ComponentInfo{com.survivingwithandroid.weatherapp/com.survivingwithandroid.weatherapp.MainActivity}: java.lang.ClassNotFoundException: com.survivingwithandroid.weatherapp.MainActivity
09-20 22:48:19.948: E/AndroidRuntime(19427): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1880)
09-20 22:48:19.948: E/AndroidRuntime(19427): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1981)
09-20 22:48:19.948: E/AndroidRuntime(19427): at android.app.ActivityThread.access$600(ActivityThread.java:123)
09-20 22:48:19.948: E/AndroidRuntime(19427): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1147)
09-20 22:48:19.948: E/AndroidRuntime(19427): at android.os.Handler.dispatchMessage(Handler.java:99)
09-20 22:48:19.948: E/AndroidRuntime(19427): at android.os.Looper.loop(Looper.java:137)
09-20 22:48:19.948: E/AndroidRuntime(19427): at android.app.ActivityThread.main(ActivityThread.java:4424)
09-20 22:48:19.948: E/AndroidRuntime(19427): at java.lang.reflect.Method.invokeNative(Native Method)
09-20 22:48:19.948: E/AndroidRuntime(19427): at java.lang.reflect.Method.invoke(Method.java:511)
09-20 22:48:19.948: E/AndroidRuntime(19427): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:817)
09-20 22:48:19.948: E/AndroidRuntime(19427): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:584)
09-20 22:48:19.948: E/AndroidRuntime(19427): at dalvik.system.NativeStart.main(Native Method)
09-20 22:48:19.948: E/AndroidRuntime(19427): Caused by: java.lang.ClassNotFoundException: com.survivingwithandroid.weatherapp.MainActivity
09-20 22:48:19.948: E/AndroidRuntime(19427): at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:61)
09-20 22:48:19.948: E/AndroidRuntime(19427): at java.lang.ClassLoader.loadClass(ClassLoader.java:501)
09-20 22:48:19.948: E/AndroidRuntime(19427): at java.lang.ClassLoader.loadClass(ClassLoader.java:461)
09-20 22:48:19.948: E/AndroidRuntime(19427): at android.app.Instrumentation.newActivity(Instrumentation.java:1023)
09-20 22:48:19.948: E/AndroidRuntime(19427): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1871)
09-20 22:48:19.948: E/AndroidRuntime(19427): … 11 more
I guess you should rebuilt the project. Otherwise try to create a new project and just copy the source classes and the resources. Let me know!
Could you give me a link on how to do that?
Hi. Your app was very helpfull for me as example.
But I have one problem, app crash on change screen orientation. How to fix this promlem?
The current weather images dont load sometimes, what could be causing this?
AFAIK sometimes some images doesn't exist on the server, so the app doesn't show it. You shold create your mapping between the weather icon codes and images and add these images inside your apk.
There should be a NPE.
@Override
protected void onPostExecute(WeatherForecast forecastWeather) {
super.onPostExecute(forecastWeather);
DailyForecastPageAdapter adapter = new DailyForecastPageAdapter(Integer.parseInt(forecastDaysNum), getFragmentManager(), forecastWeather);
pager.setAdapter(adapter);
}
i changed getsupportmanager() to getFragmentManager() because i changed fragment activity to fragment because i need to display this page in fragment.
issue is no error but tempforecast and skydescforecsat are not displayed plz help
Hi, I am a beginner as well and I am facing up the same problem as wallace and the user below him, no images and temperature are visible in my emulator. I downloaded the entire source code from github. I see that few users asked about how to perform mapping between the weather icon codes and images and that these are to be added to the apk. How to do it?
Sorry for the delay in my answer. I will try to setup something that reproduces your code and check if it still works.
Well reading in the openmap website you can find the weather code. You could simply create an HashMap with the weather code and the drawable resource Id. I suggest to you to use a city name that exists and it is well known. then try with your city name.
If you don't want to use the standard icon you can create a simple Map where the key is the weather code returned in JSON and the value is the resource id you want to show for that weather condition
Hi,
May I ask how to get the weather of the current location instead of London, UK?
as I see from the original codes as below:
String city = "London, UK";
String lang = "en";
Thanks for answering. =)
Well there is a step you have to do before requesting the current weather condition. You have to query about the cities and get the right one. You can use "http://api.openweathermap.org/data/2.5/find?mode=json&type=like&q=" to query for the city and let the user chooses one. The q parameter is the part of the name of the city
Hi Thanks for the quick response.
I am actually new to the use of web service.
Can provide me some clues on how to implement the link given into the codes?
From the link I only see {"message":"","cod":"404"} without the q parameter.
Sorry for disturbing =(
Hi,
I really liked this tutorial and wanted to include it as a fragment inside my FragmentActivity. My app crashes each time giving a NPE. I really want to put this as part of my project. Can you please help?
Exact code is in here:
http://stackoverflow.com/questions/21910164/possible-to-have-a-fragmentpageradapter-inside-fragment-which-is-a-part-of-fragm
I also tried converting the DailyForecastPageAdapter to extend FragmentStatePagerAdapter but it did not solve anything. Please help!!
Thanks!
Hi, I am also new to android programming. I have replaced city in the code .. It works but If you can tell me how can I give an option to a user that he can select the city after running the application, if wants to view temperature of other cities. Thanks in advance .. Cheers
I’ve developed a new library ready-to-use that u can use to simplify your work. Give a look here https://www.survivingwithandroid.com/2014/04/android-weatherlib-to-create-app.html. You can find all the information you need. The library helps you to create weather app. If you like it don’t forget to +1 and give a start to github!! 🙂
Hi, I am also new to android programming. I have replaced city in the code .. It works but If you can tell me how can I give an option to a user that he can select the city after running the application, if wants to view temperature of other cities. Thanks in advance .. Cheers
Give a look at https://www.survivingwithandroid.com/2014/04/android-weatherlib-to-create-app.html
Hello Sir.
First of all thanku very Much for this weather tutorial.
i want to know
Is any limits of uses of yahoo weather api in Android ?
You should read the ‘Terms of use’. Anyway as far as i know, i think there aren’t limit for personal use but you should ask for commercial use.
Hello Sir.
First of all thanku very Much for this weather tutorial.
i want to know
Is any limits of uses of yahoo weather api in Android ?
You should read the 'Terms of use'. Anyway as far as i know, i think there aren't limit for personal use but you should ask for commercial use.
I am working in a smartphone apps development company. Very nice post
06-22 17:16:58.401: E/AndroidRuntime(20681): FATAL EXCEPTION: main
06-22 17:16:58.401: E/AndroidRuntime(20681): Process: com.survivingwithandroid.weatherapp, PID: 20681
06-22 17:16:58.401: E/AndroidRuntime(20681): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.survivingwithandroid.weatherapp/com.survivingwithandroid.weatherapp.MainActivity}: java.lang.NullPointerException: Attempt to read from field ‘com.survivingwithandroid.weatherapp.model.DayForecast$ForecastTemp com.survivingwithandroid.weatherapp.model.DayForecast.forecastTemp’ on a null object reference
06-22 17:16:58.401: E/AndroidRuntime(20681): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2693)
06-22 17:16:58.401: E/AndroidRuntime(20681): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2758)
06-22 17:16:58.401: E/AndroidRuntime(20681): at android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:4462)
06-22 17:16:58.401: E/AndroidRuntime(20681): at android.app.ActivityThread.access$1000(ActivityThread.java:177)
06-22 17:16:58.401: E/AndroidRuntime(20681): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1454)
06-22 17:16:58.401: E/AndroidRuntime(20681): at android.os.Handler.dispatchMessage(Handler.java:102)
06-22 17:16:58.401: E/AndroidRuntime(20681): at android.os.Looper.loop(Looper.java:145)
06-22 17:16:58.401: E/AndroidRuntime(20681): at android.app.ActivityThread.main(ActivityThread.java:5942)
06-22 17:16:58.401: E/AndroidRuntime(20681): at java.lang.reflect.Method.invoke(Native Method)
06-22 17:16:58.401: E/AndroidRuntime(20681): at java.lang.reflect.Method.invoke(Method.java:372)
06-22 17:16:58.401: E/AndroidRuntime(20681): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1388)
06-22 17:16:58.401: E/AndroidRuntime(20681): Caused by: java.lang.NullPointerException: Attempt to read from field ‘com.survivingwithandroid.weatherapp.model.DayForecast$ForecastTemp com.survivingwithandroid.weatherapp.model.DayForecast.forecastTemp’ on a null object reference
06-22 17:16:58.401: E/AndroidRuntime(20681): at com.survivingwithandroid.weatherapp.fragment.DayForecastFragment.onCreateView(DayForecastFragment.java:61)
06-22 17:16:58.401: E/AndroidRuntime(20681): at android.support.v4.app.Fragment.performCreateView(Fragment.java:1478)
06-22 17:16:58.401: E/AndroidRuntime(20681): at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:927)
06-22 17:16:58.401: E/AndroidRuntime(20681): at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1104)
06-22 17:16:58.401: E/AndroidRuntime(20681): at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1086)
06-22 17:16:58.401: E/AndroidRuntime(20681): at android.support.v4.app.FragmentManagerImpl.dispatchActivityCreated(FragmentManager.java:1877)
06-22 17:16:58.401: E/AndroidRuntime(20681): at android.support.v4.app.FragmentActivity.onStart(FragmentActivity.java:552)
06-22 17:16:58.401: E/AndroidRuntime(20681): at android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1234)
06-22 17:16:58.401: E/AndroidRuntime(20681): at android.app.Activity.performStart(Activity.java:6329)
06-22 17:16:58.401: E/AndroidRuntime(20681): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2656)
06-22 17:16:58.401: E/AndroidRuntime(20681): FATAL EXCEPTION: main
06-22 17:16:58.401: E/AndroidRuntime(20681): Process: com.survivingwithandroid.weatherapp, PID: 20681
06-22 17:16:58.401: E/AndroidRuntime(20681): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.survivingwithandroid.weatherapp/com.survivingwithandroid.weatherapp.MainActivity}: java.lang.NullPointerException: Attempt to read from field 'com.survivingwithandroid.weatherapp.model.DayForecast$ForecastTemp com.survivingwithandroid.weatherapp.model.DayForecast.forecastTemp' on a null object reference
06-22 17:16:58.401: E/AndroidRuntime(20681): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2693)
06-22 17:16:58.401: E/AndroidRuntime(20681): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2758)
06-22 17:16:58.401: E/AndroidRuntime(20681): at android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:4462)
06-22 17:16:58.401: E/AndroidRuntime(20681): at android.app.ActivityThread.access$1000(ActivityThread.java:177)
06-22 17:16:58.401: E/AndroidRuntime(20681): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1454)
06-22 17:16:58.401: E/AndroidRuntime(20681): at android.os.Handler.dispatchMessage(Handler.java:102)
06-22 17:16:58.401: E/AndroidRuntime(20681): at android.os.Looper.loop(Looper.java:145)
06-22 17:16:58.401: E/AndroidRuntime(20681): at android.app.ActivityThread.main(ActivityThread.java:5942)
06-22 17:16:58.401: E/AndroidRuntime(20681): at java.lang.reflect.Method.invoke(Native Method)
06-22 17:16:58.401: E/AndroidRuntime(20681): at java.lang.reflect.Method.invoke(Method.java:372)
06-22 17:16:58.401: E/AndroidRuntime(20681): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1388)
06-22 17:16:58.401: E/AndroidRuntime(20681): Caused by: java.lang.NullPointerException: Attempt to read from field 'com.survivingwithandroid.weatherapp.model.DayForecast$ForecastTemp com.survivingwithandroid.weatherapp.model.DayForecast.forecastTemp' on a null object reference
06-22 17:16:58.401: E/AndroidRuntime(20681): at com.survivingwithandroid.weatherapp.fragment.DayForecastFragment.onCreateView(DayForecastFragment.java:61)
06-22 17:16:58.401: E/AndroidRuntime(20681): at android.support.v4.app.Fragment.performCreateView(Fragment.java:1478)
06-22 17:16:58.401: E/AndroidRuntime(20681): at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:927)
06-22 17:16:58.401: E/AndroidRuntime(20681): at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1104)
06-22 17:16:58.401: E/AndroidRuntime(20681): at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1086)
06-22 17:16:58.401: E/AndroidRuntime(20681): at android.support.v4.app.FragmentManagerImpl.dispatchActivityCreated(FragmentManager.java:1877)
06-22 17:16:58.401: E/AndroidRuntime(20681): at android.support.v4.app.FragmentActivity.onStart(FragmentActivity.java:552)
06-22 17:16:58.401: E/AndroidRuntime(20681): at android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1234)
06-22 17:16:58.401: E/AndroidRuntime(20681): at android.app.Activity.performStart(Activity.java:6329)
06-22 17:16:58.401: E/AndroidRuntime(20681): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2656)
This bug happens when orientation is changed
This bug happens when orientation is changed
Hey is there anyway i could use the source code as a project for myself to play about wih?