This question is asked many times but earlier answers to it didn’t solve my problem. I am making an app which uses large string arrays in an non activity class which returns the array in any activity when used. The app didn’t give any error while compiling but crashes midway.
my code is as follows:
String[] busNamesSearch;
GetDBClass BDclassBuses;
AutoCompleteTextView searchView;
String BSquery;
Button searchButton;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_search_bus);
busNamesSearch = BDclassBuses.GetBusNameArrays();
searchView = (AutoCompleteTextView) findViewById(R.id.searchBusesView);
searchButton = (Button)findViewById(R.id.searchBusButton);
ArrayAdapter<String> arrayAdapter = new ArrayAdapter<>(this,
android.R.layout.simple_list_item_1, busNamesSearch);
searchView.setThreshold(1);
searchView.setAdapter(arrayAdapter);
Error Log is:
07-17 18:09:21.332 2548-2548/com.prinia.gaurav.Ppbus E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.prinia.gaurav.Ppbus, PID: 2548
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.prinia.gaurav.punebus/com.prinia.gaurav.Ppbus.SearchBusActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String[] com.prinia.gaurav.Ppbus.GetDBClass.GetBusNameArrays()' on a null object reference
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2646)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2707)
at android.app.ActivityThread.-wrap12(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1460)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6077)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:865)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:755)
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String[] com.prinia.gaurav.Ppbus.GetDBClass.GetBusNameArrays()' on a null object reference
at com.prinia.gaurav.Ppbus.SearchBusActivity.onCreate(SearchBusActivity.java:26)
at android.app.Activity.performCreate(Activity.java:6662)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1118)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2599)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2707)
at android.app.ActivityThread.-wrap12(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1460)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6077)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:865)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:755)
The error line which seems to be causing problems is:
busNamesSearch = BDclassBuses.GetBusNameArrays();
I don’t what to do now.I have tried every way I could find.
asked Jul 17, 2017 at 12:50
10
Just note for future reference. Null pointer occurs if you access any method/variable of a class without initializing it. In a very naive version it happens whenever you do null.something.
So if you ever face null pointer on any line, check if you have anyway done null.something.
And a class reference is null till the point an object is not created. Usually an object creation line looks like
ClassName referenceName = new ClassName()
Where the part on the right hand side of = is creating the object which you can access using the reference name which is on the left hand side of = sign
answered Jul 17, 2017 at 13:04
Kapil GKapil G
4,0711 gold badge20 silver badges32 bronze badges
Some times you just copy paste code from other sources. In this circumstances, your package name may be changed or not exist.
Check your Manifest file and see error in which activity it’s appear.
then go to activity and retype your package name and make sure your class exist in this package.
answered Dec 4, 2021 at 16:20
Find the function which is showing error and put that under try-catch block
.
In your case Its,
GetBusNameArrays()
Solution is,
try{
.......GetBusNameArrays()
}
catch (Exception e)
{
//To-do with expection
}
answered Dec 16, 2018 at 6:58
dgamerdgamer
1552 silver badges3 bronze badges
1
Привет, столкнулся с ошибкой, уже все просмотрел, все перешерстил, ничего не могу поделать.
Выдает ошибку :
java.lang.NullPointerException: Attempt to invoke virtual method 'java.util.List com.google.firebase.firestore.QuerySnapshot.getDocumentChanges()' on a null object reference
Логи с ошибкой :
Process: com.vuradoapps.mycity, PID: 8801
java.lang.NullPointerException: Attempt to invoke virtual method 'java.util.List com.google.firebase.firestore.QuerySnapshot.getDocumentChanges()' on a null object reference
at com.vuradoapps.mycity.Tasks_mini_app_Activity$3.onEvent(Tasks_mini_app_Activity.java:86)
at com.vuradoapps.mycity.Tasks_mini_app_Activity$3.onEvent(Tasks_mini_app_Activity.java:82)
at com.google.firebase.firestore.Query.lambda$addSnapshotListenerInternal$2$com-google-firebase-firestore-Query(Query.java:1131)
at com.google.firebase.firestore.Query$$ExternalSyntheticLambda2.onEvent(Unknown Source:6)
at com.google.firebase.firestore.core.AsyncEventListener.lambda$onEvent$0$com-google-firebase-firestore-core-AsyncEventListener(AsyncEventListener.java:42)
at com.google.firebase.firestore.core.AsyncEventListener$$ExternalSyntheticLambda0.run(Unknown Source:6)
at android.os.Handler.handleCallback(Handler.java:938)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:246)
at android.app.ActivityThread.main(ActivityThread.java:8653)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:602)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1130)
Код с активити на которую указывают логи :
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
import androidx.recyclerview.widget.ItemTouchHelper;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.content.DialogInterface;
import android.os.Bundle;
import android.view.View;
import com.google.android.material.floatingactionbutton.FloatingActionButton;
import com.google.firebase.firestore.DocumentChange;
import com.google.firebase.firestore.EventListener;
import com.google.firebase.firestore.FirebaseFirestore;
import com.google.firebase.firestore.FirebaseFirestoreException;
import com.google.firebase.firestore.ListenerRegistration;
import com.google.firebase.firestore.Query;
import com.google.firebase.firestore.QuerySnapshot;
import com.vuradoapps.mycity.Adapter.ToDoAdapter;
import com.vuradoapps.mycity.Model.ToDoModel;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
public class Tasks_mini_app_Activity extends AppCompatActivity implements OnDialogChooce{
private RecyclerView recyclerView;
private FloatingActionButton mFab;
private FirebaseFirestore firebaseFirestore;
private ToDoAdapter adapter;
private List<ToDoModel> mList;
private Query query;
private ListenerRegistration listenerRegistration;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_tasks_mini_app);
Toolbar toolbar = findViewById(R.id.app_bar);
setSupportActionBar(toolbar);
toolbar.setNavigationOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
onBackPressed();
}
});
recyclerView = findViewById(R.id.recycleView);
mFab = findViewById(R.id.floatingActionButton);
firebaseFirestore = FirebaseFirestore.getInstance();
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(Tasks_mini_app_Activity.this));
mFab.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Add_new_task.newInstance().show(getSupportFragmentManager(), Add_new_task.TAG);
}
});
mList = new ArrayList<>();
adapter = new ToDoAdapter(Tasks_mini_app_Activity.this, mList);
ItemTouchHelper itemTouchHelper = new ItemTouchHelper(new TouchHelper(adapter));
itemTouchHelper.attachToRecyclerView(recyclerView);
recyclerView.setAdapter(adapter);
showData();
}
private void showData(){
query = firebaseFirestore.collection("task").orderBy("time" , Query.Direction.DESCENDING);
listenerRegistration = query.addSnapshotListener(new EventListener<QuerySnapshot>() {
@Override
public void onEvent(@Nullable QuerySnapshot value, @Nullable FirebaseFirestoreException error) {
for (DocumentChange documentChange : value.getDocumentChanges()){
if (documentChange.getType() == DocumentChange.Type.ADDED){
String id = documentChange.getDocument().getId();
ToDoModel toDoModel = documentChange.getDocument().toObject(ToDoModel.class).withId(id);
mList.add(toDoModel);
adapter.notifyDataSetChanged();
}
}
listenerRegistration.remove();
}
});
}
@Override
public void onDialogClose(DialogInterface dialogInterface) {
mList.clear();
showData();
adapter.notifyDataSetChanged();
}
}
Я проверил строки, но ничего не нашел, строки на которые указывают логи, они обе тут :
private void showData(){
query = firebaseFirestore.collection("task").orderBy("time" , Query.Direction.DESCENDING);
listenerRegistration = query.addSnapshotListener(new EventListener<QuerySnapshot>() {
@Override
public void onEvent(@Nullable QuerySnapshot value, @Nullable FirebaseFirestoreException error) {
for (DocumentChange documentChange : value.getDocumentChanges()){
if (documentChange.getType() == DocumentChange.Type.ADDED){
String id = documentChange.getDocument().getId();
ToDoModel toDoModel = documentChange.getDocument().toObject(ToDoModel.class).withId(id);
mList.add(toDoModel);
adapter.notifyDataSetChanged();
}
}
listenerRegistration.remove();
}
});
}
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.pd.myapplication/com.pd.myapplication.DisplayData}: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.ListView.setAdapter(android.widget.ListAdapter)' on a null object reference
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2302)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2375)
at android.app.ActivityThread.access$800(ActivityThread.java:148)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1282)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5240)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:950)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:745)
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.ListView.setAdapter(android.widget.ListAdapter)' on a null object reference
at com.pd.myapplication.DisplayData.displayData(DisplayData.java:58)
at com.pd.myapplication.DisplayData.onCreate(DisplayData.java:28)
at android.app.Activity.performCreate(Activity.java:6008)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1105)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2255)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2375)
at android.app.ActivityThread.access$800(ActivityThread.java:148)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1282)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5240)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:950)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:745)
Null object reference error in android studio
so friends, in this error solution tutorial, we’ll discuss the error “null object reference”.
Often, we are fetching this type of error in android studio.
Also Read : one activity to another new activity
What do if you’re getting a null object reference error, however, you can solve it easily or not, although if you know android programming, and also you previously solved error then this will make you solve easily.
When and why does this error occur?
This is not a compile-time error but when you perform some task inactivity in your device or run your app fine, midway your application crashes. For example, you make two buttons, generally, one is submitted and another is displayed. However, clicking on the display button, the app crashes. For the most part of the android studio, this error happens due to a null object, which means you create the object, but you forgot casting, so at that time you getting an error.
How to solve null object reference error in android studio?
In this case, you don’t need to worry about this type of error because here given an accurate solution. Whenever you get this type of issue in your android studio, first, check you don’t forget initializing. Sometimes you define a pointer, but you forgot to assign it. So check variable then check method that it should be proper initialization. If you don’t understand, watch videos on YouTube.
If you have any queries regarding this post, feel free to contact or comment. Stay tuned.
This tutorial demonstrates how to solve the Attempt to invoke virtual method on a null object reference
error in Java.
the Attempt to invoke virtual method on a null object reference
Error in Java
While working on an Android application, the error Attempt to invoke virtual method on a null object reference
can occur, a type of NullPointerException
. Whenever we try to invoke a method using a null object, it will throw this error.
Here is a system based on the Android platform, which throws the NullPointerException
with the attempt to invoke virtual method on a null object reference
description.
This example has three different Java classes.
Main_Player.java
:
package delftstack;
import javax.naming.Context;
public class Main_Player {
private Context AppContext;
private SharedPreferences SharedPreferencesSettingsU;
private SharedPreferences.Editor PreferencesEditorU;
private static final int PREFERENCE_MODE = 0;
private static final String UNIQUE_PREFERENCES_FILE = "DemoApp";
public Player(Context AppContext, String Player_Name) {
this.AppContext = AppContext;
Save_Name(Player_Name);
}
public void Save_Name(String nValue) {
SharedPreferencesSettingsU = AppContext.getSharedPreferences(UNIQUE_PREFERENCES_FILE, PREFERENCE_MODE);
PreferencesEditorU = SharedPreferencesSettingsU.edit();
PreferencesEditorU.putString("keyName", nValue);
PreferencesEditorU.commit();
}
public String Get_Name(Context DemoContext) {
SharedPreferencesSettingsU = DemoContext.getSharedPreferences(UNIQUE_PREFERENCES_FILE, PREFERENCE_MODE);
String PlayerName = SharedPreferencesSettingsU.getString("keyName", "ANONYMOUS");
return PlayerName;
}
}
Player_Name.java
:
package delftstack;
import javax.naming.Context;
public class Player_Name extends Activity {
private EditText Player_Name;
private Player M_Player;
public static Context AppContext;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.player_name);
AppContext = this;
Player_Name = (EditText) findViewById (R.id.etName);
}
public void onC_Confirm(View btnclick) {
M_Player = new Player(AppContext, String.valueOf(Player_Name.getText()));
//M_Player.saveName();
Intent intent = new Intent(Player_Name.this, Game_Play.class);
startActivity(intent);
}
public void onC_testShPref(View btnclick) {
Intent intent = new Intent(Player_Name.this, Game_Play.class);
startActivity(intent);
}
Game_Play.java
:
public class Game_Play extends Activity {
private TextView Welcome_Player;
private ListView Games_Created;
private Player M_Player;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.play_game);
Welcome_Player = (TextView) findViewById (R.id.tvPlayer_Name);
Welcome_Player.setText("Welcome Back Player, " + String.valueOf(M_Player.getName(this)) + " !");
Games_Created = (ListView) findViewById (R.id.listCreatedGames);
Games_Created.setEmptyView(findViewById (R.id.tvNoGames));
}
}
We run the above system on an Android platform, which will throw an error caused by the java.lang.NullPointerException: Attempt to invoke virtual method
.
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String plp.cs4b.thesis.drawitapp.Main_Player.getName()' on a null object reference
at plp.cs4b.thesis.drawitapp.Game_Play.onCreate(Game_Play.java:20)
at android.app.Activity.performCreate(Activity.java:5933)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1105)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2251)
... 10 more
The error occurs in the below code line in the class Game_Play.java
.
Welcome_Player.setText("Welcome Back Player, " + String.valueOf(M_Player.getName(this)) + " !");
This error occurs because the M_Player
comes as Null
. After all, it is not initialized. By initializing, we can solve that issue.
See the solution:
Game_Play.java
:
package delftstack;
public class Game_Play extends Activity {
private TextView Welcome_Player;
private ListView Games_Created;
//initialize the M_Player
private Player M_Player = new Main_Player(AppContext,"");
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.play_game);
Welcome_Player = (TextView) findViewById (R.id.tvPlayer_Name);
Welcome_Player.setText("Welcome Back Player, " + String.valueOf(M_Player.getName(this)) + " !");
Games_Created = (ListView) findViewById (R.id.listCreatedGames);
Games_Created.setEmptyView(findViewById (R.id.tvNoGames));
}
}
So whenever working on a system like this, you must ensure that a method is not invoking any null
value; otherwise, it will throw this exception.
Comments
natansalda
added
triage me
I really want to be triaged.
type: bug
Error or flaw in code with unintended results or allowing sub-optimal usage patterns.
labels
Oct 21, 2021
barbeau
added
type: question
Request for information or clarification. Not an issue.
and removed
type: bug
Error or flaw in code with unintended results or allowing sub-optimal usage patterns.
triage me
I really want to be triaged.
labels
Oct 21, 2021
barbeau
changed the title
java.lang.NullPointerException: Attempt to invoke virtual method ‘int java.lang.String.hashCode()’ on a null object reference at pl.mytest.app.data.point.dto.AcceptancePoint.hashCode(Unknown Source:55) at com.google.maps.android.clustering.algo.NonHierarchicalDistanceBasedAlgorithm$QuadItem.hashCode(NonHierarchicalDistanceBasedAlgorithm.java:297)
java.lang.NullPointerException: Attempt to invoke virtual method ‘int java.lang.String.hashCode()’ on a null object reference
Oct 27, 2021
This post is specifically for a problem whose solution is usually hard to find (at least now). The solution is at the end.
Basically, the problem lies in the referencing method being used to make reference towards the current activity. The solution is to make the referencing dynamic. Read below for solution with code example.
Problem
- You are developing an android app.
- You have loaded a fragment.
- You are taking inputs from EditText and calculating.
- Moreover, you are showing the result in a TextView.
Basically, it looks like this,
Now, when the fragment is loaded and you fill in the values and press the button, you get this error in Logcat
java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.CharSequence android.widget.TextView.getText()' on a null object reference
As evident from my Logcat as well.
Problematic code is given below:
/** * Created by Codeonion on 9/26/2015. */ public class CustomFragmentClass extends Fragment implements View.OnClickListener{ TextView mFirstNumber; EditText mSecondNumber; TextView m_resultHolder; Button btnAdd; double num1, num2, result; @Nullable @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View fragmentHandle = inflater.inflate(R.layout.myLayoutName, container, false); btnAdd = (Button) fragmentHandle.findViewById(R.id.btnAdd); btnAdd.setOnClickListener(new OnClickListener() { @Override public void onClick(View view) { // Get references from the views mFirstNumber = (EditText) view.findViewById(R.id.inputParam_A); mSecondNumber = (EditText) view.findViewById(R.id.inputParam_B); m_resultHolder = (TextView) view.findViewById(R.id.textView_lblResult); // Get the actual usable values of views num1 = Double.parseDouble(mFirstNumber.getText().toString()); num2 = Double.parseDouble(mSecondNumber.getText().toString()); // Calculation Area result = num1 + num2; // Show Result m_resultHolder.setText(Double.toString(result)); } }); return fragmentHandle; } @Override public void onClick(View v) { } }
Solution
In my case, the problem was in the line 25, 26, 27. instead of “view.“, I need to dynamically get the current activity using “getActivity().“. As a result, the current activity reference is obtained dynamically and the error is resolved.
Here is the correct code. Please note the difference in lines 26, 26 and 27.
/** * Created by Codeonion on 9/26/2015. */ public class CustomFragmentClass extends Fragment implements View.OnClickListener{ TextView mFirstNumber; EditText mSecondNumber; TextView m_resultHolder; Button btnAdd; double num1, num2, result; @Nullable @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View fragmentHandle = inflater.inflate(R.layout.myLayoutName, container, false); btnAdd = (Button) fragmentHandle.findViewById(R.id.btnAdd); btnAdd.setOnClickListener(new OnClickListener() { @Override public void onClick(View view) { // Get references from the views mFirstNumber = (EditText) getActivity().findViewById(R.id.inputParam_A); mSecondNumber = (EditText) getActivity().findViewById(R.id.inputParam_B); m_resultHolder = (TextView) getActivity().findViewById(R.id.textView_lblResult); // Get the actual usable values of views num1 = Double.parseDouble(mFirstNumber.getText().toString()); num2 = Double.parseDouble(mSecondNumber.getText().toString()); // Calculation Area result = num1 + num2; // Show Result m_resultHolder.setText(Double.toString(result)); } }); return fragmentHandle; } @Override public void onClick(View v) { } }
Now, I will show you my app working.
Result
Now, when I input the values and press the button, the activities are obtained dynamically and the error does not appear any more.
As you see! swift arithmetic operation! Speaking of which, do check out my Android Tutorials Series for more!
Android Development Tutorials by Codeonion Learn more!
So I’ve followed this course a few times and this time through thought I would attempt a few changes. Like making the Dailylist an recycler view. I assumed I would run into some issue and where here we go. When I run my app and click the hourly button the app crashes.
Heres is the Monitor output
06-03 10:22:49.052 26737-26737/me.johnweland.tempest E/AndroidRuntime: FATAL EXCEPTION: main Process: me.johnweland.tempest, PID: 26737 java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.TextView.setText(java.lang.CharSequence)' on a null object reference at me.johnweland.tempest.adapter.HourAdapter$HourViewHolder.bindHour(HourAdapter.java:56) at me.johnweland.tempest.adapter.HourAdapter.onBindViewHolder(HourAdapter.java:31) at me.johnweland.tempest.adapter.HourAdapter.onBindViewHolder(HourAdapter.java:13) at android.support.v7.widget.RecyclerView$Adapter.onBindViewHolder(RecyclerView.java:5471) at android.support.v7.widget.RecyclerView$Adapter.bindViewHolder(RecyclerView.java:5504) at android.support.v7.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:4741) at android.support.v7.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:4617) at android.support.v7.widget.LinearLayoutManager$LayoutState.next(LinearLayoutManager.java:1994) at android.support.v7.widget.LinearLayoutManager.layoutChunk(LinearLayoutManager.java:1390) at android.support.v7.widget.LinearLayoutManager.fill(LinearLayoutManager.java:1353) at android.support.v7.widget.LinearLayoutManager.onLayoutChildren(LinearLayoutManager.java:574) at android.support.v7.widget.RecyclerView.dispatchLayoutStep2(RecyclerView.java:3028) at android.support.v7.widget.RecyclerView.dispatchLayout(RecyclerView.java:2906) at android.support.v7.widget.RecyclerView.onLayout(RecyclerView.java:3283) at android.view.View.layout(View.java:17508) at android.view.ViewGroup.layout(ViewGroup.java:5555) at android.widget.RelativeLayout.onLayout(RelativeLayout.java:1079) at android.view.View.layout(View.java:17508) at android.view.ViewGroup.layout(ViewGroup.java:5555) at android.widget.FrameLayout.layoutChildren(FrameLayout.java:323) at android.widget.FrameLayout.onLayout(FrameLayout.java:261) at android.view.View.layout(View.java:17508) at android.view.ViewGroup.layout(ViewGroup.java:5555) at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1737) at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1581) at android.widget.LinearLayout.onLayout(LinearLayout.java:1490) at android.view.View.layout(View.java:17508) at android.view.ViewGroup.layout(ViewGroup.java:5555) at android.widget.FrameLayout.layoutChildren(FrameLayout.java:323) at android.widget.FrameLayout.onLayout(FrameLayout.java:261) at android.view.View.layout(View.java:17508) at android.view.ViewGroup.layout(ViewGroup.java:5555) at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1737) at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1581) at android.widget.LinearLayout.onLayout(LinearLayout.java:1490) at android.view.View.layout(View.java:17508) at android.view.ViewGroup.layout(ViewGroup.java:5555) at android.widget.FrameLayout.layoutChildren(FrameLayout.java:323) at android.widget.FrameLayout.onLayout(FrameLayout.java:261) at com.android.internal.policy.DecorView.onLayout(DecorView.java:701) at android.view.View.layout(View.java:17508) at android.view.ViewGroup.layout(ViewGroup.java:5555) at android.view.ViewRootImpl.performLayout(ViewRootImpl.java:2319) at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2049) at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1240) at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:6298) at android.view.Choreographer$CallbackRecord.run(Choreographer.java:858) at android.view.Choreographer.doCallbacks(Choreographer.java:670) at android.view.Choreographer.doFrame(Choreographer.java:606) at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:844) at android.os.Handler.handleCallback(Handler.java:751) at android.os.Handler.dispatchMessage(Handler.java:95) at android.os.Looper.loop(Looper.java:154) at android.app.ActivityThread.main(ActivityThread.java:5969) at java.lang.reflect.Method.invoke(Native Method) 06-03 10:22:49.052 26737-26737/me.johnweland.tempest E/AndroidRuntime: at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:801) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:691)
HourlyActivity.java
package me.johnweland.tempest.ui; import android.content.Intent; import android.os.Bundle; import android.os.Parcelable; import android.support.design.widget.FloatingActionButton; import android.support.design.widget.Snackbar; import android.support.v7.app.AppCompatActivity; import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.RecyclerView; import android.support.v7.widget.Toolbar; import android.view.View; import java.util.Arrays; import butterknife.BindView; import butterknife.ButterKnife; import me.johnweland.tempest.R; import me.johnweland.tempest.adapter.HourAdapter; import me.johnweland.tempest.weather.Hour; public class HourlyActivity extends AppCompatActivity { private Hour[] mHours; @BindView(R.id.recyclerView) RecyclerView mRecyclerView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_hourly); ButterKnife.bind(this); Intent intent = getIntent(); Parcelable[] parcelables = intent.getParcelableArrayExtra(MainActivity.HOURLY_FORECAST); mHours = Arrays.copyOf(parcelables, parcelables.length, Hour[].class); HourAdapter adapter = new HourAdapter(mHours); mRecyclerView.setAdapter(adapter); RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(this); mRecyclerView.setLayoutManager(layoutManager); mRecyclerView.setHasFixedSize(true); } }
Hour.java
package me.johnweland.tempest.weather; import android.os.Parcel; import android.os.Parcelable; import java.text.SimpleDateFormat; import java.util.Date; public class Hour implements Parcelable{ private long mTime; private String mSummary; private double mTemperature; private String mIcon; private String mTimezone; public Hour() { } public long getTime() { return mTime; } public void setTime(long time) { mTime = time; } public String getTimezone() { return mTimezone; } public void setTimezone(String timezone) { mTimezone = timezone; } public String getIcon() { return mIcon; } public int getIconId() { return Forecast.getIconId(mIcon); } public void setIcon(String icon) { mIcon = icon; } public int getTemperature() { return (int) Math.round(mTemperature); } public void setTemperature(double temperature) { mTemperature = temperature; } public String getSummary() { return mSummary; } public void setSummary(String summary) { mSummary = summary; } public String getHour() { SimpleDateFormat formatter = new SimpleDateFormat("h a"); Date date = new Date(mTime * 1000); return formatter.format(date); } @Override public int describeContents() { return 0; // ignore } @Override public void writeToParcel(Parcel dest, int flags) { dest.writeLong(mTime); dest.writeDouble(mTemperature); dest.writeString(mSummary); dest.writeString(mIcon); dest.writeString(mTimezone); } private Hour(Parcel in) { mTime = in.readLong(); mTemperature = in.readDouble(); mSummary = in.readString(); mIcon = in.readString(); mTimezone = in.readString(); } public static final Creator<Hour> CREATOR = new Creator<Hour>() { @Override public Hour createFromParcel(Parcel source) { return new Hour(source); } @Override public Hour[] newArray(int size) { return new Hour[size]; } }; }
HourAdapter.java
package me.johnweland.tempest.adapter; import android.support.v7.widget.RecyclerView; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.ImageView; import android.widget.TextView; import me.johnweland.tempest.R; import me.johnweland.tempest.weather.Hour; public class HourAdapter extends RecyclerView.Adapter<HourAdapter.HourViewHolder> { private Hour[] mHours; public HourAdapter(Hour[] hours) { mHours = hours; } @Override public HourViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { View view = LayoutInflater.from(parent.getContext()) .inflate(R.layout.hourly_list_item, parent, false); HourViewHolder viewHolder = new HourViewHolder(view); return viewHolder; } @Override public void onBindViewHolder(HourViewHolder holder, int position) { holder.bindHour(mHours[position]); } @Override public int getItemCount() { return mHours.length; } public class HourViewHolder extends RecyclerView.ViewHolder { public TextView mTimeLabel; public TextView mSummaryLabel; public TextView mTemperatureLabel; public ImageView mIconImageView; public HourViewHolder(View itemView) { super(itemView); mTimeLabel = (TextView) itemView.findViewById(R.id.timeLabel); mSummaryLabel = (TextView) itemView.findViewById(R.id.summaryLabel); mTemperatureLabel = (TextView) itemView.findViewById(R.id.temperatureLabel); mIconImageView = (ImageView) itemView.findViewById(R.id.iconImageView); } public void bindHour(Hour hour){ mTimeLabel.setText(hour.getHour()); mSummaryLabel.setText(hour.getSummary()); mTemperatureLabel.setText(hour.getTemperature() + ""); mIconImageView.setImageResource(hour.getIconId()); } } }
MainActivity.java
package me.johnweland.tempest.ui; import android.app.Activity; import android.content.Context; import android.content.Intent; import android.graphics.drawable.Drawable; import android.net.ConnectivityManager; import android.net.NetworkInfo; import android.os.Bundle; import android.util.Log; import android.view.View; import android.widget.ImageView; import android.widget.ProgressBar; import android.widget.TextView; import android.widget.Toast; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; import java.io.IOException; import butterknife.BindView; import butterknife.ButterKnife; import butterknife.OnClick; import me.johnweland.tempest.R; import me.johnweland.tempest.ui.AlertDialogFragment; import me.johnweland.tempest.weather.Current; import me.johnweland.tempest.weather.Day; import me.johnweland.tempest.weather.Forecast; import me.johnweland.tempest.weather.Hour; import okhttp3.Call; import okhttp3.Callback; import okhttp3.OkHttpClient; import okhttp3.Request; import okhttp3.Response; public class MainActivity extends Activity { public static final String TAG = MainActivity.class.getSimpleName(); public static final String DAILY_FORECAST = "DAILY_FORECAST"; public static final String HOURLY_FORECAST = "HOURLY_FORECAST"; private Forecast mForecast; @BindView(R.id.timeLabel) TextView mTimeLabel; @BindView(R.id.temperatureLabel) TextView mTemperatureLabel; @BindView(R.id.humidityValue) TextView mHumidityValue; @BindView(R.id.precipValue) TextView mPrecipValue; @BindView(R.id.summaryLabel) TextView mSummaryLabel; @BindView(R.id.iconImageView) ImageView mIconImageView; @BindView(R.id.refreshImageView) ImageView mRefreshImageView; @BindView(R.id.progressBar) ProgressBar mProgressBar; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); ButterKnife.bind(this); mProgressBar.setVisibility(View.INVISIBLE); final double latitude = 37.8267; final double longitude = -122.423; mRefreshImageView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { getForecast(latitude, longitude); } }); getForecast(latitude, longitude); } private void getForecast(double latitude, double longitude) { String apiKey = " APIKEY "; String forecastURL = "https://api.forecast.io/forecast/" + apiKey + "/" + latitude + "," + longitude; if(isNetworkAvailable()) { toggleRefresh(); OkHttpClient client = new OkHttpClient(); Request request = new Request.Builder() .url(forecastURL) .build(); Call call = client.newCall(request); call.enqueue(new Callback() { @Override public void onFailure(Call call, IOException e) { runOnUiThread(new Runnable() { @Override public void run() { toggleRefresh(); } }); alertUserAboutError(); } @Override public void onResponse(Call call, Response response) throws IOException { runOnUiThread(new Runnable() { @Override public void run() { toggleRefresh(); } }); try { String jsonData = response.body().string(); if (response.isSuccessful()) { mForecast = parseForecastDetails(jsonData); runOnUiThread(new Runnable() { @Override public void run() { updateDisplay(); } }); } else { alertUserAboutError(); } } catch (IOException e) { Log.e(TAG, "Exception caught: ",e); } catch (JSONException e) { Log.e(TAG, "Exception caught: ",e); } } }); } else { Toast.makeText(this, R.string.network_unavailable_message, Toast.LENGTH_LONG).show(); } } private void toggleRefresh() { if (mProgressBar.getVisibility() == View.INVISIBLE) { mProgressBar.setVisibility(View.VISIBLE); mRefreshImageView.setVisibility(View.INVISIBLE); } else { mProgressBar.setVisibility(View.INVISIBLE); mRefreshImageView.setVisibility(View.VISIBLE); } } private void updateDisplay() { Current current = mForecast.getCurrently(); mTemperatureLabel.setText(current.getTemperature() + ""); mTimeLabel.setText("At " + current.getFormattedTime() + " it will be"); mHumidityValue.setText(current.getHumidity() + ""); mPrecipValue.setText(current.getPrecipChance() + "%"); mSummaryLabel.setText((current.getSummary())); Drawable drawable = getResources().getDrawable(current.getIconId()); mIconImageView.setImageDrawable(drawable); } private Forecast parseForecastDetails(String jsonData) throws JSONException { Forecast forecast = new Forecast(); forecast.setCurrently(getCurrentDetails(jsonData)); forecast.setHourly(getHourlyDetails(jsonData)); forecast.setDaily(getDailyDetails(jsonData)); return forecast; } private Day[] getDailyDetails(String jsonData) throws JSONException { JSONObject forecast = new JSONObject(jsonData); String timezone = forecast.getString("timezone"); JSONObject daily = forecast.getJSONObject("daily"); JSONArray data = daily.getJSONArray("data"); Day[] days = new Day[data.length()]; for ( int i = 0; i < data.length(); i++ ) { JSONObject jsonDay = data.getJSONObject(i); Day day = new Day(); day.setSummary(jsonDay.getString("summary")); day.setTempMax(jsonDay.getDouble("temperatureMax")); day.setTempMin(jsonDay.getDouble("temperatureMin")); day.setIcon(jsonDay.getString("icon")); day.setTime(jsonDay.getLong("time")); day.setTimezone(timezone); days[i] = day; } return days; } private Hour[] getHourlyDetails(String jsonData) throws JSONException { JSONObject forecast = new JSONObject(jsonData); String timezone = forecast.getString("timezone"); JSONObject hourly = forecast.getJSONObject("hourly"); JSONArray data = hourly.getJSONArray("data"); Hour[] hours = new Hour[data.length()]; for ( int i = 0; i < data.length(); i++ ) { JSONObject jsonHour = data.getJSONObject(i); Hour hour = new Hour(); hour.setSummary(jsonHour.getString("summary")); hour.setTemperature(jsonHour.getDouble("temperature")); hour.setIcon(jsonHour.getString("icon")); hour.setTime(jsonHour.getLong("time")); hour.setTimezone(timezone); hours[i] = hour; } return hours; } private Current getCurrentDetails(String jsonData) throws JSONException { JSONObject forecast = new JSONObject(jsonData); String timezone = forecast.getString("timezone"); JSONObject currently = forecast.getJSONObject("currently"); Current current = new Current(); current.setHumidity(currently.getDouble("humidity")); current.setTime(currently.getLong("time")); current.setIcon(currently.getString("icon")); current.setPrecipChance(currently.getDouble("precipProbability")); current.setSummary(currently.getString("summary")); current.setTemperature(currently.getDouble("temperature")); current.setTimezone(timezone); return current; } private boolean isNetworkAvailable() { ConnectivityManager manager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE); NetworkInfo networkinfo = manager.getActiveNetworkInfo(); boolean isAvalable = false; if(networkinfo != null && networkinfo.isConnected()) { isAvalable = true; } return isAvalable; } private void alertUserAboutError() { AlertDialogFragment dialog = new AlertDialogFragment(); dialog.show(getFragmentManager(), "error_dialog"); } @OnClick (R.id.dailyButton) public void startDailyActivity (View view) { Intent intent = new Intent(this, DailyActivity.class); intent.putExtra(DAILY_FORECAST, mForecast.getDaily()); startActivity(intent); } @OnClick (R.id.hourlyButton) public void startHourlyActivity (View view) { Intent intent = new Intent(this, HourlyActivity.class); intent.putExtra(HOURLY_FORECAST, mForecast.getHourly()); startActivity(intent); } }
4 Answers
Steve Hunter June 3, 2016 4:17pm
Typo! — android:id=
«@+id/temperaturLabel
«
Change that to temperatureLabel
Let me know if that works.
Steve.
Hi John — I just compared your code with the code from the «Android Lists and Adapters» course and it looks almost identical to that, except for the version of the ButterKnife librray and a few name changes. The error message points to line 56 in HourAdapter class and apparently one of the widget references, mTemperatureLabel
, is null so calling setText()
on that is causing the error, though I’m not sure why it is null. Have you tried putting a breakpoint in the HourViewHolder constructor to see if the member variables are being set? Also, can you post the relevant layout file?
Steve Hunter June 3, 2016 4:11pm
Hi John,
This is being caused by the setText
method failing as it is being called on a null object. So, mTemperatureLabel
is not pointing to anything. I’ve not got my code to hand and can’t recall where mTemperatureLabel
is bound to the R.id etc. But that’s what the error is saying; the attempt to use setText
is failing because you’re trying to set the text of a null. Therefore, mTemperatureLabel
is pulling back as null.
I hope that helps a little — I’ll be at my Mac later so will have my code available.
Steve.
Hello again John — In your HourlyActivity class you have the following line:
@BindView(R.id.recyclerView) RecyclerView mRecyclerView;
However, in your activity_hourly.xml file you are using a different id for the RecyclerView:
android:id="@+id/hourlyRecyclerView"