来自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();
}
答案 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
中执行此操作