I use a thread and holder for downloading some data and then displaying a new view with buttons that allow you to browse further through the app.
But i think i’m doing something wrong, because any next activity i use, crashes with a null pointer exception on the setContentView line. When i comment this line, nothing goes wrong (so i guess that means that the activity is declared good in the manifest and starts normally).
It looks like because of the thread the new activity has no place to set the content to or something..
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.List;
import java.util.Locale;
import org.codehaus.jackson.JsonParseException;
import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.type.TypeReference;
import com.hera.ontdekdelft.model.JJsonResponse;
import com.hera.ontdekdelft.listclasses.ListData;
import android.app.Activity;
import android.content.Intent;
import android.content.res.AssetManager;
import android.graphics.drawable.Drawable;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.ProgressBar;
import android.widget.RelativeLayout;
import android.widget.TextView;
public class StartUp extends Activity
{
private static final String tag = StartUp.class.getName();
public static final String SERIALIZEDDATA = "SerializedData";
ProgressBar pbar;
TextView tv1;
Drawable background;
Button btCategory, btMakeMyDay;
RelativeLayout loadedBackground, loadingBackground;
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
LoadData task = new LoadData();
task.execute();
String language = Locale.getDefault().getISO3Language();
background = getBackgroundImage();
setContentView(R.layout.startup_loading);
tv1=(TextView)findViewById(R.id.tvloading);
if(language.equals("nld")){
tv1.setText("bijwerken");
}else{
tv1.setText("loading");
}
pbar=(ProgressBar)findViewById(R.id.progressBar1);
pbar.setVisibility(1);
loadingBackground=(RelativeLayout)findViewById(R.id.startup_background_loading);
loadingBackground.setBackgroundDrawable(background);
}
public Drawable getBackgroundImage(){
Drawable d;
Calendar c = Calendar.getInstance();
int month = c.get(Calendar.MONTH);
Log.i("month",String.valueOf(month));
switch (month){
default: d = getResources().getDrawable(R.drawable.homescreen_summer);break;
case 0:d = getResources().getDrawable(R.drawable.homescreen_winter);break;
case 1:d = getResources().getDrawable(R.drawable.homescreen_winter); break;
case 2:d = getResources().getDrawable(R.drawable.homescreen_spring);break;
case 3:d = getResources().getDrawable(R.drawable.homescreen_spring);break;
case 4:d = getResources().getDrawable(R.drawable.homescreen_spring);break;
case 5:d = getResources().getDrawable(R.drawable.homescreen_summer); break;
case 6:d = getResources().getDrawable(R.drawable.homescreen_summer); break;
case 7:d = getResources().getDrawable(R.drawable.homescreen_summer); break;
case 8:d = getResources().getDrawable(R.drawable.homescreen_autumn); break;
case 9:d = getResources().getDrawable(R.drawable.homescreen_autumn); break;
case 10:d = getResources().getDrawable(R.drawable.homescreen_autumn); break;
case 11:d = getResources().getDrawable(R.drawable.homescreen_winter); break;
}
return d;
}
private class LoadData extends AsyncTask<Void, Void, String> {
@Override
protected void onPreExecute() {
super.onPreExecute();
}
protected void onPostExecute(String language) {
super.onPostExecute(language);
setContentView(R.layout.startup_loaded);
btCategory=(Button)findViewById(R.id.btn_category);
loadedBackground=(RelativeLayout)findViewById(R.id.startup_background_loaded);
loadedBackground.setBackgroundDrawable(background);
if(language.equals("nld")){
btCategory.setText("Ontdek Delft");
}else{
btCategory.setText("Discover Delft");
}
//newactivitybutton
btCategory.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
startActivity(new Intent(StartUp.this, Overview.class));
finish();
}
});
}
@Override
protected String doInBackground(Void... params) {
String language = Locale.getDefault().getISO3Language();
AssetManager assetManager = getAssets();
InputStream inputStream = null;
try {
inputStream = assetManager.open("originalDelftJson.json");
} catch (IOException e) {
Log.e("tag", e.getMessage());
}
ObjectMapper objectMapper = new ObjectMapper();
Log.i("tijdlog","start parsing" );
try {
List<JJsonResponse> jsonResponse = objectMapper.readValue(inputStream, new TypeReference<List<JJsonResponse>>() { });
Log.i("tijdlog","einde parsing" );
//
final List<JJsonResponse> myGlobalVariable = jsonResponse;
((ApplicationController)getApplication()).setGlobalData(myGlobalVariable);
List<ListData> ld = new ArrayList<ListData>();
int selectedPic;
JJsonResponse e;
int k =0;
for(int i=0;i < jsonResponse.size() ;i++){
e = jsonResponse.get(i);
for(int j=0; j<e.venue.themes.size();j++){
if (e.venue.themes.get(j).mobile == true){
selectedPic = 0;
String tip;
String theme;
if (language.equalsIgnoreCase("nld")){
tip=e.venue.tip;
theme=e.venue.themes.get(j).name;
}else{
tip=e.venue.tip_en;
theme=e.venue.themes.get(j).name_en;
}
// pic selected pic
String photoUrl = null;
if (e.venue.venue_photos.isEmpty() == false){
for(int l=0; l < e.venue.venue_photos.size() ;l++){
if(e.venue.venue_photos.get(l).selected == true){
selectedPic = l;
}
photoUrl=e.venue.venue_photos.get(selectedPic).medium;
}
}else
{
photoUrl=null; // null no pic--> add link later
}
ld.add(new ListData(e.venue.id, e.venue.name, photoUrl, tip, theme));//nieuwe maken
k++;
}
}
}
Collections.sort(ld, ListData.ListDataThemeAndNameComparator); // vergelijken op thema
for(int z=0;z < ld.size() ;z++){
Log.i("ld nr " + String.valueOf(z), ld.get(z).name + " theme: " + ld.get(z).theme + " & venue id= "+ ld.get(z).venueID);
}
// save
((ApplicationController)getApplication()).setListData(ld);
} catch (JsonParseException e) {
// XXX Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// XXX Auto-generated catch block
e.printStackTrace();
}
return language;
}
}
}
the new activity where my error occurs:
import android.app.Activity; import android.os.Bundle;
public class Overview extends Activity{
@Override protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(findViewById(R.layout.splash)); }}
xml splash;
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical"
android:background="@drawable/splash"
>
</LinearLayout>
edit:
i edited my code. now using a AsyncTask, it seemed to be the solution like LuxuryMode suggested below, but it doesn’t work either. Still same nullpointerexception when setContentView…
error log:
07-24 19:53:50.411: E/AndroidRuntime(29618): FATAL EXCEPTION: main
07-24 19:53:50.411: E/AndroidRuntime(29618): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.hera.ontdekdelft/com.hera.ontdekdelft.Overview}: java.lang.NullPointerException
07-24 19:53:50.411: E/AndroidRuntime(29618): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2787)
07-24 19:53:50.411: E/AndroidRuntime(29618): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2803)
07-24 19:53:50.411: E/AndroidRuntime(29618): at android.app.ActivityThread.access$2300(ActivityThread.java:135)
07-24 19:53:50.411: E/AndroidRuntime(29618): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2136)
07-24 19:53:50.411: E/AndroidRuntime(29618): at android.os.Handler.dispatchMessage(Handler.java:99)
07-24 19:53:50.411: E/AndroidRuntime(29618): at android.os.Looper.loop(Looper.java:144)
07-24 19:53:50.411: E/AndroidRuntime(29618): at android.app.ActivityThread.main(ActivityThread.java:4937)
07-24 19:53:50.411: E/AndroidRuntime(29618): at java.lang.reflect.Method.invokeNative(Native Method)
07-24 19:53:50.411: E/AndroidRuntime(29618): at java.lang.reflect.Method.invoke(Method.java:521)
07-24 19:53:50.411: E/AndroidRuntime(29618): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:858)
07-24 19:53:50.411: E/AndroidRuntime(29618): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
07-24 19:53:50.411: E/AndroidRuntime(29618): at dalvik.system.NativeStart.main(Native Method)
07-24 19:53:50.411: E/AndroidRuntime(29618): Caused by: java.lang.NullPointerException
07-24 19:53:50.411: E/AndroidRuntime(29618): at android.view.ViewGroup.addViewInner(ViewGroup.java:1977)
07-24 19:53:50.411: E/AndroidRuntime(29618): at android.view.ViewGroup.addView(ViewGroup.java:1873)
07-24 19:53:50.411: E/AndroidRuntime(29618): at android.view.ViewGroup.addView(ViewGroup.java:1853)
07-24 19:53:50.411: E/AndroidRuntime(29618): at com.android.internal.policy.impl.PhoneWindow.setContentView(PhoneWindow.java:226)
07-24 19:53:50.411: E/AndroidRuntime(29618): at com.android.internal.policy.impl.PhoneWindow.setContentView(PhoneWindow.java:216)
07-24 19:53:50.411: E/AndroidRuntime(29618): at android.app.Activity.setContentView(Activity.java:1665)
07-24 19:53:50.411: E/AndroidRuntime(29618): at com.hera.ontdekdelft.Overview.onCreate(Overview.java:12)
07-24 19:53:50.411: E/AndroidRuntime(29618): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1069)
07-24 19:53:50.411: E/AndroidRuntime(29618): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2751)
07-24 19:53:50.411: E/AndroidRuntime(29618): ... 11 more
There are two rules in the Android threading model: 1) dont block the main (UI) thread 2) dont manipulate the UI from off of the main (UI) thread. You seem to be having an issue with the second of those rules. You can try using Activity#runOnUiThread(Runnable) instead of using that handler, but in general what you’re doing is really messy and generally a terrible idea 🙂 Also, unless I’m missing something up, how exactly is your handler even usable inside of your startup thread if you’re initializing it after you start the thread? You seem to be relying on the thread scheduling going a certain way which is just a bad idea as well.
In all likelihood, what you need to use is an
AsyncTask. Set your contentview immediately in onCreate and then execute yourAsyncTaskwhich downloads your data. Then in onPostExecute of your task, do whatever relevant UI changes are necessary.UPDATE –
in onPostExecute, call the super right away. Also, don’t start your Activity by calling
startActivity(new Intent ("com.hera.ontdekdelft.OVERVIEW"));, instead it should bestartActivity(new Intent(Startup.this, Overview.class));Also, from the looks of the stacktrace, the crash is occurring when you try starting the new Activity. So I would look there on line 12 to see what the problem is.
UPDATE –
As I pointed out in our discussion below:
You cannot set the contentView of your Activity to findViewById(whatever). findViewById looks through the current contentView and tries to find a view that matches the id you passed in. But you havent set any contentview yet so theres nothing to find. Therefore you crash with a nullpointer when you try setting the contentview to the null view returned by your call to findViewById! You need to set the view to whatever the view is for that Activity. setContentView(R.layout.overview_layout) or setContentView(new OverviewView(this))