0

My app is crashing immediately upon launch. I cannot figure out why. I was having other issues with this app that were solved in another thread, however, the issue I'm having now is completely different. I know my code/structure is not the most elegant, but I am still a novice when it comes to Android and XML.

Here is the log error stacktrace:

11-30 15:42:46.970: W/dalvikvm(10028): threadid=1: thread exiting with uncaught exception (group=0x40d04210)
11-30 15:42:46.970: E/AndroidRuntime(10028): FATAL EXCEPTION: main
11-30 15:42:46.970: E/AndroidRuntime(10028): java.lang.RuntimeException: Unable to instantiate activity ComponentInfo{com.defsoftsol.db.check/com.defsoftsol.db.check.MainActivity}: java.lang.NullPointerException
11-30 15:42:46.970: E/AndroidRuntime(10028):    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1880)
11-30 15:42:46.970: E/AndroidRuntime(10028):    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1981)
11-30 15:42:46.970: E/AndroidRuntime(10028):    at android.app.ActivityThread.access$600(ActivityThread.java:123)
11-30 15:42:46.970: E/AndroidRuntime(10028):    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1147)
11-30 15:42:46.970: E/AndroidRuntime(10028):    at android.os.Handler.dispatchMessage(Handler.java:99)
11-30 15:42:46.970: E/AndroidRuntime(10028):    at android.os.Looper.loop(Looper.java:137)
11-30 15:42:46.970: E/AndroidRuntime(10028):    at android.app.ActivityThread.main(ActivityThread.java:4428)
11-30 15:42:46.970: E/AndroidRuntime(10028):    at java.lang.reflect.Method.invokeNative(Native Method)
11-30 15:42:46.970: E/AndroidRuntime(10028):    at java.lang.reflect.Method.invoke(Method.java:511)
11-30 15:42:46.970: E/AndroidRuntime(10028):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:787)
11-30 15:42:46.970: E/AndroidRuntime(10028):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:554)
11-30 15:42:46.970: E/AndroidRuntime(10028):    at dalvik.system.NativeStart.main(Native Method)
11-30 15:42:46.970: E/AndroidRuntime(10028): Caused by: java.lang.NullPointerException
11-30 15:42:46.970: E/AndroidRuntime(10028):    at android.app.Activity.findViewById(Activity.java:1794)
11-30 15:42:46.970: E/AndroidRuntime(10028):    at com.defsoftsol.db.check.MainActivity.<init>(MainActivity.java:43)
11-30 15:42:46.970: E/AndroidRuntime(10028):    at java.lang.Class.newInstanceImpl(Native Method)
11-30 15:42:46.970: E/AndroidRuntime(10028):    at java.lang.Class.newInstance(Class.java:1319)
11-30 15:42:46.970: E/AndroidRuntime(10028):    at android.app.Instrumentation.newActivity(Instrumentation.java:1023)
11-30 15:42:46.970: E/AndroidRuntime(10028):    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1871)
11-30 15:42:46.970: E/AndroidRuntime(10028):    ... 11 more

Here is my complete code:

public class MainActivity extends Activity {

String deviceID="",dateStamp="",buff="",db_id="",db_device_id="",db_install_date="";       
byte[] data;    
HttpPost httppost;    
StringBuffer buffer;    
HttpResponse response;    
HttpClient httpclient;    
InputStream inputStream;    
List<NameValuePair> nameValuePairs;
int ID,activeinstalls;
long diff;
TableLayout tl=(TableLayout)findViewById(R.id.db_data);

public void onCreate(Bundle savedInstanceState) 
{
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    Button refresh = (Button)findViewById(R.id.btnrefresh);
    refresh.setOnClickListener(new OnClickListener() {
        public void onClick(View v) {
            new MyAsyncTask(MainActivity.this).execute();

        }
    });
}

@SuppressWarnings("unused") 
public class MyAsyncTask extends AsyncTask<Void, Void, Void> 
{ 

    ProgressDialog mProgressDialog;
    private Context context;

    public MyAsyncTask(Context context) { 
        this.context = context;
    }

    @Override
    protected void onPostExecute(Void result) {
        mProgressDialog.dismiss();
    } 

    @Override 
    protected void onPreExecute() {
        mProgressDialog = ProgressDialog.show(MainActivity.this, "Loading...", "Data is Loading..."); 
    } 

