Android:NullPointerException,这里可能为null?

时间:2014-11-26 11:51:48

标签: java android android-asynctask nullpointerexception

来自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),所以这应该不是问题。但是我仍然在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();
    }

4 个答案:

答案 0 :(得分:1)

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

答案 1 :(得分:1)

除非您需要同时运行多个这些任务,否则您应该将您的任务设置为静态内部类。那么你应该完全把课程分开。

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

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

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

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

答案 2 :(得分:0)

试试这个

    @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.");
        }

    }

答案 3 :(得分:0)

你这样做

完全错误

您正在后台线程中引用UI组件,您不能这样做。所有此类引用都在活动的onCreate()方法中进行。无论何时您想要更新这些UI组件,可以在onPostExecute()

AsyncTask中执行此操作