【问题标题】:android.app.Application cannot be instantiated due to NullPointerException由于 NullPointerException,android.app.Application 无法实例化
【发布时间】:2012-02-20 18:43:15
【问题描述】:

我是 android 世界的菜鸟,正在做一个锻炼的宠物项目。这是一个非常简单的类似提醒的应用程序,只有两个活动。一种是自定义的 ListView 显示现有的警报。其中有一些按钮可以启动另一个按钮,用于添加/编辑警报。里面有一个按钮指向上一个 ListView 活动。

我最近遇到了一个奇怪的情况。我的应用程序运行良好。但问题是,每当我触发添加/编辑活动时,然后返回 ListView,然后重新运行(或者我应该说重新安装?)应用程序。将弹出一条错误消息。但它只会短暂显示,应用程序将启动。

我在日志中捕获的错误消息是:

FATAL EXCEPTION: main
java.lang.RuntimeException: Unable to instantiate application android.app.Application: java.lang.NullPointerException
at android.app.LoadedApk.makeApplication(LoadedApk.java:482)
at android.app.ActivityThread.handleBindApplication(ActivityThread.java:3909)
at android.app.ActivityThread.access$1300(ActivityThread.java:122)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1184)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:4340)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.NullPointerException
at android.app.LoadedApk.initializeJavaContextClassLoader(LoadedApk.java:362)
at android.app.LoadedApk.getClassLoader(LoadedApk.java:305)
at android.app.LoadedApk.makeApplication(LoadedApk.java:474)
... 11 more

它没有明确指出我的代码哪里出了问题。所以我不知道如何纠正它。有没有人遇到过类似的问题?任何建议将不胜感激!

这是添加/编辑活动的代码:

public class EditEntry extends Activity
{
    private AutoCompleteTextView foodNameTextView;
    private DatePicker datePicker;
    // store values in AutoCompleteTextView & DatePicker
    private String foodName;
    private Calendar foodDate;

    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.edit);
        // dummy selections for AutoCompleteTextView
        String[] foodList = new String[]{"meat", "fruit", "vega"};
        // instantiate AutoCompleteTextView & DatePicker
        ArrayAdapter<String> arrayAdapter = new ArrayAdapter<String>(this, R.layout.food_list_dropdown, foodList);
        foodNameTextView = (AutoCompleteTextView)findViewById(R.id.foodName);
        foodNameTextView.setAdapter(arrayAdapter);
        datePicker = (DatePicker)findViewById(R.id.date_picker);
        // get intent from ReminderList.
        Intent intent = getIntent();
        // get extras from intent. Return null if intent is sent from "add" action.
        foodName = intent.getStringExtra("foodName");
        foodDate = (Calendar) intent.getSerializableExtra("foodDate");
        // set default values for widgets if it is an "edit" action.
        if (null != foodName)
        {
            foodNameTextView.setText(foodName);
            datePicker.init(foodDate.get(Calendar.YEAR), foodDate.get(Calendar.MONTH), foodDate.get(Calendar.DAY_OF_MONTH), 
                    new OnDateChangedListener()
                    {   // will implement date input check later.
                        @Override
                        public void onDateChanged(DatePicker view, int year, int monthOfYear, int dayOfMonth)   {}
                    });
        }

        // Submit will add/modify the data in xml file. Back will start ReminderList activity
        Button submit = (Button)findViewById(R.id.entry_submit);
        Button back = (Button)findViewById(R.id.entry_back);

        submit.setOnClickListener(new SubmitButtonListener());
        back.setOnClickListener(new OnClickListener()
        {
            @Override
            public void onClick(View v)
            {
                Intent intent = new Intent();
                intent.setClass(EditEntry.this, FoodReminderList.class);
                startActivity(intent);
            }
        });
    }

    // add or modify data in xml file
    @SuppressWarnings("unused")
    class SubmitButtonListener implements OnClickListener
    {
        Calendar foodDate = Calendar.getInstance();

        @Override
        public void onClick(View v)
        {
            XmlUtil xmlUtil = new XmlUtil();
            // determine if it is an "edit" action.
            if (null != foodName)
            {
                FoodInfo foodInfo = new FoodInfo(foodName, foodDate);
                // delete the old data entry
                xmlUtil.deleteEntry(foodInfo);
                // cancel old alarm
                FoodReceiver alarm = new FoodReceiver(EditEntry.this, foodDate, false);
            }
            // get new input values 
            foodName = foodNameTextView.getText().toString();
            foodDate.set(datePicker.getYear(), datePicker.getMonth(), datePicker.getDayOfMonth(), 0, 0, 0);
            // update xml file
            FoodInfo foodInfo = new FoodInfo(foodName, foodDate);
            xmlUtil.updateEntry(foodInfo);
            // set new alarm
            FoodReceiver alarm = new FoodReceiver(EditEntry.this, foodDate, true);
            // popup toast confirming the submit
            Toast.makeText(EditEntry.this, "Reminder Added", Toast.LENGTH_SHORT).show();
            // clear widgets
            foodNameTextView.setText("");
            Calendar currentDate = Calendar.getInstance();
            datePicker.updateDate(currentDate.get(Calendar.YEAR), currentDate.get(Calendar.MONTH), currentDate.get(Calendar.DAY_OF_MONTH));
        }
    }
}