    @Override
    protected Void doInBackground(Void... params) {
        update(); 
        return null; 
    }
}

private final SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd"); 
private final long ONE_DAY = 24 * 60 * 60 * 1000;

@SuppressWarnings("unused")
public void update()
{
    int activeinstalls = 0;
    Date now = new Date();
    dateStamp = formatter.format(now);

    runOnUiThread(new Runnable(){ 
        @Override 
        public void run(){ 
            UISetup();
        }
    });

    ID = 1;
    try
    {
        do
        {
            try 
            {                    
                httpclient = new DefaultHttpClient();                    
                httppost = new HttpPost("http://#.#.#.#/***.php"); //Address hidden for server security.                    

                nameValuePairs = new ArrayList<NameValuePair>(1);                   
                nameValuePairs.add(new BasicNameValuePair("_id", String.valueOf(ID)));                    
                httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
                response = httpclient.execute(httppost);                    
                inputStream = response.getEntity().getContent();                     
                data = new byte[256];                     
                buffer = new StringBuffer();                    
                int len = 0;                    
                while (-1 != (len = inputStream.read(data)) )                    
                {                        
                    buffer.append(new String(data, 0, len));                    
                }
                inputStream.close();
            } catch (Exception e) {                    
                Toast.makeText(MainActivity.this, "error"+e.toString(), Toast.LENGTH_LONG).show();                
                e.printStackTrace();
            }

            if(buffer.charAt(0)=='Y')
            {
                ID++;
                buff = buffer.toString();
                db_id = buff.substring(1, buff.indexOf("."));
                db_device_id = buff.substring(buff.indexOf(".")+1, buff.indexOf(","));
                db_install_date = buff.substring(buff.indexOf(",")+1, buff.length());

                Date before = null;
                try {
                    before = (Date)formatter.parse(db_install_date);
                } catch (ParseException e) {
                    e.printStackTrace();
                }
                diff = now.getTime() - before.getTime(); 

                runOnUiThread(new Runnable(){ 
                    @Override 
                    public void run(){ 
                        UIAdd(diff,db_id,db_device_id,db_install_date);
                    }
                });

            } else { //IF buffer returns N
                //  TODO: Fill in
            }
        } while(buffer.charAt(0)=='Y');

        UIFinish();

    } catch(Exception err) {
        err.printStackTrace();
    }
}
@SuppressWarnings("deprecation")
public void UISetup()
{
    tl.removeAllViews();
    dbline();
    TableRow titr = new TableRow(this); 
    titr.setLayoutParams(new LayoutParams( LayoutParams.FILL_PARENT,LayoutParams.WRAP_CONTENT)); 
    TextView dbid0 = new TextView(this); 
    TextView dbdevid0 = new TextView(this);
    TextView dbindate0 = new TextView(this);
    dbid0.setText("|   " + "_id");
    dbdevid0.setText("|   " + "device_id");
    dbindate0.setText("|   "+ "install_date"+"    |");

    titr.addView(dbid0); 
    titr.addView(dbdevid0);
    titr.addView(dbindate0);
    tl.addView(titr, new TableLayout.LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT));
    dbline();
}
@SuppressWarnings("deprecation")
public void UIAdd(long diffr, String dbidn,String did,String idate)
{
    long days;
    days = diffr / ONE_DAY;
    TableRow tr = new TableRow(this); 
    tr.setLayoutParams(new LayoutParams( LayoutParams.FILL_PARENT,LayoutParams.WRAP_CONTENT)); 
    TextView dbid = new TextView(this); 
    TextView dbdevid = new TextView(this);
    TextView dbindate = new TextView(this);
    dbid.setText("|   " + dbidn);
    dbdevid.setText("|   " + did);
    dbindate.setText("|   " + idate+"   |");

    if(days <= 7)
    {
        activeinstalls++;
        if(days <= 3) 
        {
            dbid.setTextColor(Color.GREEN); 
            dbdevid.setTextColor(Color.GREEN);
            dbindate.setTextColor(Color.GREEN);
        } else {
            dbid.setTextColor(Color.MAGENTA);
            dbdevid.setTextColor(Color.MAGENTA);
            dbindate.setTextColor(Color.MAGENTA);
        }

    } else {
        dbid.setTextColor(Color.RED); 
        dbdevid.setTextColor(Color.RED);
        dbindate.setTextColor(Color.RED);
    }

    tr.addView(dbid); 
    tr.addView(dbdevid);
    tr.addView(dbindate);
    tl.addView(tr, new TableLayout.LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT));
}
public void UIFinish()
{
    dbline();

    TextView te = (TextView)findViewById(R.id.totalentries);
    te.setText(String.valueOf(ID-1));
    TextView au = (TextView)findViewById(R.id.activeusers);
    au.setText(String.valueOf(activeinstalls));
}
@SuppressWarnings("deprecation")
public void dbline()
{
    TableLayout tl=(TableLayout)findViewById(R.id.db_data);
    TableRow tr = new TableRow(this); 
    tr.setLayoutParams(new LayoutParams( LayoutParams.FILL_PARENT,LayoutParams.WRAP_CONTENT)); 
    TextView dbid = new TextView(this); 
    TextView dbdevid = new TextView(this);
    TextView dbindate = new TextView(this);
    dbid.setText("+---------");
    dbdevid.setText("+-------------------------------");
    dbindate.setText("+--------------------+");

    tr.addView(dbid); 
    tr.addView(dbdevid);
    tr.addView(dbindate);
    tl.addView(tr, new TableLayout.LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT));
}
}

