#java #android
#java #Android
Вопрос:
Получение NullPointerException
после того, как я переместил часть кода в отдельный пользовательский класс приложения, называемый YambaApplication
. Это приложение отправляет сообщения в службу с поддержкой Twitter. Я проверил код 3 раза и очистил проект 5 раз:
Исключение:
06-16 14:08:22.723: E/AndroidRuntime(392): Вызвано: java.lang.Исключение NullPointerException 06-16 14:08:22.723: E/AndroidRuntime(392): на com.user.yamba.StatusActivity$PostToTwitter.doInBackground(StatusActivity.java:70)
YambaApplication.java
(здесь мы инициализируем и возвращаем объект twitter):
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) amp;amp; !TextUtils.isEmpty(password)
amp;amp; !TextUtils.isEmpty(apiRoot)) {
this.twitter = new Twitter(username, password);
this.twitter.setAPIRootUrl(apiRoot);
}
}
return this.twitter;
}
}
StatusActivity.java
(первое действие, которое пользователь видит с EditText
помощью кнопки и обновления. Большая часть кода из YambaApplication
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;
//
// }
}
Манифест (добавлена эта строка в тег приложения в манифесте):
android:name=".YambaApplication"
Комментарии:
1. Перед использованием проверьте значение
params[]
,yamba
иyamba.getTwitter()
как not null . Знание того, какой из них равен нулю, поможет вам предпринять соответствующие действия. Лучше изменить (по крайней мере, завершить отладку)Twitter.Status status = yamba.getTwitter().updateStatus(params[0]);
наTwitter? twitter = yamba.getTwitter();
после проверки на ненулевое значениеTwitter.Status status = twitter.updateStatus(params[0]);
Ответ №1:
Первое, что я увидел, это новые проверки на наличие текста в имени пользователя и пароле. Возможно, попробуйте выполнить отладку, если они оба установлены правильно, и если объект Twitter возвращается из приложения или просто null из-за этих проверок.
Ответ №2:
Null — это потому, что в YambaApplication вы проверяете:
if (!TextUtils.isEmpty(username) amp;amp; !TextUtils.isEmpty(password)
amp;amp; !TextUtils.isEmpty(apiRoot)) {
...
}
Если какое-либо поле пустое, вы получаете twiter == null .