清单是这样的:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="ca.maxiao.Food"
android:versionCode="1"
android:versionName="1.0" >

<uses-sdk android:minSdkVersion="8" />

<application
    android:icon="@drawable/ic_launcher"
    android:label="@string/app_name" >
    <activity
        android:label="@string/app_name"
        android:name=".FoodReminderList" >
        <intent-filter >
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
    <activity
        android:label="@string/app_name"
        android:name=".EditEntry" >
    </activity>
    <activity 
        android:label='@string/app_name'
        android:name=".FoodReminder"></activity>

    <receiver android:name="ca.maxiao.Food.FoodReceiver">
        <intent-filter>
            <action android:name="Alarm_Setting" />
        </intent-filter>
    </receiver>
</application>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.VIBRATE"/>
</manifest>

【问题讨论】:

  • 有一个post 关于类似的错误。我知道这可能是线程竞争问题,但仍然不知道如何修改我的代码。
  • 你能在这里添加你的清单文件吗?
  • 你知道屏幕上的简短错误信息是什么吗?你能通过 DDMS 截屏吗?
  • 哦,我应该说清楚一点。这只是一个正常的错误消息,例如不幸的是, 已停止。
  • 您是否添加了日志语句来验证 foodName 是否曾经为空?

标签: android nullpointerexception


【解决方案1】:

我遇到了完全相同的错误,尽管代码比你的代码更简单。我发现只有在从 Eclipse 重新运行后没有在模拟器中关闭应用程序时才会出现问题。因此,如果我在从 Eclipse 运行它之前关闭它,一切正常。但是由于我对android真的很陌生,所以我不知道为什么会这样。我以前测试过应用程序,这从来都不是问题。

【讨论】:

    【解决方案2】:

    我在匿名内部类中为返回按钮做了更多测试并锁定了问题,因为每当我在重新启动应用程序之前单击它时都会出现错误。如果我使用手机上的“返回”按钮切换活动,一切都很好。

    我在内部类中添加了一行

    EditEntry.this.finish();
    

    它确实解决了问题。这次我尝试更系统地测试它。假设没有上述行的代码是A,而有这一行的代码是B。场景如下:

    1.运行 A 然后 A --> 错误

    2.运行 A 然后 B --> 错误

    3.运行 B 然后运行 ​​A --> OK

    4.运行 B 然后 B --> OK

    因此,我认为这是关于活动堆栈的某种问题?

    【讨论】:

    • 我尝试了复制并且可以复制一段时间,但现在不行了。很可能是其中一个已编译资源未更新的结果。当我进行清洁时,它一直开始工作。如果您将该行恢复为“startActivity(intent);”错误会回来吗?我对这个真的很感兴趣!
    • 糟糕,我在这篇文章中犯了一个错误。我尝试了几种方法,它们必须以某种方式混合在一起。我修改了我的答案。请再次检查。
    • @MikeC 感谢您的关注。我编辑我的答案。我认为清理项目与 EditEntry.this.finish() 具有相同的效果?你知道这背后的确切原因是什么吗?
    【解决方案3】:

    其实这个问题的真正解决方案是文件夹权限问题。确保您在可以修改的文件夹中进行操作。我刚刚通过确保我在具有正确权限的文件夹中为自己解决了同样的问题。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-12-11
      • 1970-01-01
      • 1970-01-01
      • 2018-09-29
      • 1970-01-01
      • 2018-09-10
      相关资源
      最近更新 更多