Reputation:
Why do I always get a NullPointerException when I run my application? Every time I start my genymotion emulator and then run the app the first time, it crashes, but the 2nd time I run my app in works smoothly. I don't know why it happens everytime on the first run.
Here is my Splash screen which retrieves the JSON object from the RetrieveGamesBGTask:
public class Splash extends Activity {
RetrieveGamesBGTask retrieveGamesBGTask;
String json_string;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.splash);
Thread thread = new Thread(){
@Override
public void run() {
try {
retrieveGamesBGTask = new RetrieveGamesBGTask();
retrieveGamesBGTask.execute();
sleep(3000);
Intent intent = new Intent(getApplication(), Games.class);
intent.putExtra("json_data", json_string);
intent.putExtra("json_data", retrieveGamesBGTask.getResult());
startActivity(intent);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
thread.start();
Here is the next application where it crashes every time on the first run:
retrieveGamesBGTask = new RetrieveGamesBGTask();
retrieveGamesBGTask.execute();
Intent intent = this.getIntent();
if (intent != null) {
json_string = intent.getStringExtra("json_data");
}
try {
if (jsonObject == null) {
jsonObject = new JSONObject(json_string);
jsonArray = jsonObject.getJSONArray("server_response");
int count = 0;
String teamone, teamonepts, teamtwo, teamtwopts, s_name, s_gender;
while (count < jsonArray.length()) {
JSONObject JO = jsonArray.getJSONObject(count);
teamone = JO.getString("teamone");
teamonepts = JO.getString("teamonepts");
teamtwo = JO.getString("teamtwo");
teamtwopts = JO.getString("teamtwopts");
s_name = JO.getString("s_name");
s_gender = JO.getString("s_gender");
Downloader downloader = new Downloader(teamone, teamonepts, teamtwo, teamtwopts, s_name, s_gender);
gamesAdapter.add(downloader);
count++;
}
} else {
Toast.makeText(this, "JSON is null", Toast.LENGTH_LONG).show();
}
} catch (JSONException e) {
e.printStackTrace();
}
Here is my RetrieveGamesBGTask
class RetrieveGamesBGTask extends AsyncTask<Void, Void, String> {
String json_result, json_string;
@Override
protected void onPreExecute() {
}
@Override
protected String doInBackground(Void... params) {
try {
URL url = new URL(Config.URL_GAMES);
HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();
InputStream inputstream = httpURLConnection.getInputStream();
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputstream));
StringBuilder stringBuilder = new StringBuilder();
while ((json_string = bufferedReader.readLine()) != null) {
stringBuilder.append(json_string + "\n");
}
bufferedReader.close();
inputstream.close();
httpURLConnection.disconnect();
return stringBuilder.toString().trim();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
@Override
protected void onProgressUpdate(Void... values) {
super.onProgressUpdate(values);
}
@Override
protected void onPostExecute(String result) {
Log.d("haha", "hehe");
json_result = result;
}
public String getResult() {
return json_result;
}
Here is my logcat:
FATAL EXCEPTION: main
Process: com.example.aaa.bbb, PID: 5680
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.aaa.bbb/com.example.aaa.bbb.Games}: java.lang.NullPointerException: Attempt to invoke virtual method 'int java.lang.String.length()' on a null object reference
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2416)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2476)
at android.app.ActivityThread.-wrap11(ActivityThread.java)
Upvotes: 2
Views: 3398
Reputation: 1891
Another way you can place intent inside your post execute.
in your Activity's onCreate
method
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.splash);
new RetrieveGamesBGTask(Splash.this).execute();
}
now in your RetrieveGamesBGTask's onPostExecute
method
@Override
protected void onPostExecute(String result) {
Log.d("haha", "hehe");
json_result = result;
Intent intent = new Intent(context, Games.class);
intent.putExtra("json_data", json_string);
intent.putExtra("json_data",json_result);
context.startActivity(intent);
}
Upvotes: 1
Reputation: 2372
There's a couple of things you could do better here. But your main problem is that you are doing async tasks(backgroundtask) and not handling a proper callback.
Now while crashing the async task still runs and finishes. I'm not sure if you save this JSON and then it becomes readable while completing and becomes available the second time, or that the second time the task might finish within 3 seconds.
onPostExecute
have a callback to your main thread.To achieve this look here https://developer.android.com/training/best-background.html
It should provide enough information to get this piece of code stable.
Upvotes: 7
Reputation: 19800
Well the error is quite clear:
Attempt to invoke virtual method 'int java.lang.String.length()' on a null object reference
So somewhere you call length on a not initialized string. This is not in the code you posted. (only jsonArray.length()
)
Upvotes: -1