1

I know there are tons of these on SO, but I have one more for you guys. I know I have a null pointer exception error somewhere, but I have no idea where. Java isnt my best language so I am kind of fumbling through this.

My logcat looks like this:

W/dalvikvm( 6062): threadid=1: thread exiting with uncaught exception (group=0x413e5438)
E/AndroidRuntime( 6062): FATAL EXCEPTION: main
E/AndroidRuntime( 6062): java.lang.NullPointerException
E/AndroidRuntime( 6062):    at com.zach.ReportingTool.ReportingTool$1.handleMessage(ReportingTool.java:152)
E/AndroidRuntime( 6062):    at android.os.Handler.dispatchMessage(Handler.java:99)
E/AndroidRuntime( 6062):    at android.os.Looper.loop(Looper.java:137)
E/AndroidRuntime( 6062):    at android.app.ActivityThread.main(ActivityThread.java:4918)
E/AndroidRuntime( 6062):    at java.lang.reflect.Method.invokeNative(Native Method)
E/AndroidRuntime( 6062):    at java.lang.reflect.Method.invoke(Method.java:511)
E/AndroidRuntime( 6062):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1004)
E/AndroidRuntime( 6062):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:771)
E/AndroidRuntime( 6062):    at dalvik.system.NativeStart.main(Native Method)
E/android.os.Debug(  714): !@Dumpstate > dumpstate -k -t -z -d -o /data/log/dumpstate_app_error

I took the code from an open source project here. The code is for a speed test application. The only thing I really changed/removed was removing an updating progress bar that was at the top of the screen that was animated and I got rid of a network textview that indicated whether the speed was 3g or edge.

to initiate the code the button looks like this:

        bSpeed.setOnClickListener(new OnClickListener(){
        @Override
        public void onClick(final View view) {
            confirmation.setText("Test started");   
            bSpeed.setEnabled(false);
            new Thread(mWorker).start();    

        }
    });

The rest of the code looks like this:

    @SuppressLint("HandlerLeak")
private final Handler mHandler=new Handler(){
    @Override
    public void handleMessage(final Message msg) {
        try {
        switch(msg.what){
        case MSG_UPDATE_STATUS:
            final SpeedInfo info1=(SpeedInfo) msg.obj;
            speed.setText(String.format(getResources().getString(R.string.update_speed), mDecimalFormater.format(info1.kilobits)));
            progress.setText(String.format(getResources().getString(R.string.update_downloaded), msg.arg2, EXPECTED_SIZE_IN_BYTES));
            break;
        case MSG_UPDATE_CONNECTION_TIME:
            conspeed.setText(String.format(getResources().getString(R.string.update_connectionspeed), msg.arg1));
            break;              
        case MSG_COMPLETE_STATUS:
            final  SpeedInfo info2=(SpeedInfo) msg.obj;
            speed.setText(String.format(getResources().getString(R.string.update_downloaded_complete), msg.arg1, info2.kilobits));          
            progress.setText(String.format(getResources().getString(R.string.update_downloaded), msg.arg1, EXPECTED_SIZE_IN_BYTES));
            bSpeed.setEnabled(true);
            break;  
        default:
        super.handleMessage(msg);
        }
        } catch (Exception e) {confirmation.setText("6: " + e.getMessage());}
    }
};

