Android 应用崩溃,没有 logcat 错误

Android app crashes with no logcat errors

我正在为明天到期的移动应用程序开发期末项目开发 android 应用程序,运行 遇到了问题。直到昨天,我的应用程序还能在我的 phone 上正常运行,但从那时起我不知何故搞砸了一些事情。该程序 运行 非常完美,并且可以在模拟器上完成我需要它完成的所有事情,即使是在我从昨天开始向它添加的所有内容之后,所以我认为该应用程序已经完全完成并准备好展示了。但是,我今天 运行 在我的 phone 上使用它,发现应用程序在启动以下 activity...

时崩溃
public class OrderDetails extends AppCompatActivity {

    private List<PhoneBook> contactList;
    private ListView listView;
    private TextView name, number, address, orderTotal, amountReceived, tip, mileage, grandTotal;
    private Button add;
    private PhonebookAdapter adapter;
    PhoneBookHandler db;

    double dAmountReceived;
    double dTotalCost;
    double dSubtract;
    double dMileage;
    double dGrandTotal;
    double dTip;
    double dAdd;
    double dMilesDriven;
    double dMultiply;
    double dRatePerMile;
    String sAmountReceived;
    String sTotalCost;
    String sTip;
    String sMileage;
    String sGrandTotal;
    String sAddress;
    String ratePerDelivery;
    String ratePerMile;
    String milesDriven;
    EditText eAmountReceived;
    EditText eTotalCost;
    EditText eTip;
    EditText eMileage;
    EditText eAddress;
    EditText eGrandTotal;
    EditText eMilesDriven;

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

        listView = (ListView) findViewById(R.id.contactlist);

        db = new PhoneBookHandler(this);

        contactList = db.getAllContacts();

        adapter = new PhonebookAdapter(this, contactList);

        eAddress = (EditText) findViewById(R.id.address);

        eTotalCost = (EditText) findViewById(R.id.orderTotal);
        eAmountReceived = (EditText) findViewById(R.id.amountReceived);
        eTip = (EditText) findViewById(R.id.tip);
        eMileage = (EditText) findViewById(R.id.mileage);
        eGrandTotal = (EditText) findViewById(R.id.grandTotal);
        eMilesDriven = (EditText) findViewById(R.id.milesDriven);

        // use shared preferences to inflate mileage edittext with data entered in settings menu
        ratePerDelivery = PreferenceManager.getDefaultSharedPreferences(this).getString("ratePerDeliveryPref", null);
        ratePerMile = PreferenceManager.getDefaultSharedPreferences(this).getString("ratePerMilePref", null);

        eAmountReceived.addTextChangedListener(new TextWatcher()
        {
            @Override
            public void beforeTextChanged(CharSequence s, int start,
                                      int count, int after){}

            @Override
            public void onTextChanged(CharSequence s, int start,
                                  int before, int count){}

            @Override
            public void afterTextChanged(Editable s)
            {
                if (getCurrentFocus() == eAmountReceived)
                {
                    sAmountReceived = eAmountReceived.getText().toString();
                    sTotalCost = eTotalCost.getText().toString();
                    sMileage = eMileage.getText().toString();
                    sTip = eTip.getText().toString();

                    try
                    {
                        dAmountReceived = Double.parseDouble(sAmountReceived);
                        dTotalCost = Double.parseDouble(sTotalCost);

                        dSubtract = dAmountReceived - dTotalCost;
                        dMileage = Double.parseDouble(sMileage);
                        dGrandTotal = dSubtract + dMileage;
                    } catch(NumberFormatException e){}

                    sTip = String.valueOf(dSubtract);

                    DecimalFormat df = new DecimalFormat("0.00");
                    sTip = df.format(dSubtract);

                    eTip.setText(sTip);

                    sGrandTotal = String.valueOf(dGrandTotal);
                    sGrandTotal = df.format(dGrandTotal);
                    eGrandTotal.setText(sGrandTotal);
                }
            }
        });


        eTip.addTextChangedListener(new TextWatcher()
        {
            @Override
            public void beforeTextChanged(CharSequence s, int start,
                                      int count, int after){}

            @Override
            public void onTextChanged(CharSequence s, int start,
                                  int before, int count){}

            @Override
            public void afterTextChanged(Editable s) {
                if (getCurrentFocus() == eTip)
                {
                    sAmountReceived = eAmountReceived.getText().toString();
                    sTotalCost = eTotalCost.getText().toString();
                    sMileage = eMileage.getText().toString();
                    sTip = eTip.getText().toString();

                    try {
                        dTip = Double.parseDouble(sTip);
                        dTotalCost = Double.parseDouble(sTotalCost);

                        dAdd = dTotalCost + dTip;
                        dMileage = Double.parseDouble(sMileage);
                        dGrandTotal = dTip + dMileage;
                    } catch (NumberFormatException e) {
                    }

                    sAmountReceived = String.valueOf(dAdd);

                    DecimalFormat df = new DecimalFormat("0.00");
                    sAmountReceived = df.format(dAdd);

                    eAmountReceived.setText(sAmountReceived);

                    sGrandTotal = String.valueOf(dGrandTotal);
                    sGrandTotal = df.format(dGrandTotal);
                    eGrandTotal.setText(sGrandTotal);
                }
            }
        });


        if (ratePerMile.equals("") && !ratePerDelivery.equals(""))
        {
            eMileage.setText(ratePerDelivery);
        }