2 Answers2

2

Move this

TableLayout tl=(TableLayout)findViewById(R.id.db_data);

to your onCreate() because you have to setContentView() before you call findViewById.

Wenhui
  • 648
  • 4
  • 13
  • Thats basically what i did. See the answer I posted myself. Still had to name `tl` where it was so it would be shared throughout the app, but yes, I had to move the initialization into onCreate – DEF Software Solutions Dec 01 '12 at 03:11
  • Still marking your answer as the correct answer as I cannot mark my own for 2 days. – DEF Software Solutions Dec 01 '12 at 03:12
  • Altho on a side note, if you can tell me why the above code does not complete that would be awesome. I.E. There are currently 55+ entries in my database, upon hitting the refresh button in my app it loads 37 entries then stops. Does not complete, and never updates the totals (UIFinish() never runs it seems) – DEF Software Solutions Dec 01 '12 at 03:16
  • Where is your database? Is it in your remote server? – Wenhui Dec 01 '12 at 03:24
  • Yes, and an update, I forgot to run UIFinish() on UIthread. Did that and now app completes, however, still only loading the first 37 entries – DEF Software Solutions Dec 01 '12 at 03:30
  • Have you logged the String you get back from the server, see if it is correct? And have you checked your query in your server see if it returns 55+ entries? – Wenhui Dec 01 '12 at 03:35
  • I just went downstairs and checked the database on the server directly. There are 57 entries. Entry 38 was empty, had the autoincrement id, however, device id and date were blank, so I manually deleted that row. I figured maybe that was the issue, but even after removing the row, the app still stops after 37. Another note: LogCat shows no errors or even warnings on run. – DEF Software Solutions Dec 01 '12 at 03:45
  • So you manually delete Entry 38 whose `_id` is 38 right? When you `ID` is 38, what is your server return? That is where error happens. Suggestion: server can query all entries and send them all to the client instead of doing 55+ HttpRequest. – Wenhui Dec 01 '12 at 03:55
  • If your server return empty string, then it breaks the while loop. – Wenhui Dec 01 '12 at 03:56
  • Any chance you could give an example of how to do all at once rather than a loop for each entry? – DEF Software Solutions Dec 01 '12 at 04:22
  • In your server side, query all the entries, and wrap it as a Json object, then pass the `Json` object back to your client, then parse the `Json` object. [Here](http://www.vogella.com/articles/AndroidJSON/article.html) is a tutorial. – Wenhui Dec 01 '12 at 04:27
  • Thank you, I will look at that tomorrow. Little late to run through it all tonight. I thank you for your help. Just wish that mine would at least grab all the data for now, until I can revamp. – DEF Software Solutions Dec 01 '12 at 04:35
1

This was my own mistake. I was initializing a tablelayout in the wrong spot.

TableLayout tl=(TableLayout)findViewById(R.id.db_data); should have been simply TableLayout tl; and then initialized it in onCreate()