NPE从AlertDialog OnClick方法访问应用程序方法

时间:2014-05-28 21:05:27

标签: java android nullpointerexception alertdialog

以昨天的主题为基础......我正在让一个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)

1 个答案:

答案 0 :(得分:1)

因为自动装箱而获得NPE。 Long.getLong(String)不是您实际需要的,请查看其说明:

  
    

返回由string标识的系统属性的Long值。

  

在你的情况下肯定会返回null。此外,它返回对Long对象的空引用,但是您的MealTimerApplication.setMealId期望具有基本类型long的参数。以下是自动装箱隐式尝试将Long方法返回的getLong对象强制转换为long原语的点。但是当值为null时,自动装箱失败并且你得到了NPE。

您应该使用Long.valueOf(String)代替Long.getLong(String)