        else
        {
            eMilesDriven.addTextChangedListener(new TextWatcher()
            {
                @Override
                public void beforeTextChanged(CharSequence s, int start,
                                          int count, int after){}

                @Override
                public void onTextChanged(CharSequence s, int start,
                                      int before, int count){}

                @Override
                public void afterTextChanged(Editable s)
                {
                    if (getCurrentFocus() == eMilesDriven)
                    {
                        sAmountReceived = eAmountReceived.getText().toString();
                        sTotalCost = eTotalCost.getText().toString();
                        sMileage = eMileage.getText().toString();
                        sTip = eTip.getText().toString();

                        try
                        {
                            milesDriven = eMilesDriven.getText().toString();
                            dMilesDriven = Double.parseDouble(milesDriven);
                            dRatePerMile = Double.parseDouble(ratePerMile);
                            dMultiply = dRatePerMile * dMilesDriven;
                            dGrandTotal = dSubtract + dMultiply;
                        } catch(NumberFormatException e){}

                        sMileage = String.valueOf(dMultiply);

                        DecimalFormat df = new DecimalFormat("0.00");
                        sMileage = df.format(dMultiply);

                        eMileage.setText(sMileage);

                        sGrandTotal = String.valueOf(dGrandTotal);
                        sGrandTotal = df.format(dGrandTotal);
                        eGrandTotal.setText(sGrandTotal);
                    }
                }
            });
        }
    }

    public void onClick(View view)
    {

        name = (EditText) findViewById(R.id.name);
        number = (EditText) findViewById(R.id.number);
        address = (EditText) findViewById(R.id.address);
        orderTotal = (EditText) findViewById(R.id.orderTotal);
        amountReceived = (EditText) findViewById(R.id.amountReceived);
        tip = (EditText) findViewById(R.id.tip);
        mileage = (EditText) findViewById(R.id.mileage);
        grandTotal = (EditText) findViewById(R.id.grandTotal);

        String cName = name.getText().toString();
        String num = number.getText().toString();
        String cAddress = address.getText().toString();
        String cOrderTotal = orderTotal.getText().toString();
        String cAmountReceived = amountReceived.getText().toString();
        String cTip = tip.getText().toString();
        String cMileage = mileage.getText().toString();
        String cGrandTotal = grandTotal.getText().toString();


        int id = db.addContact(new PhoneBook(cName, num, cAddress, cOrderTotal,
                                          cAmountReceived, cTip, cMileage, cGrandTotal));
        contactList.add(new PhoneBook(id, cName, num, cAddress, cOrderTotal,
                                   cAmountReceived, cTip, cMileage, cGrandTotal));
        adapter.notifyDataSetChanged();

        Toast.makeText(getApplicationContext(), "Entry Successfully Created.", Toast.LENGTH_LONG).show();
    }


    public void buttonClickFunction(View v)
    {
        Intent intent = new Intent(getApplicationContext(), display_database.class);
        startActivity(intent);
    }

    public void sendMessage(View v)
    {
        eAddress = (EditText) findViewById(R.id.address);
        sAddress = eAddress.getText().toString();

        String map = "http://maps.google.com/maps?q=" + sAddress;
        Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(map));
        startActivity(intent);
    }
}

自昨天以来我唯一添加的是在 "eMilesDriven" 变量上设置的 TextWatcher,它将进行计算。我唯一能想到的另一件事是我今天更改了我的启动器图标,但应用程序中的其他所有内容都正常工作,所以我不确定是不是这样。我只是不明白为什么它在我的模拟器上 运行 完美无缺地在我的 phone 上崩溃。我已经多次重新启动 Android Studio,并从我的 phone 中删除了该应用程序并尝试再次启动它,但每次都没有 logcat 错误。如果能得到任何帮助,我将不胜感激。如果我不能在明天之前解决它,我可能只需要在模拟器上展示我的应用程序,但我真的很想知道它为什么会崩溃。

编辑: logcat错误如下:

FATAL EXCEPTION: main
                                                                               Process: com.example.boley.databaseexample, PID: 15335
                                                                               java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.boley.databaseexample/com.example.boley.personaldeliveryassistant.OrderDetails}: java.lang.NullPointerException: Attempt to invoke virtual method 'boolean java.lang.String.equals(java.lang.Object)' on a null object reference
                                                                                   at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3253)
                                                                                   at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3349)
                                                                                   at android.app.ActivityThread.access00(ActivityThread.java:221)
                                                                                   at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1794)
                                                                                   at android.os.Handler.dispatchMessage(Handler.java:102)
                                                                                   at android.os.Looper.loop(Looper.java:158)
                                                                                   at android.app.ActivityThread.main(ActivityThread.java:7224)
                                                                                   at java.lang.reflect.Method.invoke(Native Method)
                                                                                   at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1230)
                                                                                   at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1120)
                                                                                Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'boolean java.lang.String.equals(java.lang.Object)' on a null object reference
                                                                                   at com.example.boley.personaldeliveryassistant.OrderDetails.onCreate(OrderDetails.java:173)
                                                                                   at android.app.Activity.performCreate(Activity.java:6876)
                                                                                   at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1135)
                                                                                   at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3206)
                                                                                   at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3349) 
                                                                                   at android.app.ActivityThread.access00(ActivityThread.java:221) 
                                                                                   at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1794) 
                                                                                   at android.os.Handler.dispatchMessage(Handler.java:102) 
                                                                                   at android.os.Looper.loop(Looper.java:158) 
                                                                                   at android.app.ActivityThread.main(ActivityThread.java:7224) 
                                                                                   at java.lang.reflect.Method.invoke(Native Method)

getCurrentFocus()

Return the view in this Window that currently has focus, or null if there are none. Note that this does not look in any containing Window.

删除 getCurrentFocus() 因为它将 return null..

我看到的,你在 afterTextChanged(Editable s) 中所做的,它已经指向当前的编辑文本..

其他可能的空指针在这里

if (ratePerMile.equals("") && !ratePerDelivery.equals(""))

改为

if (ratePerMile == null && ratePerDelivery != null)