以昨天的主题为基础......我正在让一个NPE从AlertDialog中的单例Application类中访问一个方法。
活动SavedMealsActivity将OnLongClickListenerSavedMeals设置为ScrollView中一系列TextView的侦听器。 OnLongClickListenerSavedMeals被定义为一个单独的类。
OnLongClickListenerSavedMeals显示一个AlertDialog,它提供了转到不同Activity的选项,但它首先需要触发定义为单例(MealTimerApplication)的Application类的方法。这是onClick方法的第一行(下面第一个代码示例中的第25行),它抛出了NPE,因为当时活动为空。
我已经尝试通过调用Activity(SavedMealsActivity)传递活动但是由于某种原因它不能像我希望的那样工作。有什么想法吗?
OnLongClick侦听器类 - OnLongClickListenerSavedMeals:
public class OnLongClickListenerSavedMeals implements OnLongClickListener {
Context context;
String id;
private Activity activity;
public OnLongClickListenerSavedMeals(Activity activity) {
this.activity = activity;
this.context = activity;
}
@Override
public boolean onLongClick(View view){
// TODO Auto-generated method stub
this.context = context;
id = view.getTag().toString();
final CharSequence[] items = { "Edit", "Delete" };
//Set activity to allow context to be used in the OnClickListener/onClick method below
this.activity = activity;
new AlertDialog.Builder(context).setTitle("Meal Item")
.setItems(items, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int item) {
if (item == 0) {
//Set the global meal_id variable and invoke the MealActivity
((MealTimerApplication) activity.getApplication()).setMealId(Long.getLong(id));
Intent myIntent = new Intent(activity.getBaseContext(),MealActivity.class);
activity.startActivityForResult(myIntent, 0);
}
else if (item == 1) {
boolean deleteSuccessful = new TableControllerMeal(context).delete(id);
if (deleteSuccessful){
Toast.makeText(context, "Record was deleted.", Toast.LENGTH_SHORT).show();
}else{
Toast.makeText(context, "Unable to delete record.", Toast.LENGTH_SHORT).show();
}
((SavedMealsActivity) context).readRecords();
}
dialog.dismiss();
}
}).show();
return false;
}
调用活动 - SavedMealsActivity:
public class SavedMealsActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_saved_meals);
//Read saved meal records from the database and display them
readRecords();
}
public void readRecords() {
LinearLayout linearLayoutRecords = (LinearLayout) findViewById(R.id.linearLayoutRecords);
linearLayoutRecords.removeAllViews();
List<meal> meal = new TableControllerMeal(this).read();
if (meal.size() > 0) {
for (meal obj : meal) {
long id = obj.id;
String MealDesc = obj.meal_desc;
int MealMinutes = obj.meal_ready_time;
String textViewContents = MealDesc + " - ready at "
+ Utilities.formatTime(MealMinutes);
TextView textViewItem = new TextView(this);
textViewItem.setPadding(0, 10, 0, 10);
textViewItem.setText(textViewContents);
textViewItem.setTag(Long.toString(id));
textViewItem.setOnLongClickListener(new OnLongClickListenerSavedMeals(this));
linearLayoutRecords.addView(textViewItem);
}
}
else {
TextView Item = new TextView(this);
Item.setPadding(8, 8, 8, 8);
Item.setText("No records yet.");
linearLayoutRecords.addView(Item);
}
}
申请类:
public class MealTimerApplication extends Application {
private static MealTimerApplication singleton;
private long mealId = 0;
// Returns the application instance
public static MealTimerApplication getInstance() {
return singleton;
}
public final void onCreate() {
super.onCreate();
singleton = this;
}
public void setMealId(long mealId) {
this.mealId = mealId;
}
public long getMealId() {
return this.mealId;
}
}
logcat的:
05-28 16:48:03.637: E/AndroidRuntime(4241): java.lang.NullPointerException
05-28 16:48:03.637: E/AndroidRuntime(4241): at com.ian.mealtimer.OnLongClickListenerSavedMeals$1.onClick(OnLongClickListenerSavedMeals.java:39)
05-28 16:48:03.637: E/AndroidRuntime(4241): at com.android.internal.app.AlertController$AlertParams$3.onItemClick(AlertController.java:941)
05-28 16:48:03.637: E/AndroidRuntime(4241): at android.widget.AdapterView.performItemClick(AdapterView.java:299)
05-28 16:48:03.637: E/AndroidRuntime(4241): at android.widget.AbsListView.performItemClick(AbsListView.java:1113)
05-28 16:48:03.637: E/AndroidRuntime(4241): at android.widget.AbsListView$PerformClick.run(AbsListView.java:2904)
05-28 16:48:03.637: E/AndroidRuntime(4241): at android.widget.AbsListView$3.run(AbsListView.java:3638)
05-28 16:48:03.637: E/AndroidRuntime(4241): at android.os.Handler.handleCallback(Handler.java:733)
05-28 16:48:03.637: E/AndroidRuntime(4241): at android.os.Handler.dispatchMessage(Handler.java:95)
05-28 16:48:03.637: E/AndroidRuntime(4241): at android.os.Looper.loop(Looper.java:136)
05-28 16:48:03.637: E/AndroidRuntime(4241): at android.app.ActivityThread.main(ActivityThread.java:5017)
05-28 16:48:03.637: E/AndroidRuntime(4241): at java.lang.reflect.Method.invokeNative(Native Method)
05-28 16:48:03.637: E/AndroidRuntime(4241): at java.lang.reflect.Method.invoke(Method.java:515)
05-28 16:48:03.637: E/AndroidRuntime(4241): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:779)
05-28 16:48:03.637: E/AndroidRuntime(4241): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:595)
05-28 16:48:03.637: E/AndroidRuntime(4241): at dalvik.system.NativeStart.main(Native Method)
答案 0 :(得分:1)
因为自动装箱而获得NPE。 Long.getLong(String)不是您实际需要的,请查看其说明:
返回由string标识的系统属性的Long值。
在你的情况下肯定会返回null。此外,它返回对Long
对象的空引用,但是您的MealTimerApplication.setMealId
期望具有基本类型long
的参数。以下是自动装箱隐式尝试将Long
方法返回的getLong
对象强制转换为long
原语的点。但是当值为null时,自动装箱失败并且你得到了NPE。
您应该使用Long.valueOf(String)代替Long.getLong(String)
。