【问题标题】:Android: NullPointerException, what could be null here?Android:NullPointerException,这里什么可能是 null?
【发布时间】:2015-01-24 17:45:59
【问题描述】:

来自 Logcat:

11-26 06:43:40.643: E/AndroidRuntime(1163): FATAL EXCEPTION: AsyncTask #1
...
11-26 06:43:40.643: E/AndroidRuntime(1163): java.lang.RuntimeException: An error occured while executing doInBackground()
...
11-26 06:43:40.643: E/AndroidRuntime(1163): Caused by: java.lang.NullPointerException
...
11-26 06:43:40.643: E/AndroidRuntime(1163):     at com.example.mymobiletest.SearchTask.doInBackground(SearchTask.java:134)

第 134 行是ed = (EditText) mainActivity.findViewById(R.id.mainSearchActivity_editTextSearch);。现在这一行的执行表明mainActivity(它是传递给这个AsyncTask的构造函数的主要活动的一个实例)不是null。那么在这一行还有什么可能是null,这会导致NullPointerException

@Override
protected String doInBackground(Void... voidParameters) {
    EditText ed=null;
    if (mainActivity!=null) {
        ed = (EditText) mainActivity.findViewById(R.id.mainSearchActivity_editTextSearch);
    } else {
        return "mainActivity is the Null culprit.";
    }

编辑:- 我确实认为,因为我没有更改 doInBackground() 中的 UI(但仅从 UI 中读取) ,所以这应该不是问题。但是我仍然在onPreExecute() 中尝试了这个,因为onPreExecute 是在 UI 线程中执行的,但我仍然在同一条语句中得到 NPE。

@Override 
    protected void onPreExecute() {
        EditText ed=null;
        if (mainActivity!=null) {
            ed = (EditText) mainActivity.findViewById(R.id.mainSearchActivity_editTextSearch);//******NPE
        } else {
            Log.i(TAG, "mainActivity is the Null culprit.");
        }
        searchQuery = ed.getText().toString();
    }

【问题讨论】:

  • @MD ed 在这行之前是null,但是我们有这行来分配ed 一个View,所以为什么会出现异常!
  • mainActivity 同步了吗?
  • @Zarah 你不应该在 doInBackground() 中使用 ui 做任何事情,考虑使用 onProgress()
  • 尝试打印一个简单的mainActivity.toString() 并检查您是否获得了 NPE。同样正如 grub 所说,您不应该更改 doInBackground 上的 UI。
  • 他已经对 mainActivity 进行了空检查,因此它不能为此抛出 NPE,并且他没有更改 doInBackground 中的用户界面

标签: java android android-asynctask nullpointerexception


【解决方案1】:

由于 doInBackground() 方法运行在与主线程不同的线程上,因此您不应在 doInBackground() 方法中访问 UI 元素。您应该在 OnProgress() 或 OnPostExcecute() 方法中访问 UI 元素。

【讨论】:

  • 我在onPreExecute 中尝试过,但没有任何收获。请查看问题中的编辑。
【解决方案2】:

试试这个

    @Override 
    protected void onPreExecute() {
        EditText ed=null;
        if (mainActivity!=null) {
            ed = (EditText) mainActivity.findViewById(R.id.mainSearchActivity_editTextSearch);//******NPE
searchQuery = ed.getText().toString();
        } else {
            Log.i(TAG, "mainActivity is the Null culprit.");
        }

    }

【讨论】:

  • 您确定只在 onPreExecute 中访问 UI 吗?
  • 也许你应该发布整个 Asynktask?我会尝试重构
  • 是的,100%,在onPreExecuteonPostExecute。其次,当我们从后台线程manipulate UI 时,我们得到一个不同的异常或其他东西(我不完全记得)但不是 NPE。
【解决方案3】:

你正在这样做

完全错误

你在后台线程中引用了 UI 组件,你不能这样做。所有这些引用都在活动的 onCreate() 方法中获取。当你想要更新这些 UI 组件时,你可以这样做它在您的AsyncTaskonPostExecute()

【讨论】:

  • 首先,我没有更新EditText。其次,我确实尝试在onPreExecute 中这样做,但没有解决这个问题。请看问题中的编辑,我还想念吗?
  • 为什么不在活动的 onCreate() 方法中获取引用,然后从中获取文本并将其发送到 AsyncTask
  • 因为我没有将 AsyncTask 实现为内部类,而是作为一个单独的类。
  • 为什么不这样做呢?它将减少您的大部分开销
【解决方案4】:

您应该使您的任务成为静态内部类,除非您需要同时运行多个此类任务。那么你应该把这个类完全分开。

doInBackground 执行一个任务,然后将结果返回给 onPostExecute。这是 ASynctask 的一般用途的预期用途。

不同之处在于 doInBackground 通过后台进程在完全独立的线程中运行。您无法保证它何时运行或完成。它看不到 UI 线程。然而,onPostExecute 在 UI 线程上运行。

这意味着您的 ASyncTask 无法保证相同的 MainActivity 将保持活动状态。由于我们程序员不知道的原因,活动不断地被创建和销毁。例如,方向的任何更改都会破坏您的 MainActivity 并重新创建它,这意味着您传递的引用现在是空的,无论它在进程中的哪个位置。它可以通过第一个空检查,然后在 findViewById 上崩溃。你无法保证在 onCreate() 之外会发生什么。

如果您将其设为内部静态类并在 onPostExecute 中调用 edittext,它应该可以正常工作,因为内部类将重新附加到新的活动实例。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-05-11
    • 1970-01-01
    • 2018-03-06
    • 2016-05-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多