user3745217
user3745217

Reputation: 13

Null Pointer Exception after some code moved to a custom Application class

Getting NullPointerException after I moved some of the code to a separate, custom application class called YambaApplication. This application posts to a Twitter enabled service. I checked the code 3 times, and cleaned the project 5 times:

Exception:

06-16 14:08:22.723: E/AndroidRuntime(392): Caused by: java.lang.NullPointerException 06-16 14:08:22.723: E/AndroidRuntime(392): at com.user.yamba.StatusActivity$PostToTwitter.doInBackground(StatusActivity.java:70)

YambaApplication.java (here we initialize and return a twitter object):

package com.user.yamba;

import winterwell.jtwitter.Twitter;
import android.app.Application;
import android.content.SharedPreferences;
import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
import android.preference.PreferenceManager;
import android.text.TextUtils;
import android.util.Log;

    public class YambaApplication extends Application implements
            OnSharedPreferenceChangeListener {

        private static final String TAG = YambaApplication.class.getSimpleName();
        public Twitter twitter;
        private SharedPreferences prefs;

        @Override
        public void onCreate() {
            super.onCreate();
            this.prefs = PreferenceManager.getDefaultSharedPreferences(this);
            this.prefs.registerOnSharedPreferenceChangeListener(this);
            Log.i(TAG, "onCreated");
        }

        @Override
        public void onTerminate() {
            super.onTerminate();
            Log.i(TAG, "onTerminated");
        }

        @Override
        public synchronized void onSharedPreferenceChanged(
                SharedPreferences sharedPreferences, String key) {
            this.twitter = null;

        }

        public synchronized Twitter getTwitter() {
            if (this.twitter == null) {
                String username, password, apiRoot;
                username = this.prefs.getString("username", "");
                password = this.prefs.getString("password", "");
                apiRoot = this.prefs.getString("apiRoot",
                        "http://yamba.marakana.com/api");
                if (!TextUtils.isEmpty(username) && !TextUtils.isEmpty(password)
                        && !TextUtils.isEmpty(apiRoot)) {
                    this.twitter = new Twitter(username, password);
                    this.twitter.setAPIRootUrl(apiRoot);
                }
            }
            return this.twitter;
        }

    }

StatusActivity.java (the first activity user sees with an EditText and an update button. Most of the code from YambaApplication class was inside this class.):

package com.user.yamba;

import winterwell.jtwitter.Twitter;
import winterwell.jtwitter.TwitterException;
import android.app.Activity;
import android.content.Intent;
import android.graphics.Color;
import android.os.AsyncTask;
import android.os.Bundle;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.Log;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;

public class StatusActivity extends Activity implements OnClickListener,
        TextWatcher {
    private static final String TAG = "StatusActivity";
    EditText editTextStatusUpdate;
    Button buttonStatusUpdate;
    TextView textViewCharacterCounter;
    //SharedPreferences prefs;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_status);

        // Find views
        editTextStatusUpdate = (EditText) findViewById(R.id.editStatus);
        buttonStatusUpdate = (Button) findViewById(R.id.buttonUpdate);
        buttonStatusUpdate.setOnClickListener(this);

        textViewCharacterCounter = (TextView) findViewById(R.id.editTextUpdateStatusCounter);
        textViewCharacterCounter.setText(Integer.toString(140));
        textViewCharacterCounter.setTextColor(Color.GREEN);
        editTextStatusUpdate.addTextChangedListener(this);

        //prefs = PreferenceManager.getDefaultSharedPreferences(this);
        //prefs.registerOnSharedPreferenceChangeListener(this);

        // Initialize twitter
        // twitter = new Twitter("student", "password");
        // twitter.setAPIRootUrl("http://yamba.marakana.com/api");

    }

    @Override
    public void onClick(View v) {
        String statusUpdate = editTextStatusUpdate.getText().toString();
        new PostToTwitter().execute(statusUpdate);
        Log.d(TAG, "onClicked");
    }

    // Async class to post of twitter
    class PostToTwitter extends AsyncTask<String, Integer, String> {

        // Async post status to twitter
        @Override
        protected String doInBackground(String... params) {
            try {
                YambaApplication yamba = ((YambaApplication) getApplication());
                Twitter.Status status = yamba.getTwitter().updateStatus(params[0]); // EXCEPTION FIRED HERE
                return status.text;
            } catch (TwitterException e) {
                Log.e(TAG, "Failed to connect to twitter service");
                return "Failed to post";
            }

        }

        // Called when there's status to be updated
        @Override
        protected void onProgressUpdate(Integer... values) {
            super.onProgressUpdate(values);
            // Not used
        }

        // Called once async task completed
        @Override
        protected void onPostExecute(String result) {
            Toast.makeText(StatusActivity.this, result, Toast.LENGTH_LONG)
                    .show();
        }
    }

    @Override
    public void beforeTextChanged(CharSequence s, int start, int count,
            int after) {
        // Not in use

    }

    @Override
    public void onTextChanged(CharSequence s, int start, int before, int count) {
        // Not in use

    }

    // Update characters counter after text
    // is changed(entered or deleted)
    @Override
    public void afterTextChanged(Editable statusText) {
        int count = 140 - statusText.length();
        textViewCharacterCounter.setText(Integer.toString(count));
        textViewCharacterCounter.setTextColor(Color.GREEN);
        if (count < 10) {
            textViewCharacterCounter.setTextColor(Color.YELLOW);
        }
        if (count < 0) {
            textViewCharacterCounter.setTextColor(Color.RED);
        }
    }

    // When user taps on the menu hardware button inflate
    // the menu resource
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        MenuInflater inflater = getMenuInflater();
        inflater.inflate(R.menu.menu, menu);
        return true;
    }

    // Determine what item user tapped on the menu
    // and start the item's activity
    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
        case R.id.itemPrefs:
            startActivity(new Intent(this, PrefsActivity.class));
            break;
        }
        return true;
    }

//  private Twitter getTwitter() {
//      if (twitter == null) {
//          String username, password, apiRoot;
//          username = prefs.getString("username", "");
//          password = prefs.getString("password", "");
//          apiRoot = prefs.getString("apiRoot",
//                  "http://yamba.marakana.com/api");
//
//          // Connect to twitter
//          twitter = new Twitter(username, password);
//          twitter.setAPIRootUrl(apiRoot);
//      }
//      return twitter;
//  }

//  @Override
//  public void onSharedPreferenceChanged(SharedPreferences sharedPreferences,
//          String key) {
//      // invalidate twitter
//      twitter = null;
//
//  }
}

Manifest (added this line to the application tag in the manifest):

android:name=".YambaApplication"

Upvotes: 1

Views: 119

Answers (2)

Zoran
Zoran

Reputation: 1494

Null is because in YambaApplication you check:

if (!TextUtils.isEmpty(username) && !TextUtils.isEmpty(password)
    && !TextUtils.isEmpty(apiRoot)) {
    ...
}

If any field is empty you get twiter == null.

Upvotes: 1

tknell
tknell

Reputation: 9047

The first thing I saw were the new checks for the username and password to contain text. Maybe try to debug if they both are set correctly and if a Twitter Object is returned from the Application, or simply null, because of those checks.

Upvotes: 1

Related Questions