2013-02-21 48 views
0

我正在为一所大学的项目工作,我正在使用Singleton设计模式从我的应用程序中的任何活动全局访问一个变量。NPE试图访问使用Singleton的变量时

java.lang.NullPointerException at com.example.waitronproto9.SectionsActivity$2.onClick(SectionsActivity.java:80) 

这是代码它涉及到行:

Order.getInstance().setTableNumber(table); 

这是我整个SectionsActivity

public class SectionsActivity extends Activity{ 

    LayoutInflater inflater; 
    ActionBar ab; 
    Button homeBtn; 
    Button viewBtn; 
    Button langBtn; 

    ImageView callWaiterBtn; 

    public static Order order; 
    public static EditText tableNum; 
    public static EditText coverNum; 
    int table; 
    int covers; 

    private OrderApplication app; 

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

     Dialog d = createDialog(); 
     d.show(); 

     callWaiterBtn = (ImageView)findViewById(R.id.callWaiter); 
     callWaiterBtn.setOnClickListener(new View.OnClickListener() { 

       @Override 
       public void onClick(View v) { 
        Toast.makeText(v.getContext(), "A Waiter is on their way!", 
          Toast.LENGTH_SHORT).show(); 
       } 
     }); 
    } 

    public Dialog createDialog(){ 
     AlertDialog.Builder builder = new AlertDialog.Builder(SectionsActivity.this); 

     View v = getLayoutInflater().inflate(R.layout.order_dialog, null); 
     builder.setView(v); 

     tableNum = (EditText)v.findViewById(R.id.numberEntry); 
     coverNum = (EditText)v.findViewById(R.id.coversEntry); 

     builder.setMessage("Order Information"); 
     builder.setPositiveButton("Confirm", new DialogInterface.OnClickListener() { 

       @Override 
       public void onClick(DialogInterface dialog, int id) { 
        // Create order object in here 
        table = Integer.parseInt(tableNum.getText().toString()); 
        covers = Integer.parseInt(coverNum.getText().toString()); 
        Order.getInstance().setTableNumber(table); 
        Order.getInstance().setCoverNumber(covers); 
        Toast.makeText(SectionsActivity.this, "Order Created", 
          Toast.LENGTH_SHORT).show(); 
       } 
     }); 

     return builder.create(); 
    } 
} 

,当我跑我的申请,我得到这个错误

这是Order类:

public class Order { 

    int tableNumber; 
    int coverNumber; 
    double amount; 
    List<Dish> orderItems; 

    private static Order instance; 

    // Constructors hidden because it is singleton... 
    private Order(int tableNumber, int coverNumber, double amount, 
      List<Dish> orderItems) { 
     super(); 
     this.tableNumber = tableNumber; 
     this.coverNumber = coverNumber; 
     this.amount = amount; 
     this.orderItems = orderItems; 
    } 

    private Order() { 
     super(); 
     orderItems = new ArrayList<Dish>(); 
    } 

    // SET THE INSTANCE 
    public static void initInstance() { 
     if (instance == null) { 
      instance = new Order(); 
     } 
    } 

    // RETURN INSTANCE 
    public static Order getInstance(){ 
     return instance; 
    } 

    // Getters and Setters 
    public int getTableNumber() { 
     return tableNumber; 
    } 

    public void setTableNumber(int tableNumber) { 
     this.tableNumber = tableNumber; 
    } 

    public int getCoverNumber() { 
     return coverNumber; 
    } 

    public void setCoverNumber(int coverNumber) { 
     this.coverNumber = coverNumber; 
    } 

    public double getAmount() { 
     return amount; 
    } 

    public void setAmount(double amount) { 
     this.amount = amount; 
    } 

    public List<Dish> getOrderItems() { 
     return orderItems; 
    } 

    // Add to order 
    public void addToOrder(Dish d){ 
     this.orderItems.add(d); 
    } 

    public void removeFromOrder(int position){ 
     this.orderItems.remove(position); 
    } 

    public void setOrderItems(List<Dish> orderItems) { 
     this.orderItems = orderItems; 
    } 
} 

这是类:

public class OrderApplication extends Application { 

    @Override 
    public void onCreate() { 
     super.onCreate(); 
     initSingletons(); 
    } 

    protected void initSingletons(){ 
     Order.initInstance(); 
    } 
} 

任何人都可以看到,我错了?任何意见非常感谢!

堆栈跟踪:

02-21 04:06:14.559: E/AndroidRuntime(29562): FATAL EXCEPTION: main 
02-21 04:06:14.559: E/AndroidRuntime(29562): java.lang.NullPointerException 
02-21 04:06:14.559: E/AndroidRuntime(29562): at com.example.waitronproto9.SectionsActivity$2.onClick(SectionsActivity.java:80) 
02-21 04:06:14.559: E/AndroidRuntime(29562): at com.android.internal.app.AlertController$ButtonHandler.handleMessage(AlertController.java:166) 
02-21 04:06:14.559: E/AndroidRuntime(29562): at android.os.Handler.dispatchMessage(Handler.java:99) 
02-21 04:06:14.559: E/AndroidRuntime(29562): at android.os.Looper.loop(Looper.java:137) 
02-21 04:06:14.559: E/AndroidRuntime(29562): at android.app.ActivityThread.main(ActivityThread.java:5041) 
02-21 04:06:14.559: E/AndroidRuntime(29562): at java.lang.reflect.Method.invokeNative(Native Method) 
02-21 04:06:14.559: E/AndroidRuntime(29562): at java.lang.reflect.Method.invoke(Method.java:511) 
02-21 04:06:14.559: E/AndroidRuntime(29562): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793) 
02-21 04:06:14.559: E/AndroidRuntime(29562): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560) 
02-21 04:06:14.559: E/AndroidRuntime(29562): at dalvik.system.NativeStart.main(Native Method) 

回答

1

您还没有实例化您的Order。在尝试访问其方法之前,您需要这样做。

尝试这样的事情,在你的Order类: -

//RETURN INSTANCE 
public static Order getInstance(){ 
    initInstance(); // Instantiate and then return. 
    return instance; 
} 

建议: -

在你SectionsActivity,因为你已经宣布public static Order order;,为什么不利用这样的: -

order = Order.getInstance(); 
order.setTableNumber(table); 
+0

我照你的关系到'的InitInstance(建议)',它解决了问题。 SO让我接受你的答案。你的第二个建议是什么意思?你的意思是我可以做到这一点,而不是调用'initInstance()'? – Javacadabra 2013-02-21 04:18:00

+1

不,我的意思是,既然您已经声明'Order order',为什么不通过将'Order.getInstance()'分配给它来使用它,就像我在我的回复中提到的那样。但这只是一个建议。 – SudoRahul 2013-02-21 04:21:14

+0

对不起,我看到你的回复错误,我明白你的意思了!现在是凌晨4点,我一直在这里工作,在这个舞台上有点晕!感谢您的帮助 – Javacadabra 2013-02-21 04:22:35

0

在getInsance()中调用initInstance()。

虽然,你可能想重新考虑你对单身人士的使用。关于这是否是好的做法存在争议,我不会在没有看到您的整个申请的情况下发表评论。

+0

http://www.object-oriented-security.org/lets-argue/singletons – 2013-02-21 04:55:56

0

R.Js建议确实消除了NPE,但您的代码也应该工作,因为OrderApplication在创建时会调用Order.initInstance(),因此一旦SectionsActivity启动时应该实例化单例。 在mainfest.xml当然,除非你没有申报OrderApplication这很可能对NPE的根本原因:

<application 
    android:name="OrderApplication"