private final Runnable mWorker=new Runnable(){      
    @Override
    public void run() {
        InputStream stream=null;
        try {
            int bytesIn=0;
            String downloadFileUrl="http://www.gregbugaj.com/wp-content/uploads/2009/03/dummy.txt"; 
            long startCon=System.currentTimeMillis(); 
            URL url=new URL(downloadFileUrl);
            URLConnection con=url.openConnection();
            con.setUseCaches(false);
            long connectionLatency=System.currentTimeMillis()- startCon;
            stream=con.getInputStream();

            Message msgUpdateConnection=Message.obtain(mHandler, MSG_UPDATE_CONNECTION_TIME);
            msgUpdateConnection.arg1=(int) connectionLatency;
            mHandler.sendMessage(msgUpdateConnection);

            long start=System.currentTimeMillis();
            int currentByte=0;
            long updateStart=System.currentTimeMillis();
            long updateDelta=0;
            int  bytesInThreshold=0;

            while((currentByte=stream.read())!=-1){ 
                bytesIn++;
                bytesInThreshold++;
                if(updateDelta>=UPDATE_THRESHOLD){
                    int progress=(int)((bytesIn/(double)EXPECTED_SIZE_IN_BYTES)*100);
                    Message msg=Message.obtain(mHandler, MSG_UPDATE_STATUS, calculate(updateDelta, bytesInThreshold));
                    msg.arg1=progress;
                    msg.arg2=bytesIn;
                    mHandler.sendMessage(msg);
                    //Reset
                    updateStart=System.currentTimeMillis();
                    bytesInThreshold=0;
                }
                updateDelta = System.currentTimeMillis()- updateStart;
            }

            long downloadTime=(System.currentTimeMillis()-start);
            if(downloadTime==0){
                downloadTime=1;
            }

            Message msg=Message.obtain(mHandler, MSG_COMPLETE_STATUS, calculate(downloadTime, bytesIn));
            msg.arg1=bytesIn;
            mHandler.sendMessage(msg);
        } 
        catch (MalformedURLException e) {
            confirmation.setText("1: " + e.getMessage());
        } catch (Exception e) {
            confirmation.setText("2: " + e.getMessage());
        }finally{
            try {
                if(stream!=null){
                    stream.close();
                }
            } catch (Exception e) { 
                confirmation.setText("3: " + e.getMessage());
            }
        }
    }
};

private SpeedInfo calculate(final long downloadTime, final long bytesIn){
    SpeedInfo info=new SpeedInfo();
    long bytespersecond   =(bytesIn / downloadTime) * 1000;
    double kilobits=bytespersecond * BYTE_TO_KILOBIT;
    double megabits=kilobits  * KILOBIT_TO_MEGABIT;
    info.downspeed=bytespersecond;
    info.kilobits=kilobits;
    info.megabits=megabits;
    return info;    
}

private static class SpeedInfo{
    public double kilobits=0;   
    public double megabits=0;
    public double downspeed=0;  
}
private static final int EXPECTED_SIZE_IN_BYTES = 1048576;
private static final double BYTE_TO_KILOBIT = 0.0078125;
private static final double KILOBIT_TO_MEGABIT = 0.0009765625;

private Button bSpeed;
private TextView conspeed;
private TextView progress;
private TextView speed;
private TextView confirmation;

private final int MSG_UPDATE_STATUS=0;
private final int MSG_UPDATE_CONNECTION_TIME=1;
private final int MSG_COMPLETE_STATUS=2;

private final static int UPDATE_THRESHOLD=300;
private DecimalFormat mDecimalFormater;
}

Where I think the error is coming from, is the objects in the case statement. (ReportingTool.java:152) points to this line:

     conspeed.setText(String.format(getResources().getString(R.string.update_connectionspeed), msg.arg1));

If i comment that line out, it then points to the progress.setText() above that line in the previous case statement. Ignore all the try/catch blocks, I was just trying to narrow down where the error was coming from.

If anyone could take a look at this code it would be greatly appreciated, Thanks -Z

UPDATE

Thank you guys for the quick responses. After debugging that line and the ones around it, it looks like conspeed, speed, and progress are all returning with null values, am I not initiating them right?

To initiate I updated everything to match this in the "oncreate":

    TextView speed = (TextView) findViewById(R.id.speed);
    TextView progress = (TextView) findViewById(R.id.progress);
    TextView connectionspeed = (TextView)findViewById(R.id.connectionspeed);

so now line 152 is connectionspeed.setText()

UPDATE 2

Here is the Main.xml

 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/textView3"
android:layout_width="fill_parent" 
android:layout_height="wrap_content"  >

<TextView
    android:id="@+id/progress"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:layout_alignParentLeft="true"
    android:layout_below="@+id/bSip"
    android:layout_marginTop="16dp"
    android:text="@string/progress" />

<Button
    android:id="@+id/bSip"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignParentLeft="true"
    android:layout_alignParentTop="true"
    android:layout_marginLeft="29dp"
    android:text="@string/EnableSip" />

<TextView
    android:id="@+id/speed"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:layout_alignParentLeft="true"
    android:layout_below="@+id/progress"
    android:text="@string/Speed"/>

<TextView
    android:id="@+id/connectionspeed"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:layout_alignParentLeft="true"
    android:layout_below="@+id/speed"
    android:text="@string/ConSpeed"/>

<Button
    android:id="@+id/bSpeed"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_above="@+id/progress"
    android:layout_alignParentRight="true"
    android:layout_marginRight="30dp"
    android:text="@string/SpeedTest" />

<TextView
    android:id="@+id/Confirmation"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:layout_alignParentLeft="true"
    android:layout_below="@+id/bmail"
    android:layout_marginTop="22dp"
    android:fitsSystemWindows="true"
    android:maxLines="@integer/MaxLines"
    android:scrollHorizontally="false"
    android:visibility="visible" />

<Button
    android:id="@+id/bmail"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_below="@+id/connectionspeed"
    android:layout_centerHorizontal="true"
    android:layout_marginTop="33dp"
    android:text="@string/Export" />

<Button
    android:id="@+id/bDelete"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignLeft="@+id/bmail"
    android:layout_alignParentBottom="true"
    android:text="@string/deleteSelf" />

Thanks Again -Z

Nefariis
  • 3,451
  • 10
  • 34
  • 52
  • 2
    Probably either conspeed or msg is null on that line, check which one is. – Egor Feb 27 '13 at 20:49
  • Debug the line to check which one is null, or if you don't know how to do that, put both arguments in local variables and check them via Log.v() calls. – soren.qvist Feb 27 '13 at 20:51
  • Why do you have no idea? Read the stack trace. Depending on the scenario, it will contain a line tagged with "caused by" which points directly to the line causing the exception. Otherwise, just read top to bottom looking for the line in your code which is the root of the exception being thrown back up through the call stack. It really isn't difficult. – Simon Feb 27 '13 at 21:08
  • updated to show the problem... – Nefariis Feb 27 '13 at 21:20
  • 1
    Be sure to call `setContentView(R.layout.Main)` **before** calling `findViewById()` in your `onCreate()` method. You can post your `onCreate()` method if you still have problems. – eternay Feb 28 '13 at 12:34

3 Answers3

1

Above line 152 in question, do this:

 if (conspeed == null){
      Log.e("TAG", "conspeed is null!");
 }
 if (getResources() == null){
      Log.e("TAG", "getResources() is null!");
 }
 if (msg == null){
      Log.e("TAG", "msg is null!");
 }
 conspeed.setText(String.format(getResources().getString(R.string.update_connectionspeed), msg.arg1));

Then you'll know what's null and the next step is just to find out why.

EDIT:

I see you're using findViewById. In your XML file have you actually defined those TextViews with an id field matching what you're looking for? Like this: android:id="@+id/speed"

EDIT 2

Hmm, your XML looks ok. The fact that you're doing this in your onCreate() leads me to believe you're perhaps just calling these too early. Refer to this post: findViewByID returns null

Try maybe re factoring your code to make this call after everything with your UI is initialized? it could be null just cause everything hasn't been set up yet.

Community
  • 1
  • 1
boltup_im_coding
  • 6,345
  • 6
  • 40
  • 52
0

The NullPointerException will be at line 152 in the file where handleMessage method is (ReportingTool.java)

See which variables are at play at that line; at least one is being null and you're trying to do an operation on that, causing the exception.

orique
  • 1,295
  • 1
  • 27
  • 36
0

So I figured it out, and it seems pretty stupid too me.

When I was initializing:

TextView speed = (TextView) findViewById(R.id.speed);
TextView progress = (TextView) findViewById(R.id.progress);
TextView connectionspeed = (TextView)findViewById(R.id.connectionspeed);
TextView confirmation = (TextView) findViewById(R.id.speed);

I was also initializing:

private TextView connectionspeed;
private TextView progress;
private TextView speed;
private TextView confirmation;

What I should of had in the onCreate() was just:

speed = (TextView) findViewById(R.id.speed);
progress = (TextView) findViewById(R.id.progress);
connectionspeed = (TextView)findViewById(R.id.connectionspeed);
confirmation = (TextView) findViewById(R.id.speed);

I think the .Net equivalent would be calling Dim or var twice ... I think ... Anyways, I took out the TextView part and it works now. If anyone has a better explanation I am all ears.

Nefariis
  • 3,451
  • 10
  • 34
  • 52
  • oh so it was picking up your global which was null and the local which you initialized was out of scope once you finished the onCreate? – boltup_im_coding Mar 01 '13 at 07:12
  • Im pretty sure that's what was happening. Once I made sure the global and the local recognized each other everything started working. – Nefariis Mar 01 '13 at 17:15