2013-02-21 50